using ScadaLink.Commons.Interfaces.Repositories; namespace ScadaLink.Security; public class RoleMapper { private readonly ISecurityRepository _securityRepository; public RoleMapper(ISecurityRepository securityRepository) { _securityRepository = securityRepository ?? throw new ArgumentNullException(nameof(securityRepository)); } // virtual: a test seam so HTTP-pipeline tests (e.g. the #23 M8 audit // endpoints) can substitute the LDAP-group→role resolution. public virtual async Task MapGroupsToRolesAsync( IReadOnlyList ldapGroups, CancellationToken ct = default) { var allMappings = await _securityRepository.GetAllMappingsAsync(ct); var matchedRoles = new HashSet(StringComparer.OrdinalIgnoreCase); var permittedSiteIds = new HashSet(); var hasDeploymentRole = false; var hasDeploymentWithScopeRules = false; foreach (var mapping in allMappings) { // Match LDAP group names (case-insensitive) if (!ldapGroups.Any(g => g.Equals(mapping.LdapGroupName, StringComparison.OrdinalIgnoreCase))) continue; matchedRoles.Add(mapping.Role); if (mapping.Role.Equals("Deployment", StringComparison.OrdinalIgnoreCase)) { hasDeploymentRole = true; // Check for site scope rules var scopeRules = await _securityRepository.GetScopeRulesForMappingAsync(mapping.Id, ct); if (scopeRules.Count > 0) { hasDeploymentWithScopeRules = true; foreach (var rule in scopeRules) { permittedSiteIds.Add(rule.SiteId.ToString()); } } } } // System-wide deployment: user has Deployment role but no site scope rules restrict them var isSystemWide = hasDeploymentRole && !hasDeploymentWithScopeRules; return new RoleMappingResult( matchedRoles.ToList(), permittedSiteIds.ToList(), isSystemWide); } }