using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
///
/// Claim-lookup helpers for the Central UI. Claim types are owned
/// by (the single source of truth). These helpers
/// resolve them through the JwtTokenService constants so a rename there
/// propagates here instead of silently breaking ten copy-pasted call sites.
///
public static class ClaimsPrincipalExtensions
{
/// Gets fresh mutation authority, failing closed on a mapping error.
/// The authentication state provider.
/// The authoritative authentication state.
public static Task GetAuthoritativeStateAsync(this AuthenticationStateProvider provider)
=> provider is CookieAuthenticationStateProvider cookie
? cookie.GetAuthoritativeStateAsync() : provider.GetAuthenticationStateAsync();
/// Checks the current grant before invoking a directly audited application service.
/// The authentication state provider.
/// The role the current session must hold.
/// The username of the authorized principal.
public static async Task RequireRoleAsync(this AuthenticationStateProvider provider, string role)
{
var principal = (await provider.GetAuthoritativeStateAsync()).User;
if (principal.Identity?.IsAuthenticated != true || !principal.HasClaim(JwtTokenService.RoleClaimType, role))
throw new UnauthorizedAccessException($"The current session requires the {role} role.");
return principal.GetUsername();
}
/// Fallback returned when no username claim is present.
public const string UnknownUser = "unknown";
///
/// The audit username for , or
/// when the claim is absent.
///
/// The claims principal to read the username from.
/// The username claim value, or if absent.
public static string GetUsername(this ClaimsPrincipal principal)
=> principal.FindFirst(JwtTokenService.UsernameClaimType)?.Value ?? UnknownUser;
///
/// The display name for , or null when
/// the claim is absent.
///
/// The claims principal to read the display name from.
/// The display name claim value, or null if the claim is absent.
public static string? GetDisplayName(this ClaimsPrincipal principal)
=> principal.FindFirst(JwtTokenService.DisplayNameClaimType)?.Value;
///
/// Resolves the current user's audit username from the auth state provider.
/// Replaces the GetCurrentUserAsync helper that was copy-pasted into
/// ten components.
///
/// The Blazor authentication state provider to read from.
/// A task that resolves to the current user's audit username, or if not authenticated.
public static async Task GetCurrentUsernameAsync(
this AuthenticationStateProvider authStateProvider)
{
var authState = await authStateProvider.GetAuthenticationStateAsync();
return authState.User.GetUsername();
}
}