From 4017afe8c863e6ef8205932ab5a1c43fa6d3586d Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 21 Nov 2021 21:53:39 -0500 Subject: [PATCH] Track denied attempts, add deny all button --- .../ExternalAuth/AuthenticationController.cs | 28 ++++++++++++++++++- .../Controllers/LoginController.cs | 14 +++++++++- .../Helpers/DeniedAuthenticationHelper.cs | 16 ++++++++++- .../ExternalAuth/AuthenticationPage.cshtml | 3 ++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs b/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs index 3ebaa778..323ea19f 100644 --- a/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs +++ b/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs @@ -1,4 +1,6 @@ #nullable enable +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Types; @@ -55,7 +57,31 @@ namespace LBPUnion.ProjectLighthouse.Controllers.ExternalAuth this.database.GameTokens.Remove(authAttempt.GameToken); this.database.AuthenticationAttempts.Remove(authAttempt); - DeniedAuthenticationHelper.Set($"{authAttempt.IPAddress}|{user.Username}"); + DeniedAuthenticationHelper.SetDeniedAt($"{authAttempt.IPAddress}|{user.Username}"); + + await this.database.SaveChangesAsync(); + + return this.Redirect("~/authentication"); + } + + [HttpGet("denyAll")] + public async Task DenyAll() + { + User? user = this.database.UserFromWebRequest(this.Request); + if (user == null) return this.Redirect("/login"); + + List authAttempts = await this.database.AuthenticationAttempts.Include + (a => a.GameToken) + .Where(a => a.GameToken.UserId == user.UserId) + .ToListAsync(); + + foreach (AuthenticationAttempt authAttempt in authAttempts) + { + this.database.GameTokens.Remove(authAttempt.GameToken); + this.database.AuthenticationAttempts.Remove(authAttempt); + + DeniedAuthenticationHelper.SetDeniedAt($"{authAttempt.IPAddress}|{user.Username}"); + } await this.database.SaveChangesAsync(); diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index ee71188b..250aad9d 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -1,5 +1,6 @@ #nullable enable using System.IO; +using System.Linq; using System.Net; using System.Threading.Tasks; using Kettu; @@ -8,6 +9,7 @@ using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; namespace LBPUnion.ProjectLighthouse.Controllers { @@ -52,7 +54,17 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameToken(token, true); if (user == null) return this.StatusCode(403, ""); - if (DeniedAuthenticationHelper.RecentlyDenied($"{token.UserLocation}|{user.Username}")) return this.StatusCode(403, ""); + string ipAddressAndName = $"{token.UserLocation}|{user.Username}"; + if (DeniedAuthenticationHelper.RecentlyDenied(ipAddressAndName) || DeniedAuthenticationHelper.GetAttempts(ipAddressAndName) > 5) + { + this.database.AuthenticationAttempts.RemoveRange + (this.database.AuthenticationAttempts.Include(a => a.GameToken).Where(a => a.GameToken.UserId == user.UserId)); + + DeniedAuthenticationHelper.AddAttempt(ipAddressAndName); + + await this.database.SaveChangesAsync(); + return this.StatusCode(403, ""); + } AuthenticationAttempt authAttempt = new() { diff --git a/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs b/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs index 9fcaa215..decfce1f 100644 --- a/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs +++ b/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs @@ -5,8 +5,9 @@ namespace LBPUnion.ProjectLighthouse.Helpers public static class DeniedAuthenticationHelper { public static readonly Dictionary IPAddressAndNameDeniedAt = new(); + public static readonly Dictionary AttemptsByIPAddressAndName = new(); - public static void Set(string ipAddressAndName, long timestamp = 0) + public static void SetDeniedAt(string ipAddressAndName, long timestamp = 0) { if (timestamp == 0) timestamp = TimestampHelper.Timestamp; @@ -20,5 +21,18 @@ namespace LBPUnion.ProjectLighthouse.Helpers return TimestampHelper.Timestamp < timestamp + 60; } + + public static void AddAttempt(string ipAddressAndName) + { + if (AttemptsByIPAddressAndName.TryGetValue(ipAddressAndName, out int attempts)) AttemptsByIPAddressAndName.Remove(ipAddressAndName); + AttemptsByIPAddressAndName.Add(ipAddressAndName, attempts + 1); + } + + public static int GetAttempts(string ipAddressAndName) + { + if (!AttemptsByIPAddressAndName.TryGetValue(ipAddressAndName, out int attempts)) return 0; + + return attempts; + } } } \ No newline at end of file diff --git a/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml b/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml index 9c80b815..58521e46 100644 --- a/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml +++ b/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml @@ -14,6 +14,9 @@ else {

You have @Model.AuthenticationAttempts.Count authentication attempts pending.

+ + + } @foreach (AuthenticationAttempt authAttempt in Model.AuthenticationAttempts)