mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-29 00:18:39 +00:00
Implement checking for the Patchwork user agent (#1090)
* Implement checking for the Patchwork user agent, move logout into standalone method * Quick fixes (awesome name) * 403 user at login instead of logging out at /announce * Move configuration and revert logout changes * Rework parsing to check against GameVersion enum and game token GameVersion * Fix logic error oopsie * Fix Zaprit suggestions * Simplify patchwork game version test * Test patchwork user agent with regex instead * Fix Qodana warnings * Fix remaining Qodana warnings
This commit is contained in:
parent
df7ebf977a
commit
aeba706391
7 changed files with 85 additions and 4 deletions
|
@ -3,6 +3,7 @@ using LBPUnion.ProjectLighthouse.Configuration;
|
||||||
using LBPUnion.ProjectLighthouse.Database;
|
using LBPUnion.ProjectLighthouse.Database;
|
||||||
using LBPUnion.ProjectLighthouse.Extensions;
|
using LBPUnion.ProjectLighthouse.Extensions;
|
||||||
using LBPUnion.ProjectLighthouse.Helpers;
|
using LBPUnion.ProjectLighthouse.Helpers;
|
||||||
|
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
|
||||||
using LBPUnion.ProjectLighthouse.Logging;
|
using LBPUnion.ProjectLighthouse.Logging;
|
||||||
using LBPUnion.ProjectLighthouse.Tickets;
|
using LBPUnion.ProjectLighthouse.Tickets;
|
||||||
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
||||||
|
@ -212,6 +213,14 @@ public class LoginController : ControllerBase
|
||||||
return this.Forbid();
|
return this.Forbid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ServerConfiguration.Instance.Authentication.RequirePatchworkUserAgent)
|
||||||
|
{
|
||||||
|
if (!PatchworkHelper.IsValidPatchworkUserAgent(this.Request.Headers.UserAgent.ToString()))
|
||||||
|
{
|
||||||
|
return this.Forbid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Success($"Successfully logged in user {user.Username} as {token.GameVersion} client", LogArea.Login);
|
Logger.Success($"Successfully logged in user {user.Username} as {token.GameVersion} client", LogArea.Login);
|
||||||
|
|
||||||
user.LastLogin = TimeHelper.TimestampMillis;
|
user.LastLogin = TimeHelper.TimestampMillis;
|
||||||
|
|
|
@ -38,5 +38,4 @@ public class LogoutController : ControllerBase
|
||||||
return this.Ok();
|
return this.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using LBPUnion.ProjectLighthouse.Configuration;
|
using LBPUnion.ProjectLighthouse.Configuration;
|
||||||
using LBPUnion.ProjectLighthouse.Database;
|
using LBPUnion.ProjectLighthouse.Database;
|
||||||
using LBPUnion.ProjectLighthouse.Extensions;
|
using LBPUnion.ProjectLighthouse.Extensions;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
using LBPUnion.ProjectLighthouse.Configuration;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
|
||||||
|
|
||||||
|
public static partial class PatchworkHelper
|
||||||
|
{
|
||||||
|
private static readonly int requiredMajor = ServerConfiguration.Instance.Authentication.PatchworkMajorVersionMinimum;
|
||||||
|
private static readonly int requiredMinor = ServerConfiguration.Instance.Authentication.PatchworkMinorVersionMinimum;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^PatchworkLBP[123V] (\d{1,5})\.(\d{1,5})$")]
|
||||||
|
private static partial Regex PatchworkUserAgentRegex();
|
||||||
|
|
||||||
|
public static bool IsValidPatchworkUserAgent(string userAgent)
|
||||||
|
{
|
||||||
|
Match result = PatchworkUserAgentRegex().Match(userAgent);
|
||||||
|
if (!result.Success) return false;
|
||||||
|
|
||||||
|
if (!int.TryParse(result.Groups[1].Value, out int major) || !int.TryParse(result.Groups[2].Value, out int minor))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return major >= requiredMajor && minor >= requiredMinor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace ProjectLighthouse.Tests.GameApiTests.Unit;
|
||||||
|
|
||||||
|
[Trait("Category", "Unit")]
|
||||||
|
public class PatchworkUserAgentTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void CanValidatePatchworkUserAgents()
|
||||||
|
{
|
||||||
|
string[] validUserAgents = {
|
||||||
|
"PatchworkLBP1 1.0",
|
||||||
|
"PatchworkLBP2 2.0",
|
||||||
|
"PatchworkLBP3 3.0",
|
||||||
|
"PatchworkLBPV 4.0",
|
||||||
|
"PatchworkLBP1 1.5",
|
||||||
|
};
|
||||||
|
|
||||||
|
string[] invalidUserAgents = {
|
||||||
|
// Matching
|
||||||
|
"patchworklbp1 1.0", // Case sensitive
|
||||||
|
"ptchwrklbp1 1.0", // Misspelled
|
||||||
|
"PatchworkLBP1 1", // Missing major/minor
|
||||||
|
"PatchworkLBP1 1.000001", // Major/minor too long
|
||||||
|
|
||||||
|
// Data
|
||||||
|
"PatchworkLBP1 0.5", // Version number too low
|
||||||
|
"PatchworkLBP1 A.0" // Int cannot be parsed
|
||||||
|
};
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
foreach (string userAgent in validUserAgents)
|
||||||
|
{
|
||||||
|
result = PatchworkHelper.IsValidPatchworkUserAgent(userAgent);
|
||||||
|
Assert.True(result, $"Valid user agent: \"{userAgent}\" was evaluated as {result}.");
|
||||||
|
}
|
||||||
|
foreach (string userAgent in invalidUserAgents)
|
||||||
|
{
|
||||||
|
result = PatchworkHelper.IsValidPatchworkUserAgent(userAgent);
|
||||||
|
Assert.False(result, $"Invalid user agent: \"{userAgent}\" was evaluated as {result}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,5 +9,11 @@ public class AuthenticationConfiguration
|
||||||
public bool AllowRPCNSignup { get; set; } = true;
|
public bool AllowRPCNSignup { get; set; } = true;
|
||||||
|
|
||||||
public bool AllowPSNSignup { get; set; } = true;
|
public bool AllowPSNSignup { get; set; } = true;
|
||||||
|
|
||||||
|
// Require use of Zaprit's "Patchwork" prx plugin's user agent when connecting to the server
|
||||||
|
// Major and minor version minimums can be left alone if patchwork is not required
|
||||||
|
public bool RequirePatchworkUserAgent { get; set; } = false;
|
||||||
|
public int PatchworkMajorVersionMinimum { get; set; } = 1;
|
||||||
|
public int PatchworkMinorVersionMinimum { get; set; } = 0;
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
|
||||||
// This is so Lighthouse can properly identify outdated configurations and update them with newer settings accordingly.
|
// This is so Lighthouse can properly identify outdated configurations and update them with newer settings accordingly.
|
||||||
// If you are modifying anything here, this value MUST be incremented.
|
// If you are modifying anything here, this value MUST be incremented.
|
||||||
// Thanks for listening~
|
// Thanks for listening~
|
||||||
public override int ConfigVersion { get; set; } = 27;
|
public override int ConfigVersion { get; set; } = 30;
|
||||||
|
|
||||||
public override string ConfigName { get; set; } = "lighthouse.yml";
|
public override string ConfigName { get; set; } = "lighthouse.yml";
|
||||||
public string WebsiteListenUrl { get; set; } = "http://localhost:10060";
|
public string WebsiteListenUrl { get; set; } = "http://localhost:10060";
|
||||||
|
@ -31,7 +31,6 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
|
||||||
public bool CheckForUnsafeFiles { get; set; } = true;
|
public bool CheckForUnsafeFiles { get; set; } = true;
|
||||||
public bool LogChatFiltering { get; set; } = false;
|
public bool LogChatFiltering { get; set; } = false;
|
||||||
public bool LogChatMessages { get; set; } = false;
|
public bool LogChatMessages { get; set; } = false;
|
||||||
|
|
||||||
public AuthenticationConfiguration Authentication { get; set; } = new();
|
public AuthenticationConfiguration Authentication { get; set; } = new();
|
||||||
public CaptchaConfiguration Captcha { get; set; } = new();
|
public CaptchaConfiguration Captcha { get; set; } = new();
|
||||||
public DigestKeyConfiguration DigestKey { get; set; } = new();
|
public DigestKeyConfiguration DigestKey { get; set; } = new();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue