Rewrite captcha system (#754)

Rewrite captcha and remove many unused directives
This commit is contained in:
Josh 2023-04-28 23:32:42 -05:00 committed by GitHub
commit 3aa9033b67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 101 additions and 111 deletions

View file

@ -0,0 +1,61 @@
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Logging;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json.Linq;
namespace LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
public class CaptchaService : ICaptchaService
{
private readonly HttpClient client;
public CaptchaService(HttpClient client)
{
this.client = client;
}
public async Task<bool> VerifyCaptcha(HttpRequest request)
{
if (!ServerConfiguration.Instance.Captcha.CaptchaEnabled) return true;
string keyName = ServerConfiguration.Instance.Captcha.Type switch
{
CaptchaType.HCaptcha => "h-captcha-response",
CaptchaType.ReCaptcha => "g-recaptcha-response",
_ => throw new ArgumentOutOfRangeException(nameof(request),
@$"Unknown captcha type: {ServerConfiguration.Instance.Captcha.Type}"),
};
bool gotCaptcha = request.Form.TryGetValue(keyName, out StringValues values);
if (!gotCaptcha) return false;
string? captchaToken = values[0];
if (captchaToken == null) return false;
List<KeyValuePair<string, string>> payload = new()
{
new KeyValuePair<string, string>("secret", ServerConfiguration.Instance.Captcha.Secret),
new KeyValuePair<string, string>("response", captchaToken),
};
try
{
using HttpResponseMessage response =
await this.client.PostAsync("siteverify", new FormUrlEncodedContent(payload));
if (!response.IsSuccessStatusCode) return false;
string responseBody = await response.Content.ReadAsStringAsync();
// We only really care about the success result, so we just parse that
return bool.Parse(JObject.Parse(responseBody)["success"]?.ToString() ?? "false");
}
catch (Exception ex)
{
Logger.Error(ex.ToDetailedException(), LogArea.HTTP);
}
return false;
}
}

View file

@ -0,0 +1,6 @@
namespace LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
public interface ICaptchaService
{
Task<bool> VerifyCaptcha(HttpRequest request);
}

View file

@ -3,10 +3,10 @@ using System.Web;
using JetBrains.Annotations;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Localization.StringLists;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -18,8 +18,12 @@ namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Login;
public class LoginForm : BaseLayout
{
public LoginForm(DatabaseContext database) : base(database)
{}
private readonly ICaptchaService captchaService;
public LoginForm(DatabaseContext database, ICaptchaService captchaService) : base(database)
{
this.captchaService = captchaService;
}
public string? Error { get; private set; }
@ -38,7 +42,7 @@ public class LoginForm : BaseLayout
return this.Page();
}
if (!await this.Request.CheckCaptchaValidity())
if (!await this.captchaService.VerifyCaptcha(this.Request))
{
this.Error = this.Translate(ErrorStrings.CaptchaFailed);
return this.Page();

View file

@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Localization.StringLists;
using LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -15,8 +15,12 @@ namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Login;
public class RegisterForm : BaseLayout
{
public RegisterForm(DatabaseContext database) : base(database)
{ }
private readonly ICaptchaService captchaService;
public RegisterForm(DatabaseContext database, ICaptchaService captchaService) : base(database)
{
this.captchaService = captchaService;
}
public string? Error { get; private set; }
@ -68,7 +72,7 @@ public class RegisterForm : BaseLayout
return this.Page();
}
if (!await this.Request.CheckCaptchaValidity())
if (!await this.captchaService.VerifyCaptcha(this.Request))
{
this.Error = this.Translate(ErrorStrings.CaptchaFailed);
return this.Page();

View file

@ -1,8 +1,11 @@
using System.Globalization;
using System.Net;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Localization;
using LBPUnion.ProjectLighthouse.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
using LBPUnion.ProjectLighthouse.Servers.Website.Middlewares;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Localization;
@ -44,6 +47,20 @@ public class WebsiteStartup
services.AddDbContext<DatabaseContext>();
services.AddHttpClient<ICaptchaService, CaptchaService>("CaptchaAPI",
client =>
{
Uri captchaUri = ServerConfiguration.Instance.Captcha.Type switch
{
CaptchaType.HCaptcha => new Uri("https://hcaptcha.com"),
CaptchaType.ReCaptcha => new Uri("https://www.google.com/recaptcha/api/"),
_ => throw new ArgumentOutOfRangeException(nameof(client)),
};
client.BaseAddress = captchaUri;
client.Timeout = TimeSpan.FromSeconds(5);
client.DefaultRequestHeaders.Add("User-Agent", "Project Lighthouse");
});
services.Configure<ForwardedHeadersOptions>
(
options =>