Add workflow NTFS WhatIf toggle

This commit is contained in:
Meik
2026-03-18 14:35:14 +01:00
parent 3ec73817e8
commit 61dd57cf0c
3 changed files with 169 additions and 73 deletions

View File

@@ -623,7 +623,8 @@ namespace C4IT.LIAM
IDictionary<string, string> customTags, IDictionary<string, string> customTags,
IEnumerable<string> ownerSids, IEnumerable<string> ownerSids,
IEnumerable<string> readerSids, IEnumerable<string> readerSids,
IEnumerable<string> writerSids IEnumerable<string> writerSids,
bool whatIf = false
) )
{ {
var engine = CreateFilesystemEngine( var engine = CreateFilesystemEngine(
@@ -633,6 +634,7 @@ namespace C4IT.LIAM
ownerSids, ownerSids,
readerSids, readerSids,
writerSids); writerSids);
engine.WhatIf = whatIf;
var result = engine.createDataArea(); var result = engine.createDataArea();
return Task.FromResult(result); return Task.FromResult(result);
} }

View File

@@ -134,19 +134,7 @@ namespace C4IT_IAM_SET
resultToken.resultErrorId = 0; resultToken.resultErrorId = 0;
if (checkRequiredVariables().resultErrorId == 0) if (checkRequiredVariables().resultErrorId == 0)
{ {
newDataArea = new DataArea(); InitializeFolderContext();
IAM_Folder folder = new IAM_Folder();
folder.configurationID = ConfigID;
folder.technicalName = newFolderPath;
folder.targetType = (int)IAM_TargetType.FileSystem;
folder.Parent = newFolderParent;
folder.ParentUID = DataArea.GetUniqueDataAreaID(newFolderParent);
newDataArea.IAM_Folders.Add(folder);
newSecurityGroups = new SecurityGroups();
newSecurityGroups.username = username;
newSecurityGroups.domainName = domainName;
newSecurityGroups.password = password;
newSecurityGroups.ForceStrictAdGroupNames = forceStrictAdGroupNames;
try try
{ {
// ImpersonationHelper.Impersonate(domainName, username, new NetworkCredential("", password).Password, delegate // ImpersonationHelper.Impersonate(domainName, username, new NetworkCredential("", password).Password, delegate
@@ -157,22 +145,26 @@ namespace C4IT_IAM_SET
DefaultLogger.LogEntry(LogLevels.Info, $"Establishing connection to {baseFolder}, User: {username}, Password: {Helper.MaskAllButLastAndFirst(new NetworkCredential("", password).Password)}"); DefaultLogger.LogEntry(LogLevels.Info, $"Establishing connection to {baseFolder}, User: {username}, Password: {Helper.MaskAllButLastAndFirst(new NetworkCredential("", password).Password)}");
using (Connection = new cNetworkConnection(baseFolder, username, new NetworkCredential("", password).Password)) using (Connection = new cNetworkConnection(baseFolder, username, new NetworkCredential("", password).Password))
{ {
if (checkFolder().resultErrorId == 0) var folderCheckResult = checkFolder();
if (folderCheckResult.resultErrorId == 0)
{ {
try try
{ {
createADGroups(); createADGroups(resultToken);
try try
{ {
resultToken = createFolder(); resultToken = MergeResultTokens(resultToken, createFolder());
try if (resultToken.resultErrorId == 0)
{ {
resultToken = SetTraversePermissions(); try
} {
catch (Exception e) resultToken = MergeResultTokens(resultToken, SetTraversePermissions());
{ }
resultToken.resultErrorId = 30200; catch (Exception e)
resultToken.resultMessage = "Fehler beim setzen der Traverserechte \n" + e.Message; {
resultToken.resultErrorId = 30200;
resultToken.resultMessage = "Fehler beim setzen der Traverserechte \n" + e.Message;
}
} }
} }
catch (Exception e) catch (Exception e)
@@ -191,7 +183,7 @@ namespace C4IT_IAM_SET
} }
else else
{ {
resultToken = checkFolder(); resultToken = folderCheckResult;
} }
/* }, /* },
logonType, logonType,
@@ -222,6 +214,29 @@ namespace C4IT_IAM_SET
} }
} }
private ResultToken MergeResultTokens(ResultToken target, ResultToken source)
{
if (target == null)
return source;
if (source == null)
return target;
if (source.resultErrorId != 0 || target.resultErrorId == 0)
target.resultErrorId = source.resultErrorId;
if (!string.IsNullOrWhiteSpace(source.resultMessage))
target.resultMessage = source.resultMessage;
if (!string.IsNullOrWhiteSpace(source.resultFunction))
target.resultFunction = source.resultFunction;
target.createdGroups.AddRange(source.createdGroups);
target.reusedGroups.AddRange(source.reusedGroups);
target.addedAclEntries.AddRange(source.addedAclEntries);
target.skippedAclEntries.AddRange(source.skippedAclEntries);
target.ensuredTraverseGroups.AddRange(source.ensuredTraverseGroups);
target.warnings.AddRange(source.warnings);
return target;
}
private ResultToken checkRequiredVariablesForEnsure() private ResultToken checkRequiredVariablesForEnsure()
{ {
ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString()); ResultToken resultToken = new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString());
@@ -601,41 +616,52 @@ namespace C4IT_IAM_SET
if (parent.Parent != null) if (parent.Parent != null)
{ {
DefaultLogger.LogEntry(LogLevels.Debug, "Parent.Parent ist nicht null. Erstelle AD-Gruppe."); DefaultLogger.LogEntry(LogLevels.Debug, "Parent.Parent ist nicht null. Erstelle AD-Gruppe.");
try if (WhatIf)
{ {
newSecurityGroups.CreateADGroup(groupOUPath, newTraverseGroup, null);
DefaultLogger.LogEntry(LogLevels.Debug, $"AD-Gruppe erstellt: {newTraverseGroup.Name}");
resultToken.createdGroups.Add(newTraverseGroup.Name); resultToken.createdGroups.Add(newTraverseGroup.Name);
resultToken.ensuredTraverseGroups.Add(newTraverseGroup.Name); resultToken.ensuredTraverseGroups.Add(newTraverseGroup.Name);
} resultToken.warnings.Add($"Traverse-Gruppe würde angelegt werden: {newTraverseGroup.Name}");
catch (Exception ex) resultToken.addedAclEntries.Add(newTraverseGroup.Name);
{
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Erstellen der AD-Gruppe: {ex.Message}");
continue;
}
parentTraverseGroup = GroupPrincipal.FindByIdentity(domainContext, newTraverseGroup.Name);
if (parentTraverseGroup == null)
{
DefaultLogger.LogEntry(LogLevels.Error, $"parentTraverseGroup konnte nach Erstellung der Gruppe nicht gefunden werden: {newTraverseGroup.Name}");
continue;
}
try
{
var accesscontrol = parent.GetAccessControl();
accesscontrol.AddAccessRule(new FileSystemAccessRule(parentTraverseGroup.Sid,
FileSystemRights.Read, InheritanceFlags.None, PropagationFlags.None,
AccessControlType.Allow));
DefaultLogger.LogEntry(LogLevels.Debug, $"Setze Traverse-ACL auf: {parent.FullName} für {parentTraverseGroup.DistinguishedName}");
parent.SetAccessControl(accesscontrol);
resultToken.addedAclEntries.Add(parentTraverseGroup.Name);
parentTraverseAclExists = true; parentTraverseAclExists = true;
} }
catch (Exception ex) else
{ {
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Setzen der ACL: {ex.Message}"); try
continue; {
newSecurityGroups.CreateADGroup(groupOUPath, newTraverseGroup, null);
DefaultLogger.LogEntry(LogLevels.Debug, $"AD-Gruppe erstellt: {newTraverseGroup.Name}");
resultToken.createdGroups.Add(newTraverseGroup.Name);
resultToken.ensuredTraverseGroups.Add(newTraverseGroup.Name);
}
catch (Exception ex)
{
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Erstellen der AD-Gruppe: {ex.Message}");
continue;
}
parentTraverseGroup = GroupPrincipal.FindByIdentity(domainContext, newTraverseGroup.Name);
if (parentTraverseGroup == null)
{
DefaultLogger.LogEntry(LogLevels.Error, $"parentTraverseGroup konnte nach Erstellung der Gruppe nicht gefunden werden: {newTraverseGroup.Name}");
continue;
}
try
{
var accesscontrol = parent.GetAccessControl();
accesscontrol.AddAccessRule(new FileSystemAccessRule(parentTraverseGroup.Sid,
FileSystemRights.Read, InheritanceFlags.None, PropagationFlags.None,
AccessControlType.Allow));
DefaultLogger.LogEntry(LogLevels.Debug, $"Setze Traverse-ACL auf: {parent.FullName} für {parentTraverseGroup.DistinguishedName}");
parent.SetAccessControl(accesscontrol);
resultToken.addedAclEntries.Add(parentTraverseGroup.Name);
parentTraverseAclExists = true;
}
catch (Exception ex)
{
DefaultLogger.LogEntry(LogLevels.Error, $"Fehler beim Setzen der ACL: {ex.Message}");
continue;
}
} }
} }
else else
@@ -662,10 +688,13 @@ namespace C4IT_IAM_SET
} }
else else
{ {
accessControl.AddAccessRule(new FileSystemAccessRule(parentTraverseGroup.Sid, if (!WhatIf)
FileSystemRights.Read, InheritanceFlags.None, PropagationFlags.None, {
AccessControlType.Allow)); accessControl.AddAccessRule(new FileSystemAccessRule(parentTraverseGroup.Sid,
parent.SetAccessControl(accessControl); FileSystemRights.Read, InheritanceFlags.None, PropagationFlags.None,
AccessControlType.Allow));
parent.SetAccessControl(accessControl);
}
resultToken.addedAclEntries.Add(parentTraverseGroup.Name); resultToken.addedAclEntries.Add(parentTraverseGroup.Name);
} }
} }
@@ -681,8 +710,11 @@ namespace C4IT_IAM_SET
if (i == lvl) if (i == lvl)
{ {
DefaultLogger.LogEntry(LogLevels.Debug, "Verarbeite SecurityGroups bei oberster Ebene."); DefaultLogger.LogEntry(LogLevels.Debug, "Verarbeite SecurityGroups bei oberster Ebene.");
DefaultLogger.LogEntry(LogLevels.Debug, "Warte 3min."); if (!WhatIf)
System.Threading.Thread.Sleep(180000); // 60 Sekunden warten {
DefaultLogger.LogEntry(LogLevels.Debug, "Warte 3min.");
System.Threading.Thread.Sleep(180000); // 60 Sekunden warten
}
foreach (var currentSecGroup in newSecurityGroups.IAM_SecurityGroups) foreach (var currentSecGroup in newSecurityGroups.IAM_SecurityGroups)
{ {
if (currentSecGroup == null) if (currentSecGroup == null)
@@ -704,9 +736,16 @@ namespace C4IT_IAM_SET
{ {
if (!parentTraverseGroup.Members.Contains(groupPrincipal)) if (!parentTraverseGroup.Members.Contains(groupPrincipal))
{ {
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {groupPrincipal.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu"); if (WhatIf)
parentTraverseGroup.Members.Add(groupPrincipal); {
parentTraverseGroup.Save(); resultToken.warnings.Add($"Traverse-Gruppe '{parentTraverseGroup.Name}' würde Mitglied '{groupPrincipal.Name}' erhalten.");
}
else
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {groupPrincipal.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu");
parentTraverseGroup.Members.Add(groupPrincipal);
parentTraverseGroup.Save();
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -727,9 +766,16 @@ namespace C4IT_IAM_SET
{ {
if (!parentTraverseGroup.Members.Contains(traverseGroup)) if (!parentTraverseGroup.Members.Contains(traverseGroup))
{ {
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {traverseGroup.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu"); if (WhatIf)
parentTraverseGroup.Members.Add(traverseGroup); {
parentTraverseGroup.Save(); resultToken.warnings.Add($"Traverse-Gruppe '{parentTraverseGroup.Name}' würde verschachtelte Gruppe '{traverseGroup.Name}' erhalten.");
}
else
{
DefaultLogger.LogEntry(LogLevels.Debug, $"Füge {traverseGroup.DistinguishedName} zur Traverse-Gruppe {parentTraverseGroup.DistinguishedName} hinzu");
parentTraverseGroup.Members.Add(traverseGroup);
parentTraverseGroup.Save();
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -741,8 +787,11 @@ namespace C4IT_IAM_SET
} }
try try
{ {
parentTraverseGroup.Save(); if (!WhatIf)
DefaultLogger.LogEntry(LogLevels.Debug, $"parentTraverseGroup gespeichert: {parentTraverseGroup.Name}"); {
parentTraverseGroup.Save();
DefaultLogger.LogEntry(LogLevels.Debug, $"parentTraverseGroup gespeichert: {parentTraverseGroup.Name}");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -974,6 +1023,26 @@ namespace C4IT_IAM_SET
} }
else else
{ {
if (WhatIf)
{
newDataArea.IAM_Folders[0].UID = DataArea.GetUniqueDataAreaID(newDataArea.IAM_Folders[0].technicalName);
resultToken.warnings.Add($"Verzeichnis würde erstellt werden: {newDataArea.IAM_Folders[0].technicalName}");
for (int i = 0; newSecurityGroups.IAM_SecurityGroups.Count > i; i++)
{
var currentSecGroup = newSecurityGroups.IAM_SecurityGroups[i];
if (groupPermissionStrategy == PermissionGroupStrategy.AGDLP && currentSecGroup.Scope == GroupScope.Local
|| groupPermissionStrategy == PermissionGroupStrategy.AGP && currentSecGroup.Scope == GroupScope.Global)
{
resultToken.addedAclEntries.Add(currentSecGroup.Name);
}
}
resultToken.resultErrorId = 0;
resultToken.resultMessage = "Verzeichnis-, Gruppen- und ACL-Vorschau erfolgreich erstellt";
return resultToken;
}
DefaultLogger.LogEntry(LogLevels.Debug, $"Creating folder: {newDataArea.IAM_Folders[0].technicalName}"); DefaultLogger.LogEntry(LogLevels.Debug, $"Creating folder: {newDataArea.IAM_Folders[0].technicalName}");
DirectoryInfo newDir = Directory.CreateDirectory(newDataArea.IAM_Folders[0].technicalName); DirectoryInfo newDir = Directory.CreateDirectory(newDataArea.IAM_Folders[0].technicalName);
newDataArea.IAM_Folders[0].UID = DataArea.GetUniqueDataAreaID(newDir.FullName); newDataArea.IAM_Folders[0].UID = DataArea.GetUniqueDataAreaID(newDir.FullName);
@@ -1026,7 +1095,7 @@ namespace C4IT_IAM_SET
LogMethodEnd(MethodBase.GetCurrentMethod()); LogMethodEnd(MethodBase.GetCurrentMethod());
} }
private void createADGroups() private void createADGroups(ResultToken resultToken)
{ {
LogMethodBegin(MethodBase.GetCurrentMethod()); LogMethodBegin(MethodBase.GetCurrentMethod());
@@ -1085,7 +1154,24 @@ namespace C4IT_IAM_SET
users = readers; users = readers;
else else
users = null; users = null;
newSecurityGroups.CreateADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], users);
if (WhatIf)
{
var existingGroup = newSecurityGroups.PreviewADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], newDataArea.IAM_Folders[0].technicalName);
newSecurityGroups.IAM_SecurityGroups[i].CreatedNewEntry = existingGroup == null;
}
else
{
newSecurityGroups.CreateADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], users);
}
if (resultToken != null)
{
if (newSecurityGroups.IAM_SecurityGroups[i].CreatedNewEntry)
resultToken.createdGroups.Add(newSecurityGroups.IAM_SecurityGroups[i].Name);
else
resultToken.reusedGroups.Add(newSecurityGroups.IAM_SecurityGroups[i].Name);
}
} }
} }
catch (Exception E) catch (Exception E)

View File

@@ -96,7 +96,8 @@ namespace LiamWorkflowActivities
return result; return result;
} }
if (!await EnsureNtfsPermissionGroupsIfConfiguredAsync(provider, dataAreas, result, simulateConfiguredNtfsPermissionEnsure)) var workflowWhatIf = IsWorkflowWhatIfEnabled(provider);
if (!await EnsureNtfsPermissionGroupsIfConfiguredAsync(provider, dataAreas, result, simulateConfiguredNtfsPermissionEnsure || workflowWhatIf))
return result; return result;
result.DataAreas = dataAreas result.DataAreas = dataAreas
@@ -170,7 +171,8 @@ namespace LiamWorkflowActivities
customTags, customTags,
NormalizeIdentifierList(ownerSids), NormalizeIdentifierList(ownerSids),
NormalizeIdentifierList(readerSids), NormalizeIdentifierList(readerSids),
NormalizeIdentifierList(writerSids)); NormalizeIdentifierList(writerSids),
IsWorkflowWhatIfEnabled(provider));
if (token == null) if (token == null)
token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while creating the data area."); token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while creating the data area.");
result.ResultToken = token; result.ResultToken = token;
@@ -202,7 +204,8 @@ namespace LiamWorkflowActivities
NormalizeIdentifierList(ownerSids), NormalizeIdentifierList(ownerSids),
NormalizeIdentifierList(readerSids), NormalizeIdentifierList(readerSids),
NormalizeIdentifierList(writerSids), NormalizeIdentifierList(writerSids),
ensureTraverseGroups); ensureTraverseGroups,
IsWorkflowWhatIfEnabled(provider));
if (token == null) if (token == null)
token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while ensuring NTFS permission groups."); token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while ensuring NTFS permission groups.");
result.ResultToken = token; result.ResultToken = token;
@@ -570,6 +573,11 @@ namespace LiamWorkflowActivities
|| rawValue.Equals("yes", StringComparison.OrdinalIgnoreCase); || rawValue.Equals("yes", StringComparison.OrdinalIgnoreCase);
} }
private static bool IsWorkflowWhatIfEnabled(cLiamProviderBase provider)
{
return IsAdditionalConfigurationEnabled(provider, "WhatIf");
}
private static void SetErrorFromProvider(GetDataAreasOperationResult result, cLiamProviderBase provider, string fallbackCode, string fallbackMessage) private static void SetErrorFromProvider(GetDataAreasOperationResult result, cLiamProviderBase provider, string fallbackCode, string fallbackMessage)
{ {
var error = ExtractProviderError(provider, fallbackCode, fallbackMessage); var error = ExtractProviderError(provider, fallbackCode, fallbackMessage);