From 787f9f7362a7d22da9f43776197e0cd2f83e7e25 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 21 Nov 2021 21:39:34 -0500 Subject: [PATCH] Game now relies on external auth to connect properly --- .../ExternalAuth/AuthenticationController.cs | 3 +++ .../Controllers/LoginController.cs | 16 ++++++++++++- .../Controllers/MessageController.cs | 10 ++++++-- ProjectLighthouse/Database.cs | 24 +++++++++++++------ .../Helpers/DeniedAuthenticationHelper.cs | 24 +++++++++++++++++++ .../Types/Settings/ServerSettings.cs | 4 +++- 6 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs diff --git a/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs b/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs index b1c5dd53..3ebaa778 100644 --- a/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs +++ b/ProjectLighthouse/Controllers/ExternalAuth/AuthenticationController.cs @@ -1,5 +1,6 @@ #nullable enable using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Types; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -54,6 +55,8 @@ namespace LBPUnion.ProjectLighthouse.Controllers.ExternalAuth this.database.GameTokens.Remove(authAttempt.GameToken); this.database.AuthenticationAttempts.Remove(authAttempt); + DeniedAuthenticationHelper.Set($"{authAttempt.IPAddress}|{user.Username}"); + await this.database.SaveChangesAsync(); return this.Redirect("~/authentication"); diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index 2a1a9999..ee71188b 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -49,9 +49,23 @@ namespace LBPUnion.ProjectLighthouse.Controllers GameToken? token = await this.database.AuthenticateUser(loginData, userLocation, titleId); if (token == null) return this.StatusCode(403, ""); - User? user = await this.database.UserFromGameToken(token); + 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, ""); + + AuthenticationAttempt authAttempt = new() + { + GameToken = token, + GameTokenId = token.TokenId, + Timestamp = TimestampHelper.Timestamp, + IPAddress = userLocation, + Platform = token.GameVersion == GameVersion.LittleBigPlanetVita ? Platform.Vita : Platform.PS3, // TODO: properly identify RPCS3 + }; + + this.database.AuthenticationAttempts.Add(authAttempt); + await this.database.SaveChangesAsync(); + Logger.Log($"Successfully logged in user {user.Username} as {token.GameVersion} client ({titleId})", LoggerLevelLogin.Instance); // Create a new room on LBP2+/Vita diff --git a/ProjectLighthouse/Controllers/MessageController.cs b/ProjectLighthouse/Controllers/MessageController.cs index 1e31bc29..1da30dae 100644 --- a/ProjectLighthouse/Controllers/MessageController.cs +++ b/ProjectLighthouse/Controllers/MessageController.cs @@ -27,10 +27,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers [HttpGet("announce")] public async Task Announce() { - User user = await this.database.UserFromGameRequest(this.Request); + User user = await this.database.UserFromGameRequest(this.Request, true); if (user == null) return this.StatusCode(403, ""); - return this.Ok($"You are now logged in as user {user.Username} (id {user.UserId}).\n\n" + ServerSettings.Instance.EulaText); + return this.Ok + ( + $"Please stay on this screen.\n" + + $"Before continuing, you must approve this session at {ServerSettings.Instance.ExternalUrl}.\n" + + $"Once approved, you may press X and continue.\n\n" + + ServerSettings.Instance.EulaText + ); } [HttpGet("notification")] diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index 68b9c6dd..bc2fa0ca 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -89,36 +89,46 @@ namespace LBPUnion.ProjectLighthouse #region Game Token Shenanigans - public async Task UserFromMMAuth(string authToken) + public async Task UserFromMMAuth(string authToken, bool allowUnapproved = false) { GameToken? token = await this.GameTokens.FirstOrDefaultAsync(t => t.UserToken == authToken); + if (token == null) return null; + if (!allowUnapproved && !token.Approved) return null; return await this.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.UserId == token.UserId); } - public async Task UserFromGameToken(GameToken gameToken) => await this.UserFromMMAuth(gameToken.UserToken); + public async Task UserFromGameToken + (GameToken gameToken, bool allowUnapproved = false) + => await this.UserFromMMAuth(gameToken.UserToken, allowUnapproved); - public async Task UserFromGameRequest(HttpRequest request) + public async Task UserFromGameRequest(HttpRequest request, bool allowUnapproved = false) { if (!request.Cookies.TryGetValue("MM_AUTH", out string? mmAuth) || mmAuth == null) return null; - return await this.UserFromMMAuth(mmAuth); + return await this.UserFromMMAuth(mmAuth, allowUnapproved); } - public async Task GameTokenFromRequest(HttpRequest request) + public async Task GameTokenFromRequest(HttpRequest request, bool allowUnapproved = false) { if (!request.Cookies.TryGetValue("MM_AUTH", out string? mmAuth) || mmAuth == null) return null; - return await this.GameTokens.FirstOrDefaultAsync(t => t.UserToken == mmAuth); + GameToken? token = await this.GameTokens.FirstOrDefaultAsync(t => t.UserToken == mmAuth); + + if (token == null) return null; + if (!allowUnapproved && !token.Approved) return null; + + return token; } - public async Task<(User, GameToken)?> UserAndGameTokenFromRequest(HttpRequest request) + public async Task<(User, GameToken)?> UserAndGameTokenFromRequest(HttpRequest request, bool allowUnapproved = false) { if (!request.Cookies.TryGetValue("MM_AUTH", out string? mmAuth) || mmAuth == null) return null; GameToken? token = await this.GameTokens.FirstOrDefaultAsync(t => t.UserToken == mmAuth); if (token == null) return null; + if (!allowUnapproved && !token.Approved) return null; User? user = await this.UserFromGameToken(token); diff --git a/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs b/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs new file mode 100644 index 00000000..9fcaa215 --- /dev/null +++ b/ProjectLighthouse/Helpers/DeniedAuthenticationHelper.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace LBPUnion.ProjectLighthouse.Helpers +{ + public static class DeniedAuthenticationHelper + { + public static readonly Dictionary IPAddressAndNameDeniedAt = new(); + + public static void Set(string ipAddressAndName, long timestamp = 0) + { + if (timestamp == 0) timestamp = TimestampHelper.Timestamp; + + if (IPAddressAndNameDeniedAt.TryGetValue(ipAddressAndName, out long _)) IPAddressAndNameDeniedAt.Remove(ipAddressAndName); + IPAddressAndNameDeniedAt.Add(ipAddressAndName, timestamp); + } + + public static bool RecentlyDenied(string ipAddressAndName) + { + if (!IPAddressAndNameDeniedAt.TryGetValue(ipAddressAndName, out long timestamp)) return false; + + return TimestampHelper.Timestamp < timestamp + 60; + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Settings/ServerSettings.cs b/ProjectLighthouse/Types/Settings/ServerSettings.cs index 405e90db..9f2dd928 100644 --- a/ProjectLighthouse/Types/Settings/ServerSettings.cs +++ b/ProjectLighthouse/Types/Settings/ServerSettings.cs @@ -68,7 +68,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings [NotNull] public static ServerSettings Instance; - public const int CurrentConfigVersion = 4; + public const int CurrentConfigVersion = 5; [JsonPropertyName("ConfigVersionDoNotModifyOrYouWillBeSlapped")] public int ConfigVersion { get; set; } = CurrentConfigVersion; @@ -87,5 +87,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings public string EulaText { get; set; } = ""; public string DbConnectionString { get; set; } = "server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse"; + + public string ExternalUrl { get; set; } = "http://localhost:10060"; } } \ No newline at end of file