Files
DocumentService/DocumentService.API/Controllers/PdfSignatureController.cs
TekH 5e7652ef88 Refactor and rename to DocumentService
Renamed namespaces and projects from DocumentOperator to DocumentService, updating all references accordingly. Refactored PdfSignatureAppearanceDto and related enums to use properties with init accessors for improved clarity. Removed and re-added IPkcs11SelfTestStatusProvider with updated namespace. Simplified dependency injection by removing DocumentOperatorApplication registration. Updated appsettings.json with a specific AssetsRootPath. Incremented version numbers in project files for a new release. Introduced PdfSignatureClient and IPdfSignatureClient for PDF digital-signing operations. Updated project files to use newer Microsoft.Extensions package versions. Removed all DocumentOperator references, completing the transition to DocumentService. Added new DTOs and enums for PDF signature options and appearance.
2026-10-25 18:49:08 +01:00

73 lines
2.7 KiB
C#

using DocumentService.Application.Common.DTOs;
using DocumentService.Application.SignPdf;
using DocumentService.Domain.Common.Exceptions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
namespace DocumentService.API.Controllers;
/// <summary>
/// Controller for PDF digital signing (PKCS#11 / company certificate).
/// </summary>
[ApiController]
[Route("api/pdf/signature")]
public class PdfSignatureController(IMediator mediator) : ControllerBase
{
/// <summary>
/// Digitally signs a PDF using the configured PKCS#11 signing infrastructure.
/// </summary>
/// <param name="request">Base64-encoded PDF, optional signature image, and signing options</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Signed PDF</returns>
/// <response code="200">PDF signed successfully - returns signed PDF</response>
/// <response code="400">Invalid input (Base64 format error, invalid appearance)</response>
/// <response code="500">Internal server error during signing</response>
[HttpPost("sign")]
[Consumes("application/json")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Sign([FromBody] SignPdfRequest request, CancellationToken cancellationToken)
{
byte[] signedPdf;
try
{
signedPdf = await mediator.Send(new SignPdfCommand
{
InputPdf = new MemoryStream(Convert.FromBase64String(request.Base64Pdf)),
Options = request.Options,
SignatureImage = string.IsNullOrWhiteSpace(request.Base64SignatureImage)
? null
: new MemoryStream(Convert.FromBase64String(request.Base64SignatureImage))
}, cancellationToken);
}
catch (FormatException ex)
{
throw new BadRequestException("Invalid Base64 format: " + ex.Message);
}
return File(signedPdf, "application/pdf", "signed.pdf");
}
}
/// <summary>
/// Request DTO for PDF signing via JSON payload.
/// </summary>
public sealed class SignPdfRequest
{
/// <summary>
/// Base64-encoded PDF to sign.
/// </summary>
public required string Base64Pdf { get; init; }
/// <summary>
/// Optional Base64-encoded signature image (PNG/JPEG).
/// </summary>
public string? Base64SignatureImage { get; init; }
/// <summary>
/// Signing options (metadata + appearance).
/// </summary>
public required PdfSignOptionsDto Options { get; init; }
}