using System.Security.Claims; using System.Text.Json; using Microsoft.AspNetCore.Authentication; namespace WorkClub.Api.Auth; public class ClubRoleClaimsTransformation : IClaimsTransformation { private readonly IHttpContextAccessor _httpContextAccessor; public ClubRoleClaimsTransformation(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public Task TransformAsync(ClaimsPrincipal principal) { if (principal.Identity is not ClaimsIdentity identity || !identity.IsAuthenticated) { return Task.FromResult(principal); } var clubsClaim = principal.FindFirst("clubs")?.Value; if (string.IsNullOrEmpty(clubsClaim)) { return Task.FromResult(principal); } Dictionary? clubsDict; try { clubsDict = JsonSerializer.Deserialize>(clubsClaim); } catch (JsonException) { return Task.FromResult(principal); } if (clubsDict == null || clubsDict.Count == 0) { return Task.FromResult(principal); } var tenantId = _httpContextAccessor.HttpContext?.Request.Headers["X-Tenant-Id"].FirstOrDefault(); if (string.IsNullOrEmpty(tenantId)) { return Task.FromResult(principal); } if (!clubsDict.TryGetValue(tenantId, out var clubRole)) { return Task.FromResult(principal); } var mappedRole = MapClubRoleToAspNetRole(clubRole); identity.AddClaim(new Claim(ClaimTypes.Role, mappedRole)); return Task.FromResult(principal); } private static string MapClubRoleToAspNetRole(string clubRole) { return clubRole.ToLowerInvariant() switch { "admin" => "Admin", "manager" => "Manager", "member" => "Member", "viewer" => "Viewer", _ => "Viewer" }; } }