Replaced all EnvelopeGenerator.GeneratorAPI namespaces with EnvelopeGenerator.API across controllers, models, extensions, middleware, and annotation-related files. Updated using/import statements and namespace declarations accordingly. Added wwwroot folder to project file. Minor code adjustments made for consistency. This unifies API naming for improved clarity and maintainability.
130 lines
5.0 KiB
C#
130 lines
5.0 KiB
C#
using DigitalData.Core.Abstraction.Application.DTO;
|
|
using EnvelopeGenerator.Application.Common.Extensions;
|
|
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
|
using EnvelopeGenerator.Application.Resources;
|
|
using EnvelopeGenerator.Domain.Constants;
|
|
using EnvelopeGenerator.API.Models;
|
|
using Ganss.Xss;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Localization;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace EnvelopeGenerator.API.Controllers;
|
|
|
|
/// <summary>
|
|
/// Exposes endpoints for registering and managing two-factor authentication for envelope receivers.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/tfa")]
|
|
public class TfaRegistrationController : ControllerBase
|
|
{
|
|
private readonly ILogger<TfaRegistrationController> _logger;
|
|
private readonly IEnvelopeReceiverService _envelopeReceiverService;
|
|
private readonly IAuthenticator _authenticator;
|
|
private readonly IReceiverService _receiverService;
|
|
private readonly TFARegParams _parameters;
|
|
private readonly IStringLocalizer<Resource> _localizer;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="TfaRegistrationController"/> class.
|
|
/// </summary>
|
|
public TfaRegistrationController(
|
|
ILogger<TfaRegistrationController> logger,
|
|
IEnvelopeReceiverService envelopeReceiverService,
|
|
IAuthenticator authenticator,
|
|
IReceiverService receiverService,
|
|
IOptions<TFARegParams> tfaRegParamsOptions,
|
|
IStringLocalizer<Resource> localizer)
|
|
{
|
|
_logger = logger;
|
|
_envelopeReceiverService = envelopeReceiverService;
|
|
_authenticator = authenticator;
|
|
_receiverService = receiverService;
|
|
_parameters = tfaRegParamsOptions.Value;
|
|
_localizer = localizer;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates registration metadata (QR code and deadline) for a receiver.
|
|
/// </summary>
|
|
/// <param name="envelopeReceiverId">Encoded envelope receiver id.</param>
|
|
[Authorize]
|
|
[HttpGet("{envelopeReceiverId}")]
|
|
public async Task<IActionResult> RegisterAsync(string envelopeReceiverId)
|
|
{
|
|
try
|
|
{
|
|
var (uuid, signature) = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
|
|
|
if (uuid is null || signature is null)
|
|
{
|
|
_logger.LogEnvelopeError(uuid: uuid, signature: signature, message: _localizer.WrongEnvelopeReceiverId());
|
|
return Unauthorized(new { message = _localizer.WrongEnvelopeReceiverId() });
|
|
}
|
|
|
|
var secretResult = await _envelopeReceiverService.ReadWithSecretByUuidSignatureAsync(uuid: uuid, signature: signature);
|
|
if (secretResult.IsFailed)
|
|
{
|
|
_logger.LogNotice(secretResult.Notices);
|
|
return NotFound(new { message = _localizer.WrongEnvelopeReceiverId() });
|
|
}
|
|
|
|
var envelopeReceiver = secretResult.Data;
|
|
|
|
if (!envelopeReceiver.Envelope!.TFAEnabled)
|
|
return Unauthorized(new { message = _localizer.WrongAccessCode() });
|
|
|
|
var receiver = envelopeReceiver.Receiver;
|
|
receiver!.TotpSecretkey = _authenticator.GenerateTotpSecretKey();
|
|
await _receiverService.UpdateAsync(receiver);
|
|
var totpQr64 = _authenticator.GenerateTotpQrCode(userEmail: receiver.EmailAddress, secretKey: receiver.TotpSecretkey).ToBase64String();
|
|
|
|
if (receiver.TfaRegDeadline is null)
|
|
{
|
|
receiver.TfaRegDeadline = _parameters.Deadline;
|
|
await _receiverService.UpdateAsync(receiver);
|
|
}
|
|
else if (receiver.TfaRegDeadline <= DateTime.Now)
|
|
{
|
|
return StatusCode(StatusCodes.Status410Gone, new { message = _localizer.WrongAccessCode() });
|
|
}
|
|
|
|
return Ok(new
|
|
{
|
|
envelopeReceiver.EnvelopeId,
|
|
envelopeReceiver.Envelope!.Uuid,
|
|
envelopeReceiver.Receiver!.Signature,
|
|
receiver.TfaRegDeadline,
|
|
TotpQR64 = totpQr64
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex, message: _localizer.WrongEnvelopeReceiverId());
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = _localizer.UnexpectedError() });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs out the envelope receiver from cookie authentication.
|
|
/// </summary>
|
|
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
|
[HttpPost("auth/logout")]
|
|
public async Task<IActionResult> LogOutAsync()
|
|
{
|
|
try
|
|
{
|
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "{message}", ex.Message);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = _localizer.UnexpectedError() });
|
|
}
|
|
}
|
|
}
|