Slight refactor and polish

This commit is contained in:
FeTetra 2025-02-16 21:51:56 -05:00
commit 0c8ca731a4
6 changed files with 127 additions and 115 deletions

View file

@ -67,19 +67,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n"); 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) if (user.EmailAddress == null)
{ {
// This will probably need translations announceText.Insert(0, EmailEnforcementConfiguration.Instance.EmailEnforcementMessageNoEmail);
announceText.Insert(0, EnforceEmailConfiguration.Instance.EmailEnforcementMessageNoEmail);
} }
else if (!user.EmailAddressVerified) else if (!user.EmailAddressVerified)
{ {
// More stuff to translate later announceText.Insert(0, EmailEnforcementConfiguration.Instance.EmailEnforcementMessageVerify);
announceText.Insert(0, EnforceEmailConfiguration.Instance.EmailEnforcementMessageVerify);
} }
} }

View file

@ -29,7 +29,7 @@ public class UserController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;
private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement; private static readonly bool emailEnforcementEnabled = EmailEnforcementConfiguration.Instance.EnableEmailEnforcement;
public UserController(DatabaseContext database) public UserController(DatabaseContext database)
{ {

View file

@ -3,46 +3,12 @@ using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Middlewares; using LBPUnion.ProjectLighthouse.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Logging;
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares; namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
public class EmailEnforcementMiddleware : MiddlewareDBContext public class EmailEnforcementMiddleware : MiddlewareDBContext
{ {
private static readonly HashSet<string> enforcedPaths = new() private static readonly HashSet<string> enforcedPaths = EmailEnforcementConfiguration.Instance.BlockedEndpoints;
{
"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",
};
public EmailEnforcementMiddleware(RequestDelegate next) : base(next) public EmailEnforcementMiddleware(RequestDelegate next) : base(next)
{ } { }
@ -51,37 +17,41 @@ public class EmailEnforcementMiddleware : MiddlewareDBContext
{ {
// Split path into segments // Split path into segments
string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries); string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries);
bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement;
if (pathSegments[0] == "LITTLEBIGPLANETPS3_XML") if (pathSegments[0] == "LITTLEBIGPLANETPS3_XML")
{ {
// Get user via GameToken if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement)
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]))
{ {
// Check if user is valid // Get user via GameToken
if (user == null) GameTokenEntity? token = await database.GameTokenFromRequest(context.Request);
{ UserEntity? user = await database.UserFromGameToken(token);
// Send bad request status
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Not a valid user");
// Don't go to next in pipeline // Check second part of path to see if client is within an enforced path
return; // 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]))
// Check if email is there and verified
if (emailEnforcementEnabled && (!user.EmailAddressVerified || user.EmailAddress == null))
{ {
// Send bad request status // Check if user is valid, don't want any exceptions
context.Response.StatusCode = StatusCodes.Status400BadRequest; if (user == null)
await context.Response.WriteAsync("Invalid user email address"); {
// Send bad request status
// Don't go to next in pipeline context.Response.StatusCode = StatusCodes.Status400BadRequest;
return; 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;
}
} }
} }
} }

View file

@ -0,0 +1,89 @@
#nullable enable
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
namespace LBPUnion.ProjectLighthouse.Configuration;
public class EmailEnforcementConfiguration : ConfigurationBase<EmailEnforcementConfiguration>
{
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<string> 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<EmailEnforcementConfiguration> Deserialize
(IDeserializer deserializer, string text) =>
deserializer.Deserialize<EmailEnforcementConfiguration>(text);
}

View file

@ -1,45 +0,0 @@
#nullable enable
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
namespace LBPUnion.ProjectLighthouse.Configuration;
public class EnforceEmailConfiguration : ConfigurationBase<EnforceEmailConfiguration>
{
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 \"<em>/setemail " +
"[youremail@example.com]</em>\" (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<EnforceEmailConfiguration> Deserialize
(IDeserializer deserializer, string text) =>
deserializer.Deserialize<EnforceEmailConfiguration>(text);
}

View file

@ -27,8 +27,8 @@ public static class SMTPHelper
// To prevent ReadAllLines() exception when BlacklistFilePath is empty // To prevent ReadAllLines() exception when BlacklistFilePath is empty
private static readonly string[] blacklistFile = private static readonly string[] blacklistFile =
!string.IsNullOrWhiteSpace(EnforceEmailConfiguration.Instance.BlacklistFilePath) !string.IsNullOrWhiteSpace(EmailEnforcementConfiguration.Instance.BlacklistFilePath)
? File.ReadAllLines(EnforceEmailConfiguration.Instance.BlacklistFilePath) : []; ? File.ReadAllLines(EmailEnforcementConfiguration.Instance.BlacklistFilePath) : [];
private static readonly HashSet<string> blacklistedDomains = new(blacklistFile); private static readonly HashSet<string> blacklistedDomains = new(blacklistFile);
@ -87,7 +87,7 @@ public static class SMTPHelper
if (!string.IsNullOrWhiteSpace(email) && emailValidator.IsValid(email) && !EmailIsUsed(database, email).Result) 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) // 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 // Get domain by splitting at '@' character
string domain = email.Split('@')[1]; string domain = email.Split('@')[1];