diff --git a/SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs b/SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs index b383da2..d2ec7c2 100644 --- a/SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs +++ b/SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs @@ -27,6 +27,7 @@ public partial class PermissionsViewModel : FeatureViewModelBase private readonly CsvExportService? _csvExportService; private readonly HtmlExportService? _htmlExportService; private readonly IBrandingService? _brandingService; + private readonly ISharePointGroupResolver? _groupResolver; private readonly ILogger _logger; // ── Observable properties ─────────────────────────────────────────────── @@ -134,7 +135,8 @@ public partial class PermissionsViewModel : FeatureViewModelBase CsvExportService csvExportService, HtmlExportService htmlExportService, IBrandingService brandingService, - ILogger logger) + ILogger logger, + ISharePointGroupResolver? groupResolver = null) : base(logger) { _permissionsService = permissionsService; @@ -143,6 +145,7 @@ public partial class PermissionsViewModel : FeatureViewModelBase _csvExportService = csvExportService; _htmlExportService = htmlExportService; _brandingService = brandingService; + _groupResolver = groupResolver; _logger = logger; ExportCsvCommand = new AsyncRelayCommand(ExportCsvAsync, CanExport); @@ -330,10 +333,37 @@ public partial class PermissionsViewModel : FeatureViewModelBase branding = new ReportBranding(mspLogo, clientLogo); } + IReadOnlyDictionary>? groupMembers = null; + if (_groupResolver != null && Results.Count > 0) + { + var groupNames = Results + .Where(r => r.PrincipalType == "SharePointGroup") + .SelectMany(r => r.Users.Split(';', StringSplitOptions.RemoveEmptyEntries)) + .Select(n => n.Trim()) + .Where(n => n.Length > 0) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + if (groupNames.Count > 0 && _currentProfile != null) + { + try + { + var ctx = await _sessionManager.GetOrCreateContextAsync( + _currentProfile, CancellationToken.None); + groupMembers = await _groupResolver.ResolveGroupsAsync( + ctx, _currentProfile.ClientId, groupNames, CancellationToken.None); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Group resolution failed — exporting without member expansion."); + } + } + } + if (IsSimplifiedMode && SimplifiedResults.Count > 0) - await _htmlExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None, branding); + await _htmlExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None, branding, groupMembers); else - await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None, branding); + await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None, branding, groupMembers); OpenFile(dialog.FileName); } catch (Exception ex)