From 40a4d5e2397ede19c47849d5240ffee7bec5cbdc Mon Sep 17 00:00:00 2001 From: FeTetra Date: Thu, 20 Feb 2025 21:12:34 -0500 Subject: [PATCH] Fix Koko suggestions --- .../Controllers/CommentController.cs | 3 +- .../Controllers/MessageController.cs | 3 +- .../Controllers/Resources/PhotosController.cs | 2 +- .../Resources/ResourcesController.cs | 8 ++-- .../Controllers/UserController.cs | 2 - .../Middlewares/EmailEnforcementMiddleware.cs | 4 +- .../Pages/UserSettingsPage.cshtml.cs | 4 +- .../EmailEnforcementConfiguration.cs | 9 ++-- .../Configuration/ServerConfiguration.cs | 4 +- ProjectLighthouse/Helpers/EmailHelper.cs | 43 +++++++++---------- 10 files changed, 40 insertions(+), 42 deletions(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs index d1886d7f..8f550acf 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs @@ -97,7 +97,8 @@ public class CommentController : ControllerBase .ApplyPagination(pageData) .ToListAsync()).ToSerializableList(c => GameComment.CreateFromEntity(c, token.UserId)); - if (type == CommentType.Level && slotType == "developer" && user.IsModerator && pageData.PageStart == 1) { + if (type == CommentType.Level && slotType == "developer" && user.IsModerator && pageData.PageStart == 1) + { comments.Insert(0, new GameComment { CommentId = 0, diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs index 7a82deca..b6948dfd 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs @@ -56,6 +56,7 @@ along with this program. If not, see ."; GameTokenEntity token = this.GetToken(); UserEntity? user = await this.database.UserFromGameToken(token); + if (user == null) return this.BadRequest(); StringBuilder announceText = new(ServerConfiguration.Instance.AnnounceText); @@ -67,7 +68,7 @@ along with this program. If not, see ."; announceText.Append(BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n"); } - if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement) + if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement) { announceText.Append("\n\n" + BaseLayoutStrings.EmailEnforcementWarnMain.Translate(LocalizationManager.DefaultLang) + "\n\n"); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs index 4b13f252..80798067 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs @@ -216,7 +216,7 @@ public class PhotosController : ControllerBase [HttpGet("photos/with")] public async Task UserPhotosWith(string user) - { + { int targetUserId = await this.database.UserIdFromUsername(user); if (targetUserId == 0) return this.NotFound(); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs index 630be2c9..f48c7e7d 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs @@ -35,18 +35,18 @@ public class ResourcesController : ControllerBase } [HttpGet("r/{hash}")] - public async Task GetResource(string hash) + public Task GetResource(string hash) { string path = FileHelper.GetResourcePath(hash); string fullPath = Path.GetFullPath(path); // Prevent directory traversal attacks - if (!fullPath.StartsWith(FileHelper.FullResourcePath)) return this.BadRequest(); + if (!fullPath.StartsWith(FileHelper.FullResourcePath)) return Task.FromResult(this.BadRequest()); - if (FileHelper.ResourceExists(hash)) return this.File(IOFile.OpenRead(path), "application/octet-stream"); + if (FileHelper.ResourceExists(hash)) return Task.FromResult(this.File(IOFile.OpenRead(path), "application/octet-stream")); - return this.NotFound(); + return Task.FromResult(this.NotFound()); } [HttpPost("upload/{hash}/unattributed")] diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs index 2b32dc32..ed0dbe12 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs @@ -29,8 +29,6 @@ public class UserController : ControllerBase { private readonly DatabaseContext database; - private static readonly bool emailEnforcementEnabled = EmailEnforcementConfiguration.Instance.EnableEmailEnforcement; - public UserController(DatabaseContext database) { this.database = database; diff --git a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs index b269c97a..7482439c 100644 --- a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs +++ b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs @@ -8,14 +8,14 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares; public class EmailEnforcementMiddleware : MiddlewareDBContext { - private static readonly HashSet enforcedPaths = EmailEnforcementConfiguration.Instance.BlockedEndpoints; + private static readonly HashSet enforcedPaths = ServerConfiguration.Instance.EmailEnforcement.BlockedEndpoints; public EmailEnforcementMiddleware(RequestDelegate next) : base(next) { } public override async Task InvokeAsync(HttpContext context, DatabaseContext database) { - if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement) + if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement) { // Split path into segments string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries); diff --git a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs index d1a9c0a8..8904e294 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs @@ -64,8 +64,8 @@ public class UserSettingsPage : BaseLayout } } - if (ServerConfiguration.Instance.Mail.MailEnabled && - SMTPHelper.IsValidEmail(this.Database, email) && + if (ServerConfiguration.Instance.Mail.MailEnabled && + email != null && SMTPHelper.IsValidEmail(this.Database, email) && (this.User == this.ProfileUser || this.User.IsAdmin)) { if (this.ProfileUser.EmailAddress != email) diff --git a/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs index c6697df1..56179d91 100644 --- a/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs +++ b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs @@ -1,6 +1,5 @@ #nullable enable using System.Collections.Generic; -using System.IO; using YamlDotNet.Serialization; namespace LBPUnion.ProjectLighthouse.Configuration; @@ -13,15 +12,15 @@ public class EmailEnforcementConfiguration : ConfigurationBase false; + public bool EnableEmailBlacklist => false; // No blacklist by default, add path to blacklist - public string BlacklistFilePath { get; set; } = ""; + public string BlacklistFilePath => ""; // Endpoints to be blocked // This is kind of a random list so some may need to be added or removed - public HashSet BlockedEndpoints { get; set; } = new() + public HashSet BlockedEndpoints => new() { // Comments "rateUserComment", diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index ba9f7f4a..584c1a0e 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase // 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. // Thanks for listening~ - public override int ConfigVersion { get; set; } = 27; + public override int ConfigVersion { get; set; } = 28; public override string ConfigName { get; set; } = "lighthouse.yml"; public string WebsiteListenUrl { get; set; } = "http://localhost:10060"; @@ -46,5 +46,7 @@ public class ServerConfiguration : ConfigurationBase public RichPresenceConfiguration RichPresenceConfiguration { get; set; } = new(); public NotificationConfiguration NotificationConfiguration { get; set; } = new(); + public EmailEnforcementConfiguration EmailEnforcement { get; set; } = new(); + public override ConfigurationBase Deserialize(IDeserializer deserializer, string text) => deserializer.Deserialize(text); } \ No newline at end of file diff --git a/ProjectLighthouse/Helpers/EmailHelper.cs b/ProjectLighthouse/Helpers/EmailHelper.cs index 606b682b..65124f96 100644 --- a/ProjectLighthouse/Helpers/EmailHelper.cs +++ b/ProjectLighthouse/Helpers/EmailHelper.cs @@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Threading.Tasks; -using LBPUnion.ProjectLighthouse.Configuration; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Logging; @@ -20,15 +20,16 @@ namespace LBPUnion.ProjectLighthouse.Helpers; public static class SMTPHelper { + private static readonly string blacklistFilePath = ServerConfiguration.Instance.EmailEnforcement.BlacklistFilePath; + + // Null check blacklistFilePath and read into array + private static readonly string[] blacklistFile = + !string.IsNullOrWhiteSpace(blacklistFilePath) ? File.ReadAllLines(blacklistFilePath) : []; + // (User id, timestamp of last request + 30 seconds) private static readonly ConcurrentDictionary recentlySentMail = new(); private const long emailCooldown = 1000 * 30; - - // To prevent ReadAllLines() exception when BlacklistFilePath is empty - private static readonly string[] blacklistFile = - !string.IsNullOrWhiteSpace(EmailEnforcementConfiguration.Instance.BlacklistFilePath) - ? File.ReadAllLines(EmailEnforcementConfiguration.Instance.BlacklistFilePath) : []; private static readonly HashSet blacklistedDomains = new(blacklistFile); @@ -84,28 +85,24 @@ public static class SMTPHelper public static bool IsValidEmail(DatabaseContext database, string email) { // Email should not be empty, should be an actual email, and shouldn't already be used by an account - if (!string.IsNullOrWhiteSpace(email) && emailValidator.IsValid(email) && !EmailIsUsed(database, email).Result) + if (string.IsNullOrWhiteSpace(email) || !emailValidator.IsValid(email) || EmailIsUsed(database, email).Result) + return false; + + // Don't even bother if there are no domains in blacklist (AKA file path is empty/invalid, or file itself is empty) + if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailBlacklist && blacklistedDomains.Count > 0) { - // Don't even bother if there are no domains in blacklist (AKA file path is empty/invalid, or file itself is empty) - if (EmailEnforcementConfiguration.Instance.EnableEmailBlacklist && blacklistedDomains.Count > 0) + // Get domain by splitting at '@' character + string domain = email.Split('@')[1]; + + // Return false if domain is found in blacklist + if (blacklistedDomains.Contains(domain)) { - // Get domain by splitting at '@' character - string domain = email.Split('@')[1]; - - // Return false if domain is found in blacklist - if (blacklistedDomains.Contains(domain)) - { - Logger.Info($"Invalid email address {email} submitted by user.", LogArea.Email); - return false; - } - - return true; + Logger.Info($"Invalid email address {email} submitted by user.", LogArea.Email); + return false; } - - return true; } - return false; + return true; } // Don't want to allocate every single time we call EmailAddressAttribute.IsValidEmail()