From dc2e58442df3b84ee418d5a5e94769b43fbdb77a Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:05:53 +0300 Subject: [PATCH] CMS Kit: Cache generated reCaptcha result --- .../CmsKitPublicCommentsController.cs | 4 +- .../Commenting/CommentingViewComponent.cs | 14 ++++-- .../Components/Commenting/Default.cshtml | 3 +- .../Security/Captcha/CaptchaOptions.cs | 5 +- .../Captcha/SimpleMathsCaptchaGenerator.cs | 47 +++++++++++-------- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicCommentsController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicCommentsController.cs index a2e2dea013..79163c5b03 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicCommentsController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicCommentsController.cs @@ -37,7 +37,7 @@ public class CmsKitPublicCommentsController : CmsKitPublicControllerBase { CheckCaptchaTokenNullity(input.CaptchaToken); - SimpleMathsCaptchaGenerator.Validate(input.CaptchaToken.Value, input.CaptchaAnswer); + await SimpleMathsCaptchaGenerator.ValidateAsync(input.CaptchaToken.Value, input.CaptchaAnswer); } var dto = ObjectMapper.Map (input); @@ -51,7 +51,7 @@ public class CmsKitPublicCommentsController : CmsKitPublicControllerBase { CheckCaptchaTokenNullity(input.CaptchaToken); - SimpleMathsCaptchaGenerator.Validate(input.CaptchaToken.Value, input.CaptchaAnswer); + await SimpleMathsCaptchaGenerator.ValidateAsync(input.CaptchaToken.Value, input.CaptchaAnswer); } await CommentPublicAppService.UpdateAsync(id, input); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs index 4452dc5eec..5810103ea9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs @@ -76,26 +76,30 @@ public class CommentingViewComponent : AbpViewComponent LoginUrl = loginUrl, Comments = comments.OrderByDescending(i => i.CreationTime).ToList() }; + await ConvertMarkdownTextsToHtml(viewModel); if (CmsKitCommentOptions.IsRecaptchaEnabled) { - CaptchaOutput = GetCaptcha(); + CaptchaOutput = await GenerateCaptchaAsync(); viewModel.CaptchaImageBase64 = GetCaptchaImageBase64(CaptchaOutput.ImageBytes); } + this.Input = viewModel; return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", this); } - public CaptchaOutput GetCaptcha() + public async Task GenerateCaptchaAsync() { - return SimpleMathsCaptchaGenerator.Generate(new CaptchaOptions( + return await SimpleMathsCaptchaGenerator.GenerateAsync( + new CaptchaOptions( number1MinValue: 1, number1MaxValue: 10, number2MinValue: 5, - number2MaxValue: 15) - ); + number2MaxValue: 15 + ) + ); } public string GetCaptchaImageBase64(byte[] bytes) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index 5d11f624f3..d4e09e9b61 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -133,7 +133,8 @@ @if (CmsKitCommentOptions.Value.IsRecaptchaEnabled) { - var output = Model.GetCaptcha(); + var output = await Model.GenerateCaptchaAsync(); +
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/CaptchaOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/CaptchaOptions.cs index 75f08f724f..5fec9e7cdb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/CaptchaOptions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/CaptchaOptions.cs @@ -1,4 +1,5 @@ -using SixLabors.Fonts; +using System; +using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; @@ -47,6 +48,8 @@ public class CaptchaOptions public int Number2MaxValue { get; set; } = 99; + public TimeSpan DurationOfValidity { get; set; } = TimeSpan.FromMinutes(10); + public CaptchaOptions() { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/SimpleMathsCaptchaGenerator.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/SimpleMathsCaptchaGenerator.cs index 220e24f892..bd7f9f0371 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/SimpleMathsCaptchaGenerator.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Security/Captcha/SimpleMathsCaptchaGenerator.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Numerics; @@ -15,27 +14,30 @@ using Microsoft.Extensions.Localization; using Volo.Abp.DependencyInjection; using Color = SixLabors.ImageSharp.Color; using PointF = SixLabors.ImageSharp.PointF; +using Volo.Abp.Caching; +using Microsoft.Extensions.Caching.Distributed; namespace Volo.CmsKit.Public.Web.Security.Captcha; -public class SimpleMathsCaptchaGenerator : ISingletonDependency +public class SimpleMathsCaptchaGenerator : ITransientDependency { - private readonly IStringLocalizer _localizer; + protected IStringLocalizer Localizer { get; } + protected IDistributedCache Cache { get; } - public SimpleMathsCaptchaGenerator(IStringLocalizer localizer) + public SimpleMathsCaptchaGenerator(IStringLocalizer localizer, IDistributedCache cache) { - _localizer = localizer; + Localizer = localizer; + Cache = cache; } - private static Dictionary Session { get; set; } = new Dictionary(); - public CaptchaOutput Generate() + public virtual Task GenerateAsync() { - return Generate(options: null, number1: null, number2: null); + return GenerateAsync(options: null, number1: null, number2: null); } - public CaptchaOutput Generate(CaptchaOptions options) + public virtual Task GenerateAsync(CaptchaOptions options) { - return Generate(options, number1: null, number2: null); + return GenerateAsync(options, number1: null, number2: null); } /// @@ -45,7 +47,7 @@ public class SimpleMathsCaptchaGenerator : ISingletonDependency /// First number for maths operation /// Second number for maths operation /// - public CaptchaOutput Generate(CaptchaOptions options, int? number1, int? number2) + public virtual async Task GenerateAsync(CaptchaOptions options, int? number1, int? number2) { var random = new Random(); options ??= new CaptchaOptions(); @@ -65,11 +67,15 @@ public class SimpleMathsCaptchaGenerator : ISingletonDependency { Text = text, Result = Calculate(number1.Value, number2.Value), - ImageBytes = GenerateInternal(text, options) + ImageBytes = GenerateInternal(text, options) } }; - Session[request.Output.Id] = request; + await Cache.SetAsync(request.Output.Id.ToString("N"), request.Output, new DistributedCacheEntryOptions + { + AbsoluteExpiration = DateTimeOffset.Now.Add(options.DurationOfValidity) + }); + return request.Output; } @@ -78,24 +84,25 @@ public class SimpleMathsCaptchaGenerator : ISingletonDependency return number1 + number2; } - public void Validate(Guid requestId, int value) + public virtual async Task ValidateAsync(Guid requestId, int value) { - var request = Session[requestId]; - if (request.Output.Result != value) + var request = await Cache.GetAsync(requestId.ToString("N")); + + if(request == null || request.Result != value) { - throw new UserFriendlyException(_localizer["CaptchaCodeErrorMessage"]); + throw new UserFriendlyException(Localizer["CaptchaCodeErrorMessage"]); } } - public void Validate(Guid requestId, string value) + public virtual async Task ValidateAsync(Guid requestId, string value) { if (int.TryParse(value, out var captchaInput)) { - Validate(requestId, captchaInput); + await ValidateAsync(requestId, captchaInput); } else { - throw new UserFriendlyException(_localizer["CaptchaCodeMissingMessage"]); + throw new UserFriendlyException(Localizer["CaptchaCodeMissingMessage"]); } }