Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.CentralUI/Auth/ClaimsPrincipalExtensions.cs
T
Joseph Doherty 0ffd4bdbea docs(src): fix CommentChecker findings across src/ — 1,032 → 5 (all false positives)
Comment/XML-doc changes only, no code logic:
- strip project-tracking references (WP*, P*-*, row-NN, #NN, Task N) from
  comments, keeping the explanatory rationale
- add missing summaries, <param>, <returns>, <typeparam> and <inheritdoc/>
- replace misused <inheritdoc/> with real docs; where <inheritdoc/> was
  combined with useful remarks, move the rationale into // comments
- drop stale replicationActor <param> on DeploymentManagerActor ctor

Remaining 5 are false positives (CWE-1236 x2, failures-1, year-0001, M365).
Build 0 errors / 0 warnings.
2026-10-07 14:12:25 -04:00

69 lines
3.6 KiB
C#

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