From 5b220932d330a93ab9097a09abe4de779657f080 Mon Sep 17 00:00:00 2001 From: TekH Date: Tue, 9 Jun 2026 10:54:38 +0200 Subject: [PATCH] Refactor claim handling and simplify controllers Refactored multiple controllers (`AnnotationController`, `DocumentController`, `ReadOnlyController`, and `SignatureController`) to use updated claim extension methods (`ReceiverSignature`, `EnvelopeUuid`, etc.), replacing older, verbose methods for improved readability and consistency. Removed the `EnvelopeClaimTypes` class and replaced claim type constants with `EnvelopeClaimNames`. Simplified claim retrieval logic in `ReceiverClaimExtensions` by consolidating methods and removing redundant or unused functionality. Eliminated the `SignInEnvelopeAsync` method, indicating a shift away from manual claim management. Performed general cleanup, including removing obsolete code and improving exception messages for better debugging context. --- .../Controllers/AnnotationController.cs | 13 +-- .../Controllers/DocumentController.cs | 4 +- .../Controllers/ReadOnlyController.cs | 4 +- .../Controllers/SignatureController.cs | 4 +- EnvelopeGenerator.API/EnvelopeClaimTypes.cs | 17 --- .../Extensions/ReceiverClaimExtensions.cs | 104 +++++------------- 6 files changed, 41 insertions(+), 105 deletions(-) delete mode 100644 EnvelopeGenerator.API/EnvelopeClaimTypes.cs diff --git a/EnvelopeGenerator.API/Controllers/AnnotationController.cs b/EnvelopeGenerator.API/Controllers/AnnotationController.cs index c9052d51..b99df64b 100644 --- a/EnvelopeGenerator.API/Controllers/AnnotationController.cs +++ b/EnvelopeGenerator.API/Controllers/AnnotationController.cs @@ -1,11 +1,9 @@ using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Exceptions; using EnvelopeGenerator.API.Extensions; -using EnvelopeGenerator.Application.Common.Dto; using EnvelopeGenerator.Application.Common.Extensions; using EnvelopeGenerator.Application.Common.Interfaces.Services; using EnvelopeGenerator.Application.Common.Notifications.DocSigned; -using EnvelopeGenerator.Application.Documents.Queries; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries; using EnvelopeGenerator.Application.Histories.Queries; using EnvelopeGenerator.Domain.Constants; @@ -13,7 +11,6 @@ using MediatR; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.API.Controllers; @@ -62,8 +59,8 @@ public class AnnotationController : ControllerBase [Obsolete("PSPDF Kit will no longer be used.")] public async Task CreateOrUpdate([FromBody] PsPdfKitAnnotation? psPdfKitAnnotation = null, CancellationToken cancel = default) { - var signature = User.GetReceiverSignatureOfReceiver(); - var uuid = User.GetEnvelopeUuidOfReceiver(); + var signature = User.ReceiverSignature(); + var uuid = User.EnvelopeUuid(); var envelopeReceiver = await _mediator.ReadEnvelopeReceiverAsync(uuid, signature, cancel).ThrowIfNull(Exceptions.NotFound); @@ -95,9 +92,9 @@ public class AnnotationController : ControllerBase [Obsolete("Use MediatR")] public async Task Reject([FromBody] string? reason = null) { - var signature = User.GetReceiverSignatureOfReceiver(); - var uuid = User.GetEnvelopeUuidOfReceiver(); - var mail = User.GetReceiverMailOfReceiver(); + var signature = User.ReceiverSignature(); + var uuid = User.EnvelopeUuid(); + var mail = User.ReceiverMail(); var envRcvRes = await _envelopeReceiverService.ReadByUuidSignatureAsync(uuid: uuid, signature: signature); diff --git a/EnvelopeGenerator.API/Controllers/DocumentController.cs b/EnvelopeGenerator.API/Controllers/DocumentController.cs index 74049871..f8468f81 100644 --- a/EnvelopeGenerator.API/Controllers/DocumentController.cs +++ b/EnvelopeGenerator.API/Controllers/DocumentController.cs @@ -51,7 +51,7 @@ public class DocumentController(IMediator mediator, IAuthorizationService authSe if (query is not null) return BadRequest("Query parameters are not allowed for receiver role."); - var envelopeId = User.GetEnvelopeIdOfReceiver(); + var envelopeId = User.EnvelopeId(); var receiverDoc = await mediator.Send(new ReadDocumentQuery { EnvelopeId = envelopeId }, cancel); return receiverDoc.ByteData is byte[] receiverDocByte ? File(receiverDocByte, "application/octet-stream") @@ -71,7 +71,7 @@ public class DocumentController(IMediator mediator, IAuthorizationService authSe [HttpGet("{envelopeKey}")] public async Task GetDocumentOfReceiver(string envelopeKey, CancellationToken cancel) { - int envelopeId = User.GetEnvelopeIdOfReceiver(); + int envelopeId = User.EnvelopeId(); var senderDoc = await mediator.Send(new ReadDocumentQuery() { EnvelopeId = envelopeId }, cancel); diff --git a/EnvelopeGenerator.API/Controllers/ReadOnlyController.cs b/EnvelopeGenerator.API/Controllers/ReadOnlyController.cs index 3b2c139b..db800c22 100644 --- a/EnvelopeGenerator.API/Controllers/ReadOnlyController.cs +++ b/EnvelopeGenerator.API/Controllers/ReadOnlyController.cs @@ -41,14 +41,14 @@ public class ReadOnlyController : ControllerBase [Obsolete("Use MediatR")] public async Task CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto) { - var authReceiverMail = User.GetReceiverMailOfReceiver(); + var authReceiverMail = User.ReceiverMail(); if (authReceiverMail is null) { _logger.LogError("EmailAddress claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto)); return Unauthorized(); } - var envelopeId = User.GetEnvelopeIdOfReceiver(); + var envelopeId = User.EnvelopeId(); createDto.AddedWho = authReceiverMail; createDto.EnvelopeId = envelopeId; diff --git a/EnvelopeGenerator.API/Controllers/SignatureController.cs b/EnvelopeGenerator.API/Controllers/SignatureController.cs index 3368a62e..ca66b937 100644 --- a/EnvelopeGenerator.API/Controllers/SignatureController.cs +++ b/EnvelopeGenerator.API/Controllers/SignatureController.cs @@ -38,9 +38,9 @@ public class SignatureController : ControllerBase [HttpGet("{envelopeKey}")] public async Task GetAnnotsOfReceiver(string envelopeKey, CancellationToken cancel) { - int envelopeId = User.GetEnvelopeIdOfReceiver(); + int envelopeId = User.EnvelopeId(); - int receiverId = User.GetReceiverIdOfReceiver(); + int receiverId = User.ReceiverId(); var doc = await _mediator.Send(new ReadDocumentQuery() { EnvelopeId = envelopeId }, cancel); diff --git a/EnvelopeGenerator.API/EnvelopeClaimTypes.cs b/EnvelopeGenerator.API/EnvelopeClaimTypes.cs deleted file mode 100644 index c167013e..00000000 --- a/EnvelopeGenerator.API/EnvelopeClaimTypes.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace EnvelopeGenerator.API; - -/// -/// Provides custom claim types for envelope-related information. -/// -public static class EnvelopeClaimTypes -{ - /// - /// Claim type for the title of an envelope. - /// - public static readonly string Title = $"Envelope{nameof(Title)}"; - - /// - /// Claim type for the ID of an envelope. - /// - public static readonly string Id = $"Envelope{nameof(Id)}"; -} \ No newline at end of file diff --git a/EnvelopeGenerator.API/Extensions/ReceiverClaimExtensions.cs b/EnvelopeGenerator.API/Extensions/ReceiverClaimExtensions.cs index b3760d59..d851c1de 100644 --- a/EnvelopeGenerator.API/Extensions/ReceiverClaimExtensions.cs +++ b/EnvelopeGenerator.API/Extensions/ReceiverClaimExtensions.cs @@ -1,8 +1,6 @@ -using System.Linq; +using DigitalData.Auth.Claims; +using Microsoft.IdentityModel.JsonWebTokens; using System.Security.Claims; -using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; namespace EnvelopeGenerator.API.Extensions; @@ -11,12 +9,14 @@ namespace EnvelopeGenerator.API.Extensions; /// public static class ReceiverClaimExtensions { - private static readonly string[] EnvelopeIdClaimTypes = [EnvelopeClaimTypes.Id, "envelope_id", "EnvelopeId"]; - private static readonly string[] ReceiverIdClaimTypes = ["receiver_id", "ReceiverId"]; - private static readonly string[] EnvelopeUuidClaimTypes = [ClaimTypes.NameIdentifier, "envelope_uuid", "EnvelopeUuid"]; - private static readonly string[] ReceiverSignatureClaimTypes = [ClaimTypes.Hash, "receiver_sig", "ReceiverSignature"]; - - private static string GetRequiredClaimOfReceiver(this ClaimsPrincipal user, string claimType) + /// + /// + /// + /// + /// + /// + /// + private static string GetRequiredClaimValue(this ClaimsPrincipal user, string claimType) { var value = user.FindFirstValue(claimType); if (value is not null) @@ -32,7 +32,7 @@ public static class ReceiverClaimExtensions throw new InvalidOperationException(message); } - private static string GetRequiredClaimOfReceiver(this ClaimsPrincipal user, params string[] claimTypes) + private static string GetRequiredClaimValue(this ClaimsPrincipal user, params string[] claimTypes) { foreach (var claimType in claimTypes.Where(t => !string.IsNullOrWhiteSpace(t)).Distinct()) { @@ -52,89 +52,45 @@ public static class ReceiverClaimExtensions /// /// Gets the authenticated envelope UUID from the claims. /// - public static string GetEnvelopeUuidOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(EnvelopeUuidClaimTypes); + public static string EnvelopeUuid(this ClaimsPrincipal user) + => user.GetRequiredClaimValue(EnvelopeClaimNames.EnvelopeUuid); /// /// Gets the authenticated receiver signature from the claims. /// - public static string GetReceiverSignatureOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ReceiverSignatureClaimTypes); - - /// - /// Gets the authenticated receiver display name from the claims. - /// - public static string GetReceiverNameOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.Name); + public static string ReceiverSignature(this ClaimsPrincipal user) + => user.GetRequiredClaimValue(EnvelopeClaimNames.ReceiverSignature); /// /// Gets the authenticated receiver email address from the claims. /// - public static string GetReceiverMailOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.Email); - - /// - /// Gets the authenticated envelope title from the claims. - /// - public static string GetEnvelopeTitleOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(EnvelopeClaimTypes.Title); + public static string ReceiverMail(this ClaimsPrincipal user) + => user.GetRequiredClaimValue(JwtRegisteredClaimNames.Email); /// /// Gets the authenticated envelope identifier from the claims. /// - public static int GetEnvelopeIdOfReceiver(this ClaimsPrincipal user) + public static int EnvelopeId(this ClaimsPrincipal user) { - var envIdStr = user.GetRequiredClaimOfReceiver(EnvelopeIdClaimTypes); - if (!int.TryParse(envIdStr, out var envId)) - { - throw new InvalidOperationException($"Claim '{"envelope_id"}' is not a valid integer."); - } - - return envId; + var envIdStr = user.GetRequiredClaimValue(EnvelopeClaimNames.EnvelopeId); + if (int.TryParse(envIdStr, out var envId)) + return envId; + else + throw new InvalidOperationException($"Claim '{EnvelopeClaimNames.EnvelopeId}' is not a valid integer."); } /// - /// + /// Gets the authenticated receiver identifier from the claims. /// /// /// /// - public static int GetReceiverIdOfReceiver(this ClaimsPrincipal user) + public static int ReceiverId(this ClaimsPrincipal user) { - var rcvIdStr = user.GetRequiredClaimOfReceiver(ReceiverIdClaimTypes); - if (!int.TryParse(rcvIdStr, out var rcvId)) - { - throw new InvalidOperationException($"Claim '{"receiver_id"}' is not a valid integer."); - } - - return rcvId; - } - - /// - /// Signs in an envelope receiver using cookie authentication and attaches envelope claims. - /// - /// The current HTTP context. - /// Envelope receiver DTO to extract claims from. - /// Role to attach to the authentication ticket. - public static async Task SignInEnvelopeAsync(this HttpContext context, EnvelopeReceiverDto envelopeReceiver, string receiverRole) - { - var claims = new List - { - new(ClaimTypes.NameIdentifier, envelopeReceiver.Envelope!.Uuid), - new(ClaimTypes.Hash, envelopeReceiver.Receiver!.Signature), - new(ClaimTypes.Name, envelopeReceiver.Name ?? string.Empty), - new(ClaimTypes.Email, envelopeReceiver.Receiver.EmailAddress), - new(EnvelopeClaimTypes.Title, envelopeReceiver.Envelope.Title), - new(EnvelopeClaimTypes.Id, envelopeReceiver.Envelope.Id.ToString()), - new(ClaimTypes.Role, receiverRole) - }; - - var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); - - var authProperties = new AuthenticationProperties - { - AllowRefresh = false, - IsPersistent = false - }; - - await context.SignInAsync( - CookieAuthenticationDefaults.AuthenticationScheme, - new ClaimsPrincipal(claimsIdentity), - authProperties); + var rcvIdStr = user.GetRequiredClaimValue(EnvelopeClaimNames.ReceiverId); + if (int.TryParse(rcvIdStr, out var rcvId)) + return rcvId; + else + throw new InvalidOperationException($"Claim '{EnvelopeClaimNames.ReceiverId}' is not a valid integer."); } } \ No newline at end of file