Move everything into middleware

This commit is contained in:
FeTetra 2025-02-16 19:34:15 -05:00
parent a322a32b38
commit 561e1d4e26
8 changed files with 93 additions and 62 deletions

View file

@ -22,8 +22,6 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers;
public class CommentController : ControllerBase
{
private readonly DatabaseContext database;
private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement;
public CommentController(DatabaseContext database)
{
this.database = database;
@ -37,9 +35,6 @@ public class CommentController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Unauthorized();
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
// Return bad request if both are true or both are false
if ((slotId == 0 || SlotHelper.IsTypeInvalid(slotType)) == (username == null)) return this.BadRequest();
@ -57,9 +52,6 @@ public class CommentController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Unauthorized();
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
if ((slotId == 0 || SlotHelper.IsTypeInvalid(slotType)) == (username == null)) return this.BadRequest();
int originalSlotId = slotId;
@ -127,9 +119,6 @@ public class CommentController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Unauthorized();
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
// Deny request if in read-only mode
if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest();
@ -168,10 +157,6 @@ public class CommentController : ControllerBase
public async Task<IActionResult> DeleteComment([FromQuery] int commentId, string? username, string? slotType, int slotId)
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
// Deny request if in read-only mode
if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest();

View file

@ -1,10 +1,7 @@
#nullable enable
using System.Runtime.CompilerServices;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Migrations;
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;

View file

@ -25,8 +25,6 @@ public class MatchController : ControllerBase
{
private readonly DatabaseContext database;
private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement;
public MatchController(DatabaseContext database)
{
this.database = database;
@ -44,9 +42,6 @@ public class MatchController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Unauthorized();
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
await LastContactHelper.SetLastContact(this.database, user, token.GameVersion, token.Platform);
// Do not allow matchmaking if it has been disabled

View file

@ -27,8 +27,6 @@ public class PhotosController : ControllerBase
{
private readonly DatabaseContext database;
private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement;
public PhotosController(DatabaseContext database)
{
this.database = database;
@ -41,9 +39,6 @@ public class PhotosController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Unauthorized();
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
// Deny request if in read-only mode
if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest();
@ -181,12 +176,6 @@ public class PhotosController : ControllerBase
[HttpGet("photos/{slotType}/{id:int}")]
public async Task<IActionResult> SlotPhotos(string slotType, int id, [FromQuery] string? by)
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
if (SlotHelper.IsTypeInvalid(slotType)) return this.BadRequest();
if (slotType == "developer") id = await SlotHelper.GetPlaceholderSlotId(this.database, id, SlotType.Developer);
@ -248,10 +237,6 @@ public class PhotosController : ControllerBase
public async Task<IActionResult> DeletePhoto(int id)
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
PhotoEntity? photo = await this.database.Photos.FirstOrDefaultAsync(p => p.PhotoId == id);
if (photo == null) return this.NotFound();

View file

@ -1,15 +1,12 @@
#nullable enable
using System.Text;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Misc;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Resources;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using IOFile = System.IO.File;
@ -22,18 +19,9 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Resources;
[Route("LITTLEBIGPLANETPS3_XML")]
public class ResourcesController : ControllerBase
{
private readonly DatabaseContext database;
public ResourcesController(DatabaseContext database)
{
this.database = database;
}
[HttpPost("showModerated")]
public IActionResult ShowModerated() => this.Ok(new ResourceList());
private static readonly bool emailEnforcementEnabled = EnforceEmailConfiguration.Instance.EnableEmailEnforcement;
[HttpPost("filterResources")]
[HttpPost("showNotUploaded")]
public async Task<IActionResult> FilterResources()
@ -49,12 +37,6 @@ public class ResourcesController : ControllerBase
[HttpGet("r/{hash}")]
public async Task<IActionResult> GetResource(string hash)
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
string path = FileHelper.GetResourcePath(hash);
string fullPath = Path.GetFullPath(path);
@ -71,12 +53,6 @@ public class ResourcesController : ControllerBase
[HttpPost("upload/{hash}")]
public async Task<IActionResult> UploadResource(string hash)
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
// Return bad request on unverified email if enforcement is enabled
if (emailEnforcementEnabled && !user.EmailAddressVerified) return this.BadRequest();
string assetsDirectory = FileHelper.ResourcePath;
string path = FileHelper.GetResourcePath(hash);
string fullPath = Path.GetFullPath(path);

View file

@ -0,0 +1,89 @@
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
public class EmailEnforcementMiddleware : MiddlewareDBContext
{
private static readonly HashSet<string> enforcedPaths = new()
{
"rateUserComment",
"rateComment",
"comments",
"userComments",
"postUserComment",
"postComment",
"deleteUserComment",
"deleteComment",
"slots",
"upload",
"r",
"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 override async Task InvokeAsync(HttpContext context, DatabaseContext database)
{
// Split path into segments
string[] pathSegments = context.Request.Path.ToString().Split("/");
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]))
{
// 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");
// Don't go to next in pipeline
return;
}
// Check if email is there and verified
if (emailEnforcementEnabled && (!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;
}
}
}
// Go to next in pipeline
await this.next(context);
}
}

View file

@ -107,6 +107,7 @@ public class GameServerStartup
app.UseMiddleware<RateLimitMiddleware>();
app.UseMiddleware<DigestMiddleware>(computeDigests);
app.UseMiddleware<SetLastContactMiddleware>();
app.UseMiddleware<EmailEnforcementMiddleware>();
app.UseRouting();

View file

@ -18,7 +18,10 @@ public class EnforceEmailConfiguration : ConfigurationBase<EnforceEmailConfigura
// 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. " +