- update multiple LIAM projects and solution/config files - add LiamWorkflowDiagnostics app sources and generated outputs - include current workspace state (dependencies and build outputs)
371 lines
13 KiB
C#
371 lines
13 KiB
C#
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.DirectoryServices.AccountManagement;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Security.AccessControl;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
using C4IT.Logging;
|
|
using C4IT.Matrix42.ServerInfo;
|
|
using LiamAD;
|
|
using static C4IT.Logging.cLogManager;
|
|
using static LiamAD.ADServiceGroupCreator;
|
|
using static LiamAD.cActiveDirectoryBase;
|
|
|
|
namespace C4IT.LIAM
|
|
{
|
|
public static class LiamInitializer
|
|
{
|
|
static public cLiamProviderBase CreateInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
|
|
{
|
|
return new cLiamProviderAD(LiamConfiguration, ProviderData);
|
|
}
|
|
}
|
|
|
|
public class cLiamProviderAD : cLiamProviderBase
|
|
{
|
|
public static Guid adModuleId = new Guid("e820a625-0653-ee11-b886-00155d300101");
|
|
public readonly cActiveDirectoryBase activeDirectoryBase = new cActiveDirectoryBase();
|
|
private readonly ADServiceGroupCreator _serviceGroupCreator;
|
|
|
|
|
|
public cLiamProviderAD(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
|
|
base(LiamConfiguration, ProviderData)
|
|
{
|
|
_serviceGroupCreator = new ADServiceGroupCreator(this);
|
|
}
|
|
|
|
public List<Tuple<string, string, string, string>> CreateServiceGroups(
|
|
string serviceName,
|
|
string description = null,
|
|
eLiamAccessRoleScopes gruppenbereich = eLiamAccessRoleScopes.Universal,
|
|
ADGroupType gruppentyp = ADGroupType.Distribution,
|
|
IEnumerable<string> ownerSidList = null,
|
|
IEnumerable<string> memberSidList = null)
|
|
{
|
|
return _serviceGroupCreator.EnsureServiceGroups(
|
|
serviceName,
|
|
description,
|
|
gruppenbereich,
|
|
gruppentyp,
|
|
ownerSidList,
|
|
memberSidList);
|
|
}
|
|
|
|
public override async Task<bool> LogonAsync()
|
|
{
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(adModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return false;
|
|
}
|
|
return await LogonAsync(true);
|
|
}
|
|
|
|
public async Task<bool> LogonAsync(bool force = false)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var LI = new cADLogonInfo()
|
|
{
|
|
Domain = Domain,
|
|
User = Credential?.Identification,
|
|
UserSecret = Credential?.Secret,
|
|
TargetGroupPath = this.GroupPath
|
|
};
|
|
var RetVal = await activeDirectoryBase.LogonAsync(LI);
|
|
return RetVal;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int Depth = -1)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(adModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return new List<cLiamDataAreaBase>();
|
|
}
|
|
if (!await LogonAsync())
|
|
return null;
|
|
if (string.IsNullOrEmpty(this.GroupPath))
|
|
return null;
|
|
|
|
// 1. Alle Roh-Resultate einlesen
|
|
var rawList = await activeDirectoryBase.RequestSecurityGroupsListAsync(this.GroupFilter);
|
|
if (rawList == null)
|
|
return null;
|
|
|
|
// 2. Nur die, die dem RegEx entsprechen und deren Wert extrahieren
|
|
var allResults = rawList
|
|
.Where(entry =>
|
|
string.IsNullOrEmpty(this.GroupRegEx)
|
|
|| Regex.Match(entry.Value.DisplayName, this.GroupRegEx).Success)
|
|
.Select(entry => (cSecurityGroupResult)entry.Value)
|
|
.ToList();
|
|
|
|
// 3. ManagedBySID-Werte sammeln (ohne Null-/Leereinträge)
|
|
var managedBySids = new HashSet<string>(
|
|
allResults
|
|
.Select(r => r.ManagedBySID)
|
|
.Where(m => !string.IsNullOrEmpty(m))
|
|
);
|
|
|
|
// 4. Nur die Gruppen, deren ID nicht in managedBySids enthalten ist
|
|
var filteredResults = allResults
|
|
.Where(r => !managedBySids.Contains(r.ID))
|
|
.ToList();
|
|
|
|
// 5. In DataArea-Objekte umwandeln
|
|
var SecurityGroups = new List<cLiamDataAreaBase>();
|
|
foreach (var secGroup in filteredResults)
|
|
{
|
|
SecurityGroups.Add(new cLiamAdGroupAsDataArea(this, secGroup));
|
|
}
|
|
|
|
return SecurityGroups;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
|
|
{
|
|
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(adModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return new List<cLiamDataAreaBase>();
|
|
}
|
|
if (!await LogonAsync())
|
|
return null;
|
|
if (string.IsNullOrEmpty(this.GroupPath))
|
|
return null;
|
|
|
|
var SecurityGroups = new List<cLiamDataAreaBase>();
|
|
|
|
var SGL = await activeDirectoryBase.RequestSecurityGroupsListAsync(groupFilter);
|
|
if (SGL == null)
|
|
return null;
|
|
|
|
foreach (var Entry in SGL)
|
|
{
|
|
if (!string.IsNullOrEmpty(this.GroupRegEx) && !Regex.Match(Entry.Value.DisplayName, this.GroupRegEx).Success)
|
|
continue;
|
|
|
|
|
|
var SecurityGroup = new cLiamAdGroup2(this, (cSecurityGroupResult)Entry.Value);
|
|
SecurityGroups.Add(SecurityGroup);
|
|
}
|
|
return SecurityGroups;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public int getDepth(string path)
|
|
{
|
|
return getDepth(this.RootPath, path);
|
|
}
|
|
public static int getDepth(DirectoryInfo root, DirectoryInfo folder)
|
|
{
|
|
var rootDepth = root.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
|
|
var folderDepth = folder.FullName.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar).Length;
|
|
return folderDepth - rootDepth;
|
|
|
|
}
|
|
public static int getDepth(string root, string folder)
|
|
{
|
|
return getDepth(new DirectoryInfo(root), new DirectoryInfo(folder));
|
|
|
|
}
|
|
|
|
public override string GetLastErrorMessage()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override async Task<cLiamDataAreaBase> LoadDataArea(string UID)
|
|
{
|
|
//TODO implement LoadDataArea
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
await Task.Delay(0);
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(adModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return null;
|
|
}
|
|
var res = new cLiamAdGroupAsDataArea(this, new cSecurityGroupResult()
|
|
{
|
|
Path = UID
|
|
});
|
|
return res;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public class cLiamAdGroupAsDataArea : cLiamDataAreaBase
|
|
{
|
|
public new readonly cLiamProviderAD Provider = null;
|
|
public readonly string dn = null;
|
|
public readonly string scope = null;
|
|
public readonly string ManagedBySID;
|
|
|
|
public override Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public cLiamAdGroupAsDataArea(cLiamProviderAD Provider, cSecurityGroupResult secGroup) : base(Provider)
|
|
{
|
|
this.UID = secGroup.ID;
|
|
this.TechnicalName = secGroup.Path;
|
|
this.DisplayName = secGroup.DisplayName;
|
|
this.Description = secGroup.Description;
|
|
this.Provider = Provider;
|
|
this.dn = secGroup.Path;
|
|
this.scope = secGroup.Scope.ToString();
|
|
this.ManagedBySID = secGroup.ManagedBySID;
|
|
}
|
|
|
|
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
return await GetMembersAsync(true);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
private async Task<List<cLiamUserInfo>> GetMembersAsync(bool owners)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var AD = this.Provider?.activeDirectoryBase;
|
|
if (AD == null)
|
|
{
|
|
LogEntry($"Could not get ad class from Provider for folder '{this.TechnicalName}'", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
cADCollectionBase lstMembers;
|
|
if (owners && !string.IsNullOrEmpty(OwnerRef))
|
|
lstMembers = await AD.GetMembersAsync(OwnerRef);
|
|
else if (owners && !string.IsNullOrEmpty(dn))
|
|
lstMembers = await AD.GetManagedByMembersAsync(this.dn);
|
|
else
|
|
lstMembers = null;
|
|
if (lstMembers == null)
|
|
{
|
|
LogEntry($"Could not get owner list for folder '{this.TechnicalName}'", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var RetVal = new List<cLiamUserInfo>(lstMembers.Count);
|
|
LogEntry($"Owners for folder found: {lstMembers.Count}", LogLevels.Debug);
|
|
foreach (var MemberEntry in lstMembers.Values)
|
|
{
|
|
var User = new cLiamUserInfo()
|
|
{
|
|
DisplayName = MemberEntry.DisplayName,
|
|
UserPrincipalName = (MemberEntry as cADUserResult).UserPrincipalName,
|
|
SID = MemberEntry.ID
|
|
};
|
|
RetVal.Add(User);
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
}
|
|
public class cLiamAdGroup2 : cLiamDataAreaBase
|
|
{
|
|
public new readonly cLiamProviderAD Provider = null;
|
|
public readonly string dn = null;
|
|
public readonly string scope = null;
|
|
public override Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public cLiamAdGroup2(cLiamProviderAD Provider, cSecurityGroupResult secGroup) : base(Provider)
|
|
{
|
|
this.DisplayName = secGroup.DisplayName;
|
|
this.UID = secGroup.ID;
|
|
this.TechnicalName = secGroup.DisplayName;
|
|
this.Provider = Provider;
|
|
this.dn = secGroup.Path;
|
|
this.scope = secGroup.Scope.ToString();
|
|
}
|
|
}
|
|
} |