feat(EnvelopeSmsHandler): Methode VerifyTotp hinzugefügt, um Totp mit TotpVerificationWindow von TotpSmsParams zu verifizieren.

This commit is contained in:
Developer 02 2025-02-03 09:52:46 +01:00
parent 772d510705
commit bbd03615e1
4 changed files with 25 additions and 14 deletions

View File

@ -1,4 +1,5 @@
using System.Globalization; using OtpNet;
using System.Globalization;
namespace EnvelopeGenerator.Application.Configurations namespace EnvelopeGenerator.Application.Configurations
{ {
@ -13,6 +14,21 @@ namespace EnvelopeGenerator.Application.Configurations
public ExpirationHandler Expiration { get; init; } = new(); public ExpirationHandler Expiration { get; init; } = new();
public VerificationWindow? TotpVerificationWindow { get; private init; } = VerificationWindow.RfcSpecifiedNetworkDelay;
private IEnumerable<int>? _tvwParams;
public IEnumerable<int>? TotpVerificationWindowParams
{
get => _tvwParams;
init
{
_tvwParams = value;
if(_tvwParams is not null)
TotpVerificationWindow = new(previous: _tvwParams.ElementAtOrDefault(0), future: _tvwParams.ElementAtOrDefault(0));
}
}
public class ExpirationHandler public class ExpirationHandler
{ {
public string CacheKeyFormat { get; init; } = "e{0}_r{1}_sms_code_expiration"; public string CacheKeyFormat { get; init; } = "e{0}_r{1}_sms_code_expiration";

View File

@ -12,4 +12,6 @@ public interface IEnvelopeSmsHandler
/// <param name="cToken"></param> /// <param name="cToken"></param>
/// <returns></returns> /// <returns></returns>
Task<(SmsResponse? SmsResponse, DateTime Expiration)> SendTotpAsync(EnvelopeReceiverSecretDto er_secret, CancellationToken cToken = default); Task<(SmsResponse? SmsResponse, DateTime Expiration)> SendTotpAsync(EnvelopeReceiverSecretDto er_secret, CancellationToken cToken = default);
bool VerifyTotp(string totpCode, string secretKey);
} }

View File

@ -47,4 +47,7 @@ public class EnvelopeSmsHandler : IEnvelopeSmsHandler
return (await _sender.SendSmsAsync(er_secret.PhoneNumber!, msg), new_expiration); return (await _sender.SendSmsAsync(er_secret.PhoneNumber!, msg), new_expiration);
} }
} }
public bool VerifyTotp(string totpCode, string secretKey) => _codeGenerator
.VerifyTotp(totpCode, secretKey, _totpSmsParams.TotpStep, _totpSmsParams.TotpVerificationWindow);
} }

View File

@ -20,10 +20,6 @@ using Newtonsoft.Json;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs;
using DigitalData.Core.Client; using DigitalData.Core.Client;
using EnvelopeGenerator.Application.Extensions; using EnvelopeGenerator.Application.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.DTOs.Messaging;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {
@ -39,14 +35,11 @@ namespace EnvelopeGenerator.Web.Controllers
private readonly Cultures _cultures; private readonly Cultures _cultures;
private readonly IEnvelopeMailService _mailService; private readonly IEnvelopeMailService _mailService;
private readonly IEnvelopeReceiverReadOnlyService _readOnlyService; private readonly IEnvelopeReceiverReadOnlyService _readOnlyService;
private readonly ISmsSender _msgService;
private readonly ICodeGenerator _codeGenerator; private readonly ICodeGenerator _codeGenerator;
private readonly IReceiverService _rcvService; private readonly IReceiverService _rcvService;
private readonly IDistributedCache _dCache;
private readonly TotpSmsParams _totpSmsParams;
private readonly IEnvelopeSmsHandler _envSmsHandler; private readonly IEnvelopeSmsHandler _envSmsHandler;
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, ISmsSender messagingService, ICodeGenerator codeGenerator, IReceiverService receiverService, IDistributedCache distributedCache, IOptions<TotpSmsParams> totpSmsParamsOptions, IEnvelopeSmsHandler envelopeSmsService) public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, ICodeGenerator codeGenerator, IReceiverService receiverService, IEnvelopeSmsHandler envelopeSmsService)
{ {
this.envelopeOldService = envelopeOldService; this.envelopeOldService = envelopeOldService;
_envRcvService = envelopeReceiverService; _envRcvService = envelopeReceiverService;
@ -58,11 +51,8 @@ namespace EnvelopeGenerator.Web.Controllers
_mailService = envelopeMailService; _mailService = envelopeMailService;
_logger = logger; _logger = logger;
_readOnlyService = readOnlyService; _readOnlyService = readOnlyService;
_msgService = messagingService;
_codeGenerator = codeGenerator; _codeGenerator = codeGenerator;
_rcvService = receiverService; _rcvService = receiverService;
_dCache = distributedCache;
_totpSmsParams = totpSmsParamsOptions.Value;
_envSmsHandler = envelopeSmsService; _envSmsHandler = envelopeSmsService;
} }
@ -230,8 +220,8 @@ namespace EnvelopeGenerator.Web.Controllers
{ {
if (er_secret.Receiver!.TotpSecretkey is null) if (er_secret.Receiver!.TotpSecretkey is null)
throw new InvalidOperationException($"TotpSecretkey of DTO cannot validate without TotpSecretkey. Dto: {JsonConvert.SerializeObject(er_secret)}"); throw new InvalidOperationException($"TotpSecretkey of DTO cannot validate without TotpSecretkey. Dto: {JsonConvert.SerializeObject(er_secret)}");
if (_codeGenerator.VerifyTotp(auth.SmsCode!, er_secret.Receiver.TotpSecretkey, step: _totpSmsParams.TotpStep)) if (_envSmsHandler.VerifyTotp(auth.SmsCode!, er_secret.Receiver.TotpSecretkey))
{ {
Response.StatusCode = StatusCodes.Status401Unauthorized; Response.StatusCode = StatusCodes.Status401Unauthorized;
ViewData["ErrorMessage"] = _localizer[WebKey.WrongAccessCode].Value; ViewData["ErrorMessage"] = _localizer[WebKey.WrongAccessCode].Value;