diff --git a/EnvelopeGenerator.API/Extensions/EnvelopeAuthExtensions.cs b/EnvelopeGenerator.API/Extensions/EnvelopeAuthExtensions.cs index 8e7d6d7e..054677a0 100644 --- a/EnvelopeGenerator.API/Extensions/EnvelopeAuthExtensions.cs +++ b/EnvelopeGenerator.API/Extensions/EnvelopeAuthExtensions.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Security.Claims; using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver; using Microsoft.AspNetCore.Authentication; @@ -10,46 +11,67 @@ namespace EnvelopeGenerator.API.Extensions; /// public static class EnvelopeAuthExtensions { + private static string GetRequiredClaim(this ClaimsPrincipal user, string claimType) + { + var value = user.FindFirstValue(claimType); + if (value is not null) + { + return value; + } + + var identity = user.Identity; + var principalName = identity?.Name ?? "(anonymous)"; + var authType = identity?.AuthenticationType ?? "(none)"; + var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}")); + var message = $"Required claim '{claimType}' is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}]."; + throw new InvalidOperationException(message); + } + /// /// Retrieves a claim value by type. /// /// The current claims principal. /// The claim type to resolve. - /// The claim value or null when missing. - public static string? GetClaimValue(this ClaimsPrincipal user, string claimType) => user.FindFirstValue(claimType); + /// The claim value. + public static string GetClaimValue(this ClaimsPrincipal user, string claimType) => user.GetRequiredClaim(claimType); /// /// Gets the authenticated envelope UUID from the claims. /// - public static string? GetAuthEnvelopeUuid(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.NameIdentifier); + public static string GetAuthEnvelopeUuid(this ClaimsPrincipal user) => user.GetRequiredClaim(ClaimTypes.NameIdentifier); /// /// Gets the authenticated receiver signature from the claims. /// - public static string? GetAuthReceiverSignature(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Hash); + public static string GetAuthReceiverSignature(this ClaimsPrincipal user) => user.GetRequiredClaim(ClaimTypes.Hash); /// /// Gets the authenticated receiver display name from the claims. /// - public static string? GetAuthReceiverName(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Name); + public static string GetAuthReceiverName(this ClaimsPrincipal user) => user.GetRequiredClaim(ClaimTypes.Name); /// /// Gets the authenticated receiver email address from the claims. /// - public static string? GetAuthReceiverMail(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Email); + public static string GetAuthReceiverMail(this ClaimsPrincipal user) => user.GetRequiredClaim(ClaimTypes.Email); /// /// Gets the authenticated envelope title from the claims. /// - public static string? GetAuthEnvelopeTitle(this ClaimsPrincipal user) => user.FindFirstValue(EnvelopeClaimTypes.Title); + public static string GetAuthEnvelopeTitle(this ClaimsPrincipal user) => user.GetRequiredClaim(EnvelopeClaimTypes.Title); /// /// Gets the authenticated envelope identifier from the claims. /// - public static int? GetAuthEnvelopeId(this ClaimsPrincipal user) + public static int GetAuthEnvelopeId(this ClaimsPrincipal user) { - var envIdStr = user.FindFirstValue(EnvelopeClaimTypes.Id); - return int.TryParse(envIdStr, out var envId) ? envId : null; + var envIdStr = user.GetRequiredClaim(EnvelopeClaimTypes.Id); + if (!int.TryParse(envIdStr, out var envId)) + { + throw new InvalidOperationException($"Claim '{EnvelopeClaimTypes.Id}' is not a valid integer."); + } + + return envId; } /// @@ -84,4 +106,4 @@ public static class EnvelopeAuthExtensions new ClaimsPrincipal(claimsIdentity), authProperties); } -} +} \ No newline at end of file