Refactor document retrieval endpoints and authorization

- Updated DocumentController to use class-level [Authorize] and method-level role-based authorization for sender and receiver endpoints.
- Replaced ReadEnvelopeReceiverQuery with ReadDocumentQuery for sender document retrieval; simplified response logic.
- Added a new endpoint for fully authenticated receivers to fetch documents by envelope ID from user claims.
- Refactored ReadDocumentQuery and handler to always return DocumentDto, throw NotFoundException when needed, and use _repo.Query.
- Cleaned up using directives and removed legacy error handling and logging.
This commit is contained in:
2026-02-03 09:48:33 +01:00
parent 1b840f4ae3
commit 5465996563
2 changed files with 33 additions and 25 deletions

View File

@@ -1,6 +1,5 @@
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using EnvelopeGenerator.API.Extensions;
using EnvelopeGenerator.Application.Documents.Queries;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
using Microsoft.AspNetCore.Authorization;
@@ -14,7 +13,7 @@ namespace EnvelopeGenerator.API.Controllers;
/// <remarks>
/// Initializes a new instance of the <see cref="DocumentController"/> class.
/// </remarks>
[Authorize(Roles = Role.FullyAuth)]
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class DocumentController(IMediator mediator, ILogger<DocumentController> logger) : ControllerBase
@@ -25,19 +24,28 @@ public class DocumentController(IMediator mediator, ILogger<DocumentController>
/// <param name="query">Encoded envelope key.</param>
/// <param name="cancel">Cancellation token.</param>
[HttpGet]
public async Task<IActionResult> GetDocument(ReadEnvelopeReceiverQuery query, CancellationToken cancel)
[Authorize(Roles = Role.Sender)]
public async Task<IActionResult> GetDocument(ReadDocumentQuery query, CancellationToken cancel)
{
var envRcv = await mediator.Send(query, cancel).FirstAsync(Exceptions.NotFound);
var byteData = envRcv.Envelope?.Documents?.FirstOrDefault()?.ByteData;
if (byteData is null || byteData.Length == 0)
{
logger.LogError("Document byte data is null or empty for envelope-receiver entity:\n{envelopeKey}.",
envRcv.ToJson(Format.Json.ForDiagnostics));
throw new NotFoundException("Document is empty.");
}
return File(byteData, "application/octet-stream");
var doc = await mediator.Send(query, cancel);
return doc.ByteData is byte[] docByte
? File(docByte, "application/octet-stream")
: NotFound("Document is empty.");
}
}
/// <summary>
/// Returns the document bytes for the receiver.
/// </summary>
/// <param name="cancel">Cancellation token.</param>
[HttpGet]
[Authorize(Roles = Role.Receiver.FullyAuth)]
public async Task<IActionResult> GetDocument(CancellationToken cancel)
{
var envelopeId = User.GetEnvelopeIdOfReceiver();
var doc = await mediator.Send(new ReadDocumentQuery() { EnvelopeId = envelopeId }, cancel);
return doc.ByteData is byte[] docByte
? File(docByte, "application/octet-stream")
: NotFound("Document is empty.");
}
}