diff --git a/Application/Alerts/AlertExtensions.cs b/Application/Alerts/AlertExtensions.cs index b90db826..b164fa57 100644 --- a/Application/Alerts/AlertExtensions.cs +++ b/Application/Alerts/AlertExtensions.cs @@ -5,8 +5,17 @@ using SharedLibraryCore.Database.Models; namespace IW4MAdmin.Application.Alerts; +/// +/// extension method helper class to allow building of alerts +/// public static class AlertExtensions { + /// + /// builds basic alert for user with provided category + /// + /// client to build the alert for + /// alert category + /// public static Alert.AlertState BuildAlert(this EFClient client, Alert.AlertCategory? type = null) { return new Alert.AlertState @@ -16,36 +25,72 @@ public static class AlertExtensions }; } + /// + /// sets the category for an existing alert + /// + /// existing alert + /// new category + /// public static Alert.AlertState WithCategory(this Alert.AlertState state, Alert.AlertCategory category) { state.Category = category; return state; } + /// + /// sets the alert type for an existing alert + /// + /// existing alert + /// new type + /// public static Alert.AlertState OfType(this Alert.AlertState state, string type) { state.Type = type; return state; } + /// + /// sets the message for an existing alert + /// + /// existing alert + /// new message + /// public static Alert.AlertState WithMessage(this Alert.AlertState state, string message) { state.Message = message; return state; } + /// + /// sets the expiration duration for an existing alert + /// + /// existing alert + /// duration before expiration + /// public static Alert.AlertState ExpiresIn(this Alert.AlertState state, TimeSpan expiration) { state.ExpiresAt = DateTime.Now.Add(expiration); return state; } + /// + /// sets the source for an existing alert + /// + /// existing alert + /// new source + /// public static Alert.AlertState FromSource(this Alert.AlertState state, string source) { state.Source = source; return state; } + /// + /// sets the alert source to the provided client + /// + /// existing alert + /// new client + /// public static Alert.AlertState FromClient(this Alert.AlertState state, EFClient client) { state.Source = client.Name.StripColors(); diff --git a/WebfrontCore/Program.cs b/WebfrontCore/Program.cs index e4127878..978ee516 100644 --- a/WebfrontCore/Program.cs +++ b/WebfrontCore/Program.cs @@ -4,7 +4,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; -using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; namespace WebfrontCore diff --git a/WebfrontCore/Startup.cs b/WebfrontCore/Startup.cs index 5d6bed65..5ad20e8b 100644 --- a/WebfrontCore/Startup.cs +++ b/WebfrontCore/Startup.cs @@ -20,9 +20,11 @@ using System.IO; using System.Linq; using System.Net; using System.Reflection; +using System.Threading.RateLimiting; using System.Threading.Tasks; using Data.Abstractions; using Data.Helpers; +using Microsoft.AspNetCore.RateLimiting; using WebfrontCore.Controllers.API.Validation; using WebfrontCore.Middleware; using WebfrontCore.QueryHelpers; @@ -134,7 +136,14 @@ namespace WebfrontCore app.UseMiddleware(serviceProvider.GetService>(), serviceProvider.GetRequiredService().WebfrontConnectionWhitelist); } - app.UseConcurrencyLimiter(); + app.UseRateLimiter(new RateLimiterOptions() + .AddConcurrencyLimiter("concurrencyPolicy", (options) => + { + options.PermitLimit = 2; + options.QueueLimit = 25; + options.QueueProcessingOrder = QueueProcessingOrder.NewestFirst; + })); + app.UseStaticFiles(); app.UseAuthentication(); app.UseCors("AllowAll"); @@ -146,7 +155,8 @@ namespace WebfrontCore app.UseAuthorization(); app.UseEndpoints(endpoints => { - endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); + endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}") + .RequireRateLimiting("concurrencyPolicy"); }); } }