using ChessCubing.Server.Auth; using System.Security.Claims; namespace ChessCubing.Server.Users; public sealed record AuthenticatedSiteUser( string Subject, string Username, string? Email, string DisplayName); public static class AuthenticatedSiteUserFactory { public static AuthenticatedSiteUser? FromKeycloakUserInfo(KeycloakUserInfo userInfo) { if (string.IsNullOrWhiteSpace(userInfo.Subject)) { return null; } var username = string.IsNullOrWhiteSpace(userInfo.PreferredUsername) ? userInfo.Subject : userInfo.PreferredUsername; var displayName = string.IsNullOrWhiteSpace(userInfo.Name) ? username : userInfo.Name; return new AuthenticatedSiteUser( userInfo.Subject.Trim(), username.Trim(), string.IsNullOrWhiteSpace(userInfo.Email) ? null : userInfo.Email.Trim(), displayName.Trim()); } public static AuthenticatedSiteUser? FromClaimsPrincipal(ClaimsPrincipal user) { if (user.Identity?.IsAuthenticated != true) { return null; } var subject = user.FindFirst("sub")?.Value ?? user.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrWhiteSpace(subject)) { return null; } var username = user.FindFirst("preferred_username")?.Value ?? user.Identity?.Name ?? subject; var email = user.FindFirst("email")?.Value; var displayName = user.FindFirst("name")?.Value ?? username; return new AuthenticatedSiteUser( subject.Trim(), username.Trim(), string.IsNullOrWhiteSpace(email) ? null : email.Trim(), displayName.Trim()); } }