diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs index 99bc7929..6cf01e9d 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs @@ -67,19 +67,17 @@ along with this program. If not, see ."; announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n"); } - if (EnforceEmailConfiguration.Instance.EnableEmailEnforcement) + if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement) { - announceText.Insert(0, EnforceEmailConfiguration.Instance.EmailEnforcementMessageMain); + announceText.Insert(0, EmailEnforcementConfiguration.Instance.EmailEnforcementMessageMain); if (user.EmailAddress == null) { - // This will probably need translations - announceText.Insert(0, EnforceEmailConfiguration.Instance.EmailEnforcementMessageNoEmail); + announceText.Insert(0, EmailEnforcementConfiguration.Instance.EmailEnforcementMessageNoEmail); } else if (!user.EmailAddressVerified) { - // More stuff to translate later - announceText.Insert(0, EnforceEmailConfiguration.Instance.EmailEnforcementMessageVerify); + announceText.Insert(0, EmailEnforcementConfiguration.Instance.EmailEnforcementMessageVerify); } } diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs index ee537228..6c832f63 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs @@ -29,7 +29,7 @@ public class UserController : ControllerBase { private readonly DatabaseContext database; - private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement; + private static readonly bool emailEnforcementEnabled = EmailEnforcementConfiguration.Instance.EnableEmailEnforcement; public UserController(DatabaseContext database) { diff --git a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs index d0792352..0fbce0be 100644 --- a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs +++ b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs @@ -3,46 +3,12 @@ using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Middlewares; using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Token; -using LBPUnion.ProjectLighthouse.Types.Logging; namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares; public class EmailEnforcementMiddleware : MiddlewareDBContext { - private static readonly HashSet enforcedPaths = new() - { - "showModerated", - "rateUserComment", - "rateComment", - "comments", - "userComments", - "postUserComment", - "postComment", - "deleteUserComment", - "deleteComment", - "slots", - "upload", - "r", - "s", - "uploadPhoto", - "photos", - "deletePhoto", - "match", - "play", - "enterLevel", - "user", - "users", - "updateUser", - "update_my_pins", - "startPublish", - "publish", - "unpublish", - "playlists", - "tags", - "tag", - "searches", - "genres", - }; + private static readonly HashSet enforcedPaths = EmailEnforcementConfiguration.Instance.BlockedEndpoints; public EmailEnforcementMiddleware(RequestDelegate next) : base(next) { } @@ -51,37 +17,41 @@ public class EmailEnforcementMiddleware : MiddlewareDBContext { // Split path into segments string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries); - bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement; if (pathSegments[0] == "LITTLEBIGPLANETPS3_XML") { - // Get user via GameToken - GameTokenEntity? token = await database.GameTokenFromRequest(context.Request); - UserEntity? user = await database.UserFromGameToken(token); - - // Check second part of path to see if client is within an enforced path - if (enforcedPaths.Contains(pathSegments[1])) + if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement) { - // Check if user is valid - if (user == null) - { - // Send bad request status - context.Response.StatusCode = StatusCodes.Status400BadRequest; - await context.Response.WriteAsync("Not a valid user"); + // Get user via GameToken + GameTokenEntity? token = await database.GameTokenFromRequest(context.Request); + UserEntity? user = await database.UserFromGameToken(token); - // Don't go to next in pipeline - return; - } - - // Check if email is there and verified - if (emailEnforcementEnabled && (!user.EmailAddressVerified || user.EmailAddress == null)) + // Check second part of path to see if client is within an enforced path + // This could probably be reworked, seeing as you may want to check for a deeper sub-path + // But it should be perfectly fine for now + if (enforcedPaths.Contains(pathSegments[1])) { - // Send bad request status - context.Response.StatusCode = StatusCodes.Status400BadRequest; - await context.Response.WriteAsync("Invalid user email address"); - - // Don't go to next in pipeline - return; + // Check if user is valid, don't want any exceptions + if (user == null) + { + // Send bad request status + context.Response.StatusCode = StatusCodes.Status400BadRequest; + await context.Response.WriteAsync("Not a valid user"); + + // Don't go to next in pipeline + return; + } + + // Check if email is there and verified + if (!user.EmailAddressVerified || user.EmailAddress == null) + { + // Send bad request status + context.Response.StatusCode = StatusCodes.Status400BadRequest; + await context.Response.WriteAsync("Invalid user email address"); + + // Don't go to next in pipeline + return; + } } } } diff --git a/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs new file mode 100644 index 00000000..eb2ec25f --- /dev/null +++ b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs @@ -0,0 +1,89 @@ +#nullable enable +using System.Collections.Generic; +using System.IO; +using YamlDotNet.Serialization; + +namespace LBPUnion.ProjectLighthouse.Configuration; + +public class EmailEnforcementConfiguration : ConfigurationBase +{ + public override int ConfigVersion { get; set; } = 2; + + public override string ConfigName { get; set; } = "enforce-email.yml"; + + public override bool NeedsConfiguration { get; set; } = false; + + public bool EnableEmailEnforcement { get; set; } = false; + public bool EnableEmailBlacklist { get; set; } = false; + + // No blacklist by default, add path to blacklist + public string BlacklistFilePath { get; set; } = ""; + + // 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() + { + // Comments + "rateUserComment", + "rateComment", + "comments", + "userComments", + "postUserComment", + "postComment", + "deleteUserComment", + "deleteComment", + + // Slots + "showModerated", + "startPublish", + "slots", + "s", + "tags", + "tag", + "searches", + "genres", + "publish", + "unpublish", + + // Misc Resources + "upload", + "r", + + // Photos + "uploadPhoto", + "photos", + "deletePhoto", + + // Gameplay + "match", + "play", + "enterLevel", + "playlists", + + // Users + "user", + "users", + "updateUser", + "update_my_pins", + }; + + public string EmailEnforcementMessageMain { get; set; } = + "This lighthouse instance has email enforcement enabled. " + + "If you haven't already, you will need to set and verify " + + "an email address to use most features.\\n"; + + public string EmailEnforcementMessageNoEmail { get; set; } = + "You do not have an email set on your account. You can set " + + "an email by opening the text chat and typing \"/setemail " + + "[youremail@example.com]\" (do not include the brackets.)\\n\\n"; + + public string EmailEnforcementMessageVerify { get; set; } = + "You have set an email address on your account, but you have not " + + "verified it. Make sure to check your inbox for a verification email. " + + "If you have not received an email, please contact an instance " + + "administrator for further assistance.\\n\\n"; + + public override ConfigurationBase Deserialize + (IDeserializer deserializer, string text) => + deserializer.Deserialize(text); +} \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/EnforceEmailConfiguration.cs b/ProjectLighthouse/Configuration/EnforceEmailConfiguration.cs deleted file mode 100644 index 1b747763..00000000 --- a/ProjectLighthouse/Configuration/EnforceEmailConfiguration.cs +++ /dev/null @@ -1,45 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using System.IO; -using YamlDotNet.Serialization; - -namespace LBPUnion.ProjectLighthouse.Configuration; - -public class EnforceEmailConfiguration : ConfigurationBase -{ - public override int ConfigVersion { get; set; } = 2; - - public override string ConfigName { get; set; } = "enforce-email.yml"; - - public override bool NeedsConfiguration { get; set; } = false; - - public bool EnableEmailEnforcement { get; set; } = false; - public bool EnableEmailBlacklist { get; set; } = false; - - // No blacklist by default, add path to blacklist - public string BlacklistFilePath { get; set; } = ""; - - public string DomainWhitelist { get; set; } = ""; - - // TODO: Finalize what to do with these - // Keep warnings here for debug until pull - public string EmailEnforcementMessageMain { get; set; } = - "This lighthouse instance has email enforcement enabled. " + - "If you haven't already, you will need to set and verify " + - "an email address to use most features.\n"; - - public string EmailEnforcementMessageNoEmail { get; set; } = - "You do not have an email set on your account. You can set " + - "an email by opening the text chat and typing \"/setemail " + - "[youremail@example.com]\" (do not include the brackets.)\n\n"; - - public string EmailEnforcementMessageVerify { get; set; } = - "You have set an email address on your account, but you have not " + - "verified it. Make sure to check your inbox for a verification email. " + - "If you have not received an email, please contact an instance " + - "administrator for further assistance.\n\n"; - - 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 63b7ea21..606b682b 100644 --- a/ProjectLighthouse/Helpers/EmailHelper.cs +++ b/ProjectLighthouse/Helpers/EmailHelper.cs @@ -27,8 +27,8 @@ public static class SMTPHelper // To prevent ReadAllLines() exception when BlacklistFilePath is empty private static readonly string[] blacklistFile = - !string.IsNullOrWhiteSpace(EnforceEmailConfiguration.Instance.BlacklistFilePath) - ? File.ReadAllLines(EnforceEmailConfiguration.Instance.BlacklistFilePath) : []; + !string.IsNullOrWhiteSpace(EmailEnforcementConfiguration.Instance.BlacklistFilePath) + ? File.ReadAllLines(EmailEnforcementConfiguration.Instance.BlacklistFilePath) : []; private static readonly HashSet blacklistedDomains = new(blacklistFile); @@ -87,7 +87,7 @@ public static class SMTPHelper if (!string.IsNullOrWhiteSpace(email) && emailValidator.IsValid(email) && !EmailIsUsed(database, email).Result) { // Don't even bother if there are no domains in blacklist (AKA file path is empty/invalid, or file itself is empty) - if (EnforceEmailConfiguration.Instance.EnableEmailBlacklist && blacklistedDomains.Count > 0) + if (EmailEnforcementConfiguration.Instance.EnableEmailBlacklist && blacklistedDomains.Count > 0) { // Get domain by splitting at '@' character string domain = email.Split('@')[1];