feat(auth): add IGroupRoleMapper<string> seam (Task 1.1)
This commit is contained in:
@@ -142,56 +142,20 @@ public sealed class DashboardAuthenticator(
|
||||
/// Maps the user's LDAP groups to dashboard roles. A user can pick up
|
||||
/// multiple roles; Admin and Viewer are the only legal values. Returns
|
||||
/// an empty list when no group matches (caller rejects the login).
|
||||
/// Delegates to <see cref="DashboardGroupRoleMapping"/>, the single source
|
||||
/// of truth shared with <see cref="DashboardGroupRoleMapper"/>.
|
||||
/// </summary>
|
||||
/// <param name="groups">The collection of LDAP groups the user belongs to.</param>
|
||||
/// <param name="groupToRole">The mapping from group names to dashboard role names.</param>
|
||||
internal static IReadOnlyList<string> MapGroupsToRoles(
|
||||
IEnumerable<string> groups,
|
||||
IReadOnlyDictionary<string, string> groupToRole)
|
||||
{
|
||||
if (groupToRole.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
HashSet<string> roles = new(StringComparer.Ordinal);
|
||||
foreach (string group in groups)
|
||||
{
|
||||
string normalizedGroup = group.Trim();
|
||||
|
||||
// Lookup precedence (Server-040): the full literal group string is
|
||||
// tried first; only if that misses do we fall back to the leading
|
||||
// RDN value (e.g. "GwAdmin" extracted from
|
||||
// "ou=GwAdmin,ou=groups,..."). The map's comparer is
|
||||
// OrdinalIgnoreCase (see DashboardOptions.GroupToRole), so e.g.
|
||||
// "GwAdmin" and "gwadmin" both match.
|
||||
if (groupToRole.TryGetValue(normalizedGroup, out string? mapped)
|
||||
|| groupToRole.TryGetValue(ExtractFirstRdnValue(normalizedGroup), out mapped))
|
||||
{
|
||||
roles.Add(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
return [.. roles];
|
||||
}
|
||||
=> DashboardGroupRoleMapping.MapGroupsToRoles(groups, groupToRole);
|
||||
|
||||
/// <summary>Extracts the first RDN value from a distinguished name.</summary>
|
||||
/// <param name="distinguishedName">The LDAP distinguished name.</param>
|
||||
internal static string ExtractFirstRdnValue(string distinguishedName)
|
||||
{
|
||||
int equalsIndex = distinguishedName.IndexOf('=');
|
||||
if (equalsIndex < 0)
|
||||
{
|
||||
return distinguishedName;
|
||||
}
|
||||
|
||||
int valueStart = equalsIndex + 1;
|
||||
int commaIndex = distinguishedName.IndexOf(',', valueStart);
|
||||
|
||||
return commaIndex > valueStart
|
||||
? distinguishedName[valueStart..commaIndex]
|
||||
: distinguishedName[valueStart..];
|
||||
}
|
||||
=> DashboardGroupRoleMapping.ExtractFirstRdnValue(distinguishedName);
|
||||
|
||||
private static Task BindServiceAccountAsync(
|
||||
LdapConnection connection,
|
||||
|
||||
Reference in New Issue
Block a user