From 216cd2e1989c160776b64e95b178d165127ae121 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 13 Apr 2022 14:00:45 -0500 Subject: [PATCH] Fix slot version bug and other improvements (#281) * Fix slot version bug and other improvements * Fix upload tests not authenticating Co-authored-by: jvyden --- .../UploadTests.cs | 21 +++++-- .../LighthouseServerTest.cs | 10 +++ .../GameApi/Resources/ResourcesController.cs | 28 ++++++--- .../GameApi/Slots/PublishController.cs | 14 +++-- .../Pages/Partials/CommentsPartial.cshtml | 1 - .../Pages/Partials/SlotCardPartial.cshtml | 2 +- ProjectLighthouse/Pages/SlotPage.cshtml | 63 ++++++++++++++----- 7 files changed, 104 insertions(+), 35 deletions(-) diff --git a/ProjectLighthouse.Tests.GameApiTests/UploadTests.cs b/ProjectLighthouse.Tests.GameApiTests/UploadTests.cs index 8f788617..7ac1f72c 100644 --- a/ProjectLighthouse.Tests.GameApiTests/UploadTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/UploadTests.cs @@ -4,6 +4,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Tests; +using LBPUnion.ProjectLighthouse.Types; using Xunit; namespace ProjectLighthouse.Tests.GameApiTests; @@ -19,7 +20,9 @@ public class UploadTests : LighthouseServerTest [Fact] public async Task ShouldNotAcceptScript() { - HttpResponseMessage response = await this.UploadFileEndpointRequest("ExampleFiles/TestScript.ff"); + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await this.AuthenticatedUploadFileEndpointRequest("ExampleFiles/TestScript.ff", loginResult.AuthTicket); Assert.False(response.StatusCode == HttpStatusCode.Forbidden); Assert.False(response.IsSuccessStatusCode); } @@ -27,7 +30,9 @@ public class UploadTests : LighthouseServerTest [Fact] public async Task ShouldNotAcceptFarc() { - HttpResponseMessage response = await this.UploadFileEndpointRequest("ExampleFiles/TestFarc.farc"); + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await this.AuthenticatedUploadFileEndpointRequest("ExampleFiles/TestFarc.farc", loginResult.AuthTicket); Assert.False(response.StatusCode == HttpStatusCode.Forbidden); Assert.False(response.IsSuccessStatusCode); } @@ -35,7 +40,9 @@ public class UploadTests : LighthouseServerTest [Fact] public async Task ShouldNotAcceptGarbage() { - HttpResponseMessage response = await this.UploadFileEndpointRequest("ExampleFiles/TestGarbage.bin"); + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await this.AuthenticatedUploadFileEndpointRequest("ExampleFiles/TestGarbage.bin", loginResult.AuthTicket); Assert.False(response.StatusCode == HttpStatusCode.Forbidden); Assert.False(response.IsSuccessStatusCode); } @@ -43,7 +50,9 @@ public class UploadTests : LighthouseServerTest [Fact] public async Task ShouldAcceptTexture() { - HttpResponseMessage response = await this.UploadFileEndpointRequest("ExampleFiles/TestTexture.tex"); + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await this.AuthenticatedUploadFileEndpointRequest("ExampleFiles/TestTexture.tex", loginResult.AuthTicket); Assert.False(response.StatusCode == HttpStatusCode.Forbidden); Assert.True(response.IsSuccessStatusCode); } @@ -51,7 +60,9 @@ public class UploadTests : LighthouseServerTest [Fact] public async Task ShouldAcceptLevel() { - HttpResponseMessage response = await this.UploadFileEndpointRequest("ExampleFiles/TestLevel.lvl"); + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await this.AuthenticatedUploadFileEndpointRequest("ExampleFiles/TestLevel.lvl", loginResult.AuthTicket); Assert.False(response.StatusCode == HttpStatusCode.Forbidden); Assert.True(response.IsSuccessStatusCode); } diff --git a/ProjectLighthouse.Tests/LighthouseServerTest.cs b/ProjectLighthouse.Tests/LighthouseServerTest.cs index 7b37d188..02aa19fd 100644 --- a/ProjectLighthouse.Tests/LighthouseServerTest.cs +++ b/ProjectLighthouse.Tests/LighthouseServerTest.cs @@ -73,6 +73,16 @@ public class LighthouseServerTest return await this.Client.PostAsync($"/LITTLEBIGPLANETPS3_XML/upload/{hash}", new ByteArrayContent(bytes)); } + public async Task AuthenticatedUploadFileEndpointRequest(string filePath, string mmAuth) + { + byte[] bytes = await File.ReadAllBytesAsync(filePath); + string hash = HashHelper.Sha1Hash(bytes).ToLower(); + using HttpRequestMessage requestMessage = new(HttpMethod.Post, $"/LITTLEBIGPLANETPS3_XML/upload/{hash}"); + requestMessage.Headers.Add("Cookie", mmAuth); + requestMessage.Content = new ByteArrayContent(bytes); + return await this.Client.SendAsync(requestMessage); + } + public async Task UploadFileRequest(string endpoint, string filePath) => await this.Client.PostAsync(endpoint, new StringContent(await File.ReadAllTextAsync(filePath))); diff --git a/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs b/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs index 8162030f..75fc15dc 100644 --- a/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs @@ -1,5 +1,4 @@ #nullable enable -using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -20,6 +19,13 @@ namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Resources; [Route("LITTLEBIGPLANETPS3_XML")] public class ResourcesController : ControllerBase { + private readonly Database database; + + public ResourcesController(Database database) + { + this.database = database; + } + [HttpPost("showModerated")] public IActionResult ShowModerated() => this.Ok(LbpSerializer.BlankElement("resources")); @@ -27,6 +33,9 @@ public class ResourcesController : ControllerBase [HttpPost("showNotUploaded")] public async Task FilterResources() { + User? user = await this.database.UserFromGameRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync(); XmlSerializer serializer = new(typeof(ResourceList)); @@ -42,8 +51,11 @@ public class ResourcesController : ControllerBase } [HttpGet("r/{hash}")] - public IActionResult GetResource(string hash) + public async Task GetResource(string hash) { + User? user = await this.database.UserFromGameRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + string path = FileHelper.GetResourcePath(hash); if (FileHelper.ResourceExists(hash)) return this.File(IOFile.OpenRead(path), "application/octet-stream"); @@ -63,21 +75,21 @@ public class ResourcesController : ControllerBase } LbpFile? file = LbpFile.FromHash(hash); - if (file != null) + if (file != null && ImageHelper.LbpFileToPNG(file)) { - if (ImageHelper.LbpFileToPNG(file)) - { - return this.File(IOFile.OpenRead(path), "image/png"); - } + return this.File(IOFile.OpenRead(path), "image/png"); } - return this.NotFound(); } // TODO: check if this is a valid hash + [HttpPost("upload/{hash}/unattributed")] [HttpPost("upload/{hash}")] public async Task UploadResource(string hash) { + User? user = await this.database.UserFromGameRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + string assetsDirectory = FileHelper.ResourcePath; string path = FileHelper.GetResourcePath(hash); diff --git a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs index 032164f8..3a86d5ab 100644 --- a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs @@ -76,7 +76,6 @@ public class PublishController : ControllerBase [HttpPost("publish")] public async Task Publish() { -// User user = await this.database.UserFromGameRequest(this.Request); (User, GameToken)? userAndToken = await this.database.UserAndGameTokenFromRequest(this.Request); if (userAndToken == null) return this.StatusCode(403, ""); @@ -94,9 +93,9 @@ public class PublishController : ControllerBase if (slot.Name.Length > 100) return this.BadRequest(); - foreach (string resource in slot.Resources) + if (slot.Resources.Any(resource => !FileHelper.ResourceExists(resource))) { - if (!FileHelper.ResourceExists(resource)) return this.BadRequest(); + return this.BadRequest(); } LbpFile? rootLevel = LbpFile.FromHash(slot.RootLevel); @@ -148,7 +147,14 @@ public class PublishController : ControllerBase slot.TeamPick = oldSlot.TeamPick; // Only update a slot's gameVersion if the level was actually change - if (oldSlot.RootLevel != slot.RootLevel) slot.GameVersion = gameToken.GameVersion; + if (oldSlot.RootLevel != slot.RootLevel) + { + slot.GameVersion = gameToken.GameVersion; + } + else + { + slot.GameVersion = oldSlot.GameVersion; + } if (slot.MinimumPlayers == 0 || slot.MaximumPlayers == 0) { diff --git a/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml b/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml index 348db325..f921e5ad 100644 --- a/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml +++ b/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml @@ -28,7 +28,6 @@ -
} @for(int i = 0; i < Model.Comments.Count; i++) diff --git a/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml b/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml index 36318404..3852e600 100644 --- a/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml +++ b/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml @@ -51,7 +51,7 @@ }
@Model.Hearts - @Model.Plays + @Model.PlaysUnique @Model.Thumbsup @Model.Thumbsdown diff --git a/ProjectLighthouse/Pages/SlotPage.cshtml b/ProjectLighthouse/Pages/SlotPage.cshtml index 4e0153bd..1f8b9a96 100644 --- a/ProjectLighthouse/Pages/SlotPage.cshtml +++ b/ProjectLighthouse/Pages/SlotPage.cshtml @@ -1,6 +1,7 @@ @page "/slot/{id:int}" @using System.Web @using LBPUnion.ProjectLighthouse.Helpers.Extensions +@using LBPUnion.ProjectLighthouse.Types @using LBPUnion.ProjectLighthouse.Types.Reviews @using LBPUnion.ProjectLighthouse.Types.Settings @model LBPUnion.ProjectLighthouse.Pages.SlotPage @@ -81,16 +82,23 @@ }
- @foreach (Review review in Model.Reviews) + @for (int i = 0; i < Model.Reviews.Count; i++) { + Review review = Model.Reviews[i]; string faceHash = review.Thumb switch { - -1 => review.Reviewer.BooHash, - 0 => review.Reviewer.MehHash, - 1 => review.Reviewer.YayHash, + -1 => review.Reviewer?.BooHash, + 0 => review.Reviewer?.MehHash, + 1 => review.Reviewer?.YayHash, _ => throw new ArgumentOutOfRangeException(), }; + if (string.IsNullOrWhiteSpace(faceHash)) + { + faceHash = ServerSettings.Instance.MissingIconHash; + } + + string faceAlt = review.Thumb switch { -1 => "Boo!", 0 => "Meh.", @@ -106,27 +114,50 @@ @faceAlt
-

@review.Reviewer.Username

- @if (review.Labels.Length > 1) +

@review.Reviewer?.Username

+ @if (review.Deleted) { - @foreach (string reviewLabel in review.Labels) + if (review.DeletedBy == DeletedBy.LevelAuthor) { -
@reviewLabel.Replace("LABEL_", "")
+

+ This review has been deleted by the level author. +

+ } + else + { +

+ This review has been deleted by a moderator. +

} - } - @if (string.IsNullOrWhiteSpace(review.Text)) - { -

- This review contains no text. -

} else { -

@review.Text

+ @if (review.Labels.Length > 1) + { + @foreach (string reviewLabel in review.Labels) + { +
@reviewLabel.Replace("LABEL_", "")
+ } + } + @if (string.IsNullOrWhiteSpace(review.Text)) + { +

+ This review contains no text. +

+ } + else + { + { +

@review.Text

+ } + } }
-
+ @if (i != Model.Reviews.Count - 1) + { +
+ } }