From 3ec73817e85f876baebc601240bd371ee81623b5 Mon Sep 17 00:00:00 2001 From: Meik Date: Wed, 18 Mar 2026 14:17:40 +0100 Subject: [PATCH] Preview NTFS auto ensure in diagnostics --- LiamNtfs/C4IT.LIAM.Ntfs.cs | 4 +- LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs | 33 +++++++++- LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs | 33 ++++++++++ LiamWorkflowActivities/LiamWorkflowRuntime.cs | 63 +++++++++++++++++-- LiamWorkflowDiagnostics/MainWindow.xaml.cs | 8 ++- 5 files changed, 132 insertions(+), 9 deletions(-) diff --git a/LiamNtfs/C4IT.LIAM.Ntfs.cs b/LiamNtfs/C4IT.LIAM.Ntfs.cs index 02e0710..512b5c9 100644 --- a/LiamNtfs/C4IT.LIAM.Ntfs.cs +++ b/LiamNtfs/C4IT.LIAM.Ntfs.cs @@ -643,7 +643,8 @@ namespace C4IT.LIAM IEnumerable ownerSids, IEnumerable readerSids, IEnumerable writerSids, - bool ensureTraverseGroups = false) + bool ensureTraverseGroups = false, + bool whatIf = false) { var parentPath = Directory.GetParent(folderPath)?.FullName; var engine = CreateFilesystemEngine( @@ -653,6 +654,7 @@ namespace C4IT.LIAM ownerSids, readerSids, writerSids); + engine.WhatIf = whatIf; return Task.FromResult(engine.ensureDataAreaPermissions(ensureTraverseGroups)); } diff --git a/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs b/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs index ccf7a44..ccf3ea3 100644 --- a/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs +++ b/LiamNtfs/C4IT_IAM_SET/DataArea_FileSystem.cs @@ -52,6 +52,7 @@ namespace C4IT_IAM_SET public ICollection readerUserSids; public ICollection writerUserSids; public bool forceStrictAdGroupNames; + public bool WhatIf; public int ReadACLPermission = 0x200A9; public int WriteACLPermission = 0x301BF; @@ -317,6 +318,13 @@ namespace C4IT_IAM_SET if (ensureTraverseGroups) { + if (WhatIf) + { + resultToken.warnings.Add("Traverse group preview is not supported in WhatIf mode for automatic DataArea ensure."); + resultToken.resultMessage = "Gruppen- und ACL-Vorschau erfolgreich erstellt"; + return resultToken; + } + var traverseResult = SetTraversePermissions(); if (traverseResult != null) { @@ -335,7 +343,9 @@ namespace C4IT_IAM_SET } } - resultToken.resultMessage = "Gruppen und ACLs erfolgreich sichergestellt"; + resultToken.resultMessage = WhatIf + ? "Gruppen- und ACL-Vorschau erfolgreich erstellt" + : "Gruppen und ACLs erfolgreich sichergestellt"; return resultToken; } } @@ -835,6 +845,12 @@ namespace C4IT_IAM_SET var directory = new DirectoryInfo(newDataArea.IAM_Folders[0].technicalName); foreach (var currentSecGroup in newSecurityGroups.IAM_SecurityGroups) { + if (WhatIf && string.IsNullOrWhiteSpace(currentSecGroup?.UID) && currentSecGroup?.CreatedNewEntry == true) + { + resultToken.addedAclEntries.Add(currentSecGroup.Name); + continue; + } + if (string.IsNullOrWhiteSpace(currentSecGroup?.UID)) { resultToken.warnings.Add($"Keine SID für Gruppe '{currentSecGroup?.Name}' verfügbar."); @@ -854,7 +870,9 @@ namespace C4IT_IAM_SET continue; } - DataArea.AddDirectorySecurity(newDataArea.IAM_Folders[0].baseFolder, newDataArea.IAM_Folders[0].technicalName, sid, currentSecGroup.rights, AccessControlType.Allow); + if (!WhatIf) + DataArea.AddDirectorySecurity(newDataArea.IAM_Folders[0].baseFolder, newDataArea.IAM_Folders[0].technicalName, sid, currentSecGroup.rights, AccessControlType.Allow); + resultToken.addedAclEntries.Add(currentSecGroup.Name); } @@ -912,7 +930,16 @@ namespace C4IT_IAM_SET else users = null; - newSecurityGroups.EnsureADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], users, newDataArea.IAM_Folders[0].technicalName); + 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.EnsureADGroup(groupOUPath, newSecurityGroups.IAM_SecurityGroups[i], users, newDataArea.IAM_Folders[0].technicalName); + } + if (newSecurityGroups.IAM_SecurityGroups[i].CreatedNewEntry) resultToken.createdGroups.Add(newSecurityGroups.IAM_SecurityGroups[i].Name); else diff --git a/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs b/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs index 89e7bd0..14ca3b3 100644 --- a/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs +++ b/LiamNtfs/C4IT_IAM_SET/SecurityGroup.cs @@ -638,6 +638,39 @@ namespace C4IT_IAM_Engine } } + public DirectoryEntry PreviewADGroup(string ouPath, IAM_SecurityGroup secGroup, string folderPath = null) + { + LogMethodBegin(MethodBase.GetCurrentMethod()); + try + { + secGroup.CreatedNewEntry = false; + DirectoryEntry existingGroup = null; + if (!ForceStrictAdGroupNames) + existingGroup = FindGroupEntryFromFolderAcl(folderPath, secGroup.WildcardPattern); + + if (existingGroup == null) + existingGroup = FindGroupEntry(secGroup.Name); + + if (existingGroup == null && !ForceStrictAdGroupNames && string.IsNullOrWhiteSpace(folderPath)) + existingGroup = FindGroupEntryByWildcard(ouPath, secGroup.WildcardPattern); + + if (existingGroup == null) + return null; + + ApplyExistingGroup(secGroup, existingGroup); + return existingGroup; + } + catch (Exception E) + { + cLogManager.DefaultLogger.LogException(E); + throw; + } + finally + { + LogMethodEnd(MethodBase.GetCurrentMethod()); + } + } + public DirectoryEntry CreateADGroup(string ouPath, IAM_SecurityGroup secGroup, List users) { LogMethodBegin(MethodBase.GetCurrentMethod()); diff --git a/LiamWorkflowActivities/LiamWorkflowRuntime.cs b/LiamWorkflowActivities/LiamWorkflowRuntime.cs index 1d4ae84..ead2d9e 100644 --- a/LiamWorkflowActivities/LiamWorkflowRuntime.cs +++ b/LiamWorkflowActivities/LiamWorkflowRuntime.cs @@ -19,6 +19,20 @@ namespace LiamWorkflowActivities public string ErrorCode { get; set; } = string.Empty; public string ErrorMessage { get; set; } = string.Empty; public List DataAreas { get; set; } = new List(); + public List AutomaticEnsurePreview { get; set; } = new List(); + } + + public class NtfsAutomaticEnsurePreviewEntry + { + public string FolderPath { get; set; } = string.Empty; + public bool WhatIf { get; set; } = true; + public string Message { get; set; } = string.Empty; + public List WouldCreateGroups { get; set; } = new List(); + public List WouldReuseGroups { get; set; } = new List(); + public List WouldAddAclEntries { get; set; } = new List(); + public List ExistingAclEntries { get; set; } = new List(); + public List WouldEnsureTraverseGroups { get; set; } = new List(); + public List Warnings { get; set; } = new List(); } public class GetSecurityGroupsOperationResult @@ -63,7 +77,7 @@ namespace LiamWorkflowActivities public static class LiamWorkflowRuntime { - public static async Task GetDataAreasFromProviderAsync(cLiamProviderBase provider, string configurationId = null) + public static async Task GetDataAreasFromProviderAsync(cLiamProviderBase provider, string configurationId = null, bool simulateConfiguredNtfsPermissionEnsure = false) { var result = new GetDataAreasOperationResult(); if (provider == null) @@ -82,7 +96,7 @@ namespace LiamWorkflowActivities return result; } - if (!await EnsureNtfsPermissionGroupsIfConfiguredAsync(provider, dataAreas, result)) + if (!await EnsureNtfsPermissionGroupsIfConfiguredAsync(provider, dataAreas, result, simulateConfiguredNtfsPermissionEnsure)) return result; result.DataAreas = dataAreas @@ -395,7 +409,7 @@ namespace LiamWorkflowActivities .ToList(); } - private static async Task EnsureNtfsPermissionGroupsIfConfiguredAsync(cLiamProviderBase provider, List dataAreas, GetDataAreasOperationResult result) + private static async Task EnsureNtfsPermissionGroupsIfConfiguredAsync(cLiamProviderBase provider, List dataAreas, GetDataAreasOperationResult result, bool simulateOnly) { if (!(provider is cLiamProviderNtfs ntfsProvider)) return true; @@ -421,7 +435,8 @@ namespace LiamWorkflowActivities null, null, null, - false); + false, + simulateOnly); if (ensureResult == null) { result.ErrorCode = "WF_GET_DATAAREAS_ENSURE_NTFS_GROUPS_FAILED"; @@ -436,6 +451,13 @@ namespace LiamWorkflowActivities return false; } + if (simulateOnly) + { + LogAutomaticNtfsEnsurePreviewDebug(folderPath, ensureResult); + result.AutomaticEnsurePreview.Add(MapAutomaticEnsurePreview(folderPath, ensureResult)); + continue; + } + LogAutomaticNtfsEnsureDebug(folderPath, ensureResult); await ntfsArea.ResolvePermissionGroupsAsync(folderPath); } @@ -443,6 +465,39 @@ namespace LiamWorkflowActivities return true; } + private static NtfsAutomaticEnsurePreviewEntry MapAutomaticEnsurePreview(string folderPath, ResultToken ensureResult) + { + return new NtfsAutomaticEnsurePreviewEntry + { + FolderPath = folderPath ?? string.Empty, + WhatIf = true, + Message = ensureResult?.resultMessage ?? string.Empty, + WouldCreateGroups = ensureResult?.createdGroups?.ToList() ?? new List(), + WouldReuseGroups = ensureResult?.reusedGroups?.ToList() ?? new List(), + WouldAddAclEntries = ensureResult?.addedAclEntries?.ToList() ?? new List(), + ExistingAclEntries = ensureResult?.skippedAclEntries?.ToList() ?? new List(), + WouldEnsureTraverseGroups = ensureResult?.ensuredTraverseGroups?.ToList() ?? new List(), + Warnings = ensureResult?.warnings?.ToList() ?? new List() + }; + } + + private static void LogAutomaticNtfsEnsurePreviewDebug(string folderPath, ResultToken ensureResult) + { + if (ensureResult == null) + return; + + LogEntry( + $"Automatic NTFS permission group ensure preview finished for '{folderPath}'. " + + $"WouldCreateGroups={ensureResult.createdGroups.Count}, " + + $"WouldReuseGroups={ensureResult.reusedGroups.Count}, " + + $"WouldAddAcls={ensureResult.addedAclEntries.Count}, " + + $"ExistingAcls={ensureResult.skippedAclEntries.Count}, " + + $"WouldEnsureTraverseGroups={ensureResult.ensuredTraverseGroups.Count}, " + + $"Warnings={ensureResult.warnings.Count}, " + + $"ResultMessage='{ensureResult.resultMessage ?? string.Empty}'", + LogLevels.Debug); + } + private static void LogAutomaticNtfsEnsureDebug(string folderPath, ResultToken ensureResult) { if (ensureResult == null) diff --git a/LiamWorkflowDiagnostics/MainWindow.xaml.cs b/LiamWorkflowDiagnostics/MainWindow.xaml.cs index 016673a..28a8b9d 100644 --- a/LiamWorkflowDiagnostics/MainWindow.xaml.cs +++ b/LiamWorkflowDiagnostics/MainWindow.xaml.cs @@ -562,7 +562,8 @@ namespace LiamWorkflowDiagnostics _session.Provider, !string.IsNullOrWhiteSpace(_session.ProviderConfigObjectId) ? _session.ProviderConfigObjectId - : (_session.ProviderConfigId ?? string.Empty)); + : (_session.ProviderConfigId ?? string.Empty), + IsWhatIfEnabled); ResultTextBox.Text = JsonConvert.SerializeObject(result, Formatting.Indented); if (!result.Success) @@ -577,6 +578,11 @@ namespace LiamWorkflowDiagnostics return; } + if (IsWhatIfEnabled && result.AutomaticEnsurePreview != null && result.AutomaticEnsurePreview.Count > 0) + { + AppendLog($"EnsureNtfsPermissionGroups wurde nur simuliert fuer {result.AutomaticEnsurePreview.Count} Ordner. Details stehen im Result-JSON.", LogLevels.Warning); + } + AppendLog($"DataAreas erhalten: {result.DataAreas.Count}"); } catch (Exception ex)