Files
EnvelopeGenerator/EnvelopeGenerator.API/Controllers/DocumentController.cs
TekH a668dfa3eb Refactor envelope ID retrieval and error handling
Replaced hardcoded `envelopeId` with dynamic retrieval from
user claims. Reintroduced and updated error handling logic
to validate the `envelopeId` and log detailed errors when
parsing fails. Improved robustness by returning a 500 error
for invalid or missing envelope claims.
2026-05-31 16:15:00 +02:00

94 lines
3.5 KiB
C#

using DigitalData.Auth.Claims;
using EnvelopeGenerator.API.Controllers.Interfaces;
using EnvelopeGenerator.API.Extensions;
using EnvelopeGenerator.Application.Documents.Queries;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.API.Controllers;
/// <summary>
/// Provides access to envelope documents for authenticated receivers.
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="DocumentController"/> class.
/// </remarks>
[ApiController]
[Route("api/[controller]")]
public class DocumentController(IMediator mediator, IAuthorizationService authService, ILogger<DocumentController> logger) : ControllerBase, IAuthController
{
/// <summary>
///
/// </summary>
public IAuthorizationService AuthService => authService;
/// <summary>
/// Returns the document bytes receiver.
/// </summary>
/// <param name="query">Encoded envelope key.</param>
/// <param name="cancel">Cancellation token.</param>
[HttpGet]
[Authorize(Policy = AuthPolicy.SenderOrReceiver)]
public async Task<IActionResult> GetDocument(CancellationToken cancel, [FromQuery] ReadDocumentQuery? query = null)
{
// Sender: expects query with envelope key
if (await this.IsUserInPolicyAsync(AuthPolicy.Sender))
{
if (query is null)
return BadRequest("Missing document query.");
var senderDoc = await mediator.Send(query, cancel);
return senderDoc.ByteData is byte[] senderDocByte
? File(senderDocByte, "application/octet-stream")
: NotFound("Document is empty.");
}
// Receiver: resolve envelope id from claims
if (await this.IsUserInPolicyAsync(AuthPolicy.Receiver))
{
if (query is not null)
return BadRequest("Query parameters are not allowed for receiver role.");
var envelopeId = User.GetEnvelopeIdOfReceiver();
var receiverDoc = await mediator.Send(new ReadDocumentQuery { EnvelopeId = envelopeId }, cancel);
return receiverDoc.ByteData is byte[] receiverDocByte
? File(receiverDocByte, "application/octet-stream")
: NotFound("Document is empty.");
}
return Unauthorized();
}
/// <summary>
///
/// </summary>
/// <param name="envelopeKey"></param>
/// <param name="cancel"></param>
/// <returns></returns>
[HttpGet("{envelopeKey}")]
public async Task<IActionResult> GetDocumentOfReceiver(string envelopeKey, CancellationToken cancel)
{
var envelopeIdStr = User.FindFirst(EnvelopeClaimNames.EnvelopeId)?.Value;
if (!int.TryParse(envelopeIdStr, out int envelopeId))
{
logger.LogError(
"Inner service error: Failed to parse Envelope ID from claims. Claim '{ClaimName}' had an invalid or missing value: '{ClaimValue}'.",
EnvelopeClaimNames.EnvelopeId,
envelopeIdStr ?? "null");
return StatusCode(StatusCodes.Status500InternalServerError, "Inner service error: Invalid envelope claim.");
}
var senderDoc = await mediator.Send(new ReadDocumentQuery() { EnvelopeId = envelopeId }, cancel);
if (senderDoc.ByteData is not byte[] senderDocByte)
return NotFound("Document is empty.");
Response.Headers.ContentDisposition = $"inline; filename=\"{envelopeKey}.pdf\"";
return File(senderDocByte, "application/pdf");
}
}