diff --git a/UT4MasterServer/Controllers/Epic/CloudStorageController.cs b/UT4MasterServer/Controllers/Epic/CloudStorageController.cs index 479c047c..7ea80124 100644 --- a/UT4MasterServer/Controllers/Epic/CloudStorageController.cs +++ b/UT4MasterServer/Controllers/Epic/CloudStorageController.cs @@ -6,6 +6,7 @@ using UT4MasterServer.Models.DTO.Responses; using UT4MasterServer.Models.Database; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.StaticFiles; namespace UT4MasterServer.Controllers.Epic; @@ -18,6 +19,8 @@ public sealed class CloudStorageController : JsonAPIController private readonly MatchmakingService matchmakingService; private readonly AccountService accountService; + private static FileExtensionContentTypeProvider contentTypeProvider = new(); + public CloudStorageController(ILogger logger, CloudStorageService cloudStorageService, MatchmakingService matchmakingService, @@ -35,8 +38,50 @@ public async Task ListUserFiles(string id) return BuildListResult(files); } - [HttpGet("user/{id}/{filename}"), Produces("application/octet-stream")] + [HttpGet("user/{id}/{filename}")] public async Task GetUserFile(string id, string filename) + { + return await GetFile(id, filename); + } + + [HttpPut("user/{id}/{filename}")] + public async Task UpdateUserFile(string id, string filename) + { + if (User.Identity is not EpicUserIdentity user) + return Unauthorized(); + var accountID = EpicID.FromString(id); + if (user.Session.AccountID != accountID) + { + // cannot modify other's files + + // unless you are a game server with this player and are modifying this player's stats file + var isServerWithPlayer = await matchmakingService.DoesClientOwnGameServerWithPlayerAsync(user.Session.ClientID, accountID); + if (!isServerWithPlayer || filename != "stats.json") + { + return Unauthorized(); + } + } + + await cloudStorageService.UpdateFileAsync(accountID, filename, Request.Body); + return Ok(); + } + + [HttpGet("system")] + public async Task ListSystemFiles() + { + var files = await cloudStorageService.ListFilesAsync(EpicID.Empty, true); + return BuildListResult(files); + } + + [AllowAnonymous] + [HttpGet("system/{filename}")] + public async Task GetSystemFile(string filename) + { + return await GetFile(EpicID.Empty.ToString(), filename); + } + + [NonAction] + public async Task GetFile(string id, string filename) { bool isStatsFile = filename == "stats.json"; @@ -81,43 +126,13 @@ public async Task GetUserFile(string id, string filename) file.RawContent = tmp; } - return new FileContentResult(file.RawContent, "application/octet-stream"); - } - [HttpPut("user/{id}/{filename}")] - public async Task UpdateUserFile(string id, string filename) - { - if (User.Identity is not EpicUserIdentity user) - return Unauthorized(); - var accountID = EpicID.FromString(id); - if (user.Session.AccountID != accountID) + if (!contentTypeProvider.TryGetContentType(filename, out string? contentType)) { - // cannot modify other's files - - // unless you are a game server with this player and are modifying this player's stats file - var isServerWithPlayer = await matchmakingService.DoesClientOwnGameServerWithPlayerAsync(user.Session.ClientID, accountID); - if (!isServerWithPlayer || filename != "stats.json") - { - return Unauthorized(); - } + contentType = "application/octet-stream"; } - await cloudStorageService.UpdateFileAsync(accountID, filename, Request.Body); - return Ok(); - } - - [HttpGet("system")] - public async Task ListSystemFiles() - { - var files = await cloudStorageService.ListFilesAsync(EpicID.Empty, true); - return BuildListResult(files); - } - - [AllowAnonymous] - [HttpGet("system/{filename}"), Produces("application/octet-stream")] - public async Task GetSystemFile(string filename) - { - return await GetUserFile(EpicID.Empty.ToString(), filename); + return File(file.RawContent, contentType); } [NonAction]