feat(TotpSmsParams): Erstellt, um die Konfiguration von Totp zu handhaben
This commit is contained in:
@@ -22,6 +22,7 @@ using DigitalData.Core.Client;
|
|||||||
using EnvelopeGenerator.Application.Extensions;
|
using EnvelopeGenerator.Application.Extensions;
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
@@ -41,12 +42,9 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
private readonly ICodeGenerator _codeGenerator;
|
private readonly ICodeGenerator _codeGenerator;
|
||||||
private readonly IReceiverService _rcvService;
|
private readonly IReceiverService _rcvService;
|
||||||
private readonly IDistributedCache _dCache;
|
private readonly IDistributedCache _dCache;
|
||||||
private static readonly int SmsTotpStep = 60 * 1;
|
private readonly TotpSmsParams _totpSmsParams;
|
||||||
private static readonly string SmsFormat = "signFlow TFA-Passwort ist {0}. Dieses Passwort ist bis {1} Uhr gültig.";
|
|
||||||
private static readonly string SmsCodeExpirationCacheKeyFormat = "e{0}_r{1}_sms_code_expiration";
|
|
||||||
private static readonly (string DateTimeFormat, CultureInfo CultureInfo) SmsCodeExpiration = ("HH:mm:ss", new CultureInfo("de-DE"));
|
|
||||||
|
|
||||||
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IMessagingService messagingService, ICodeGenerator codeGenerator, IReceiverService receiverService, IDistributedCache distributedCache)
|
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IMessagingService messagingService, ICodeGenerator codeGenerator, IReceiverService receiverService, IDistributedCache distributedCache, IOptions<TotpSmsParams> totpSmsParamsOptions)
|
||||||
{
|
{
|
||||||
this.envelopeOldService = envelopeOldService;
|
this.envelopeOldService = envelopeOldService;
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
@@ -62,6 +60,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
_codeGenerator = codeGenerator;
|
_codeGenerator = codeGenerator;
|
||||||
_rcvService = receiverService;
|
_rcvService = receiverService;
|
||||||
_dCache = distributedCache;
|
_dCache = distributedCache;
|
||||||
|
_totpSmsParams = totpSmsParamsOptions.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("/")]
|
[HttpGet("/")]
|
||||||
@@ -174,14 +173,15 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
if (viaSms)
|
if (viaSms)
|
||||||
{
|
{
|
||||||
|
//TODO: create a service (like EnvelopeSmsService)
|
||||||
//add date time cache
|
//add date time cache
|
||||||
var key = string.Format(SmsCodeExpirationCacheKeyFormat, er_secret.EnvelopeId, er_secret.ReceiverId);
|
var key = string.Format(_totpSmsParams.Expiration.CacheKeyFormat, er_secret.EnvelopeId, er_secret.ReceiverId);
|
||||||
var expiration = await _dCache.GetDateTimeAsync(key);
|
var expiration = await _dCache.GetDateTimeAsync(key);
|
||||||
if (expiration is null || expiration <= DateTime.Now)
|
if (expiration is null || expiration <= DateTime.Now)
|
||||||
{
|
{
|
||||||
var new_expiration = DateTime.Now.AddSeconds(SmsTotpStep);
|
var new_expiration = DateTime.Now.AddSeconds(_totpSmsParams.TotpStep);
|
||||||
var totp = _codeGenerator.GenerateTotp(er_secret.Receiver!.TotpSecretkey!, SmsTotpStep);
|
var totp = _codeGenerator.GenerateTotp(er_secret.Receiver!.TotpSecretkey!, _totpSmsParams.TotpStep);
|
||||||
var msg = string.Format(SmsFormat, totp, new_expiration.ToString(SmsCodeExpiration.DateTimeFormat, SmsCodeExpiration.CultureInfo));
|
var msg = string.Format(_totpSmsParams.Format, totp, new_expiration.ToString(_totpSmsParams.Expiration.Format, _totpSmsParams.Expiration.CultureInfo));
|
||||||
var smsRes = await _msgService.SendSmsAsync(er_secret.PhoneNumber!, msg);
|
var smsRes = await _msgService.SendSmsAsync(er_secret.PhoneNumber!, msg);
|
||||||
if (smsRes.Failed)
|
if (smsRes.Failed)
|
||||||
{
|
{
|
||||||
@@ -237,7 +237,7 @@ 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: SmsTotpStep))
|
if (_codeGenerator.VerifyTotp(auth.SmsCode!, er_secret.Receiver.TotpSecretkey, step: _totpSmsParams.TotpStep))
|
||||||
{
|
{
|
||||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||||
ViewData["ErrorMessage"] = _localizer[WebKey.WrongAccessCode].Value;
|
ViewData["ErrorMessage"] = _localizer[WebKey.WrongAccessCode].Value;
|
||||||
|
|||||||
33
EnvelopeGenerator.Web/Models/TotpSmsParams.cs
Normal file
33
EnvelopeGenerator.Web/Models/TotpSmsParams.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Web.Models
|
||||||
|
{
|
||||||
|
public class TotpSmsParams
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The unit is second.
|
||||||
|
/// </summary>
|
||||||
|
public int TotpStep { get; init; } = 90;
|
||||||
|
|
||||||
|
public string Format { get; init; } = "Ihr 2FA-Passwort lautet {0}. Gültig bis {1}";
|
||||||
|
|
||||||
|
public ExpirationHandler Expiration { get; init; } = new();
|
||||||
|
|
||||||
|
public class ExpirationHandler
|
||||||
|
{
|
||||||
|
public string CacheKeyFormat { get; init; } = "e{0}_r{1}_sms_code_expiration";
|
||||||
|
|
||||||
|
public string Format { get; init; } = "HH:mm:ss";
|
||||||
|
|
||||||
|
public string CultureName
|
||||||
|
{
|
||||||
|
get => _cultureInfo.Name;
|
||||||
|
init => _cultureInfo = new(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CultureInfo _cultureInfo = new("de-DE");
|
||||||
|
|
||||||
|
public CultureInfo CultureInfo => _cultureInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ using DigitalData.EmailProfilerDispatcher;
|
|||||||
using EnvelopeGenerator.Infrastructure;
|
using EnvelopeGenerator.Infrastructure;
|
||||||
using EnvelopeGenerator.Web.Sanitizers;
|
using EnvelopeGenerator.Web.Sanitizers;
|
||||||
using EnvelopeGenerator.Application.Extensions;
|
using EnvelopeGenerator.Application.Extensions;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||||
logger.Info("Logging initialized!");
|
logger.Info("Logging initialized!");
|
||||||
@@ -49,6 +50,8 @@ try
|
|||||||
// Add higher order services
|
// Add higher order services
|
||||||
builder.Services.AddScoped<EnvelopeOldService>();
|
builder.Services.AddScoped<EnvelopeOldService>();
|
||||||
|
|
||||||
|
builder.Services.Configure<TotpSmsParams>(config.GetSection("TotpSmsParams"));
|
||||||
|
|
||||||
// Add controllers and razor views
|
// Add controllers and razor views
|
||||||
builder.Services.AddControllersWithViews(options =>
|
builder.Services.AddControllersWithViews(options =>
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user