Fix slot version bug and other improvements (#281)

* Fix slot version bug and other improvements

* Fix upload tests not authenticating

Co-authored-by: jvyden <jvyden@jvyden.xyz>
This commit is contained in:
Josh 2022-04-13 14:00:45 -05:00 committed by GitHub
parent 3aecccedf2
commit 216cd2e198
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 35 deletions

View file

@ -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);
}

View file

@ -73,6 +73,16 @@ public class LighthouseServerTest
return await this.Client.PostAsync($"/LITTLEBIGPLANETPS3_XML/upload/{hash}", new ByteArrayContent(bytes));
}
public async Task<HttpResponseMessage> 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<HttpResponseMessage> UploadFileRequest(string endpoint, string filePath)
=> await this.Client.PostAsync(endpoint, new StringContent(await File.ReadAllTextAsync(filePath)));

View file

@ -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<IActionResult> 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<IActionResult> 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 (ImageHelper.LbpFileToPNG(file))
if (file != null && ImageHelper.LbpFileToPNG(file))
{
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<IActionResult> 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);

View file

@ -76,7 +76,6 @@ public class PublishController : ControllerBase
[HttpPost("publish")]
public async Task<IActionResult> 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)
{

View file

@ -28,7 +28,6 @@
</div>
<input type="submit" class="ui blue button">
</form>
<br>
}
@for(int i = 0; i < Model.Comments.Count; i++)

View file

@ -51,7 +51,7 @@
}
<div class="cardStatsUnderTitle">
<i class="pink heart icon" title="Hearts"></i> <span>@Model.Hearts</span>
<i class="blue play icon" title="Plays"></i> <span>@Model.Plays</span>
<i class="blue play icon" title="Plays"></i> <span>@Model.PlaysUnique</span>
<i class="green thumbs up icon" title="Yays"></i> <span>@Model.Thumbsup</span>
<i class="red thumbs down icon" title="Boos"></i> <span>@Model.Thumbsdown</span>

View file

@ -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 @@
}
<div class="ui divider"></div>
@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,7 +114,24 @@
<img class="cardIcon slotCardIcon" src="@ServerSettings.Instance.ExternalUrl/gameAssets/@faceHash" alt="@faceAlt" title="@faceAlt" style="min-width: @(size)px; width: @(size)px; height: @(size)px">
</div>
<div class="cardStats">
<h3 style="margin-bottom: 5px;">@review.Reviewer.Username</h3>
<h3 style="margin-bottom: 5px;">@review.Reviewer?.Username</h3>
@if (review.Deleted)
{
if (review.DeletedBy == DeletedBy.LevelAuthor)
{
<p>
<i>This review has been deleted by the level author.</i>
</p>
}
else
{
<p>
<i>This review has been deleted by a moderator.</i>
</p>
}
}
else
{
@if (review.Labels.Length > 1)
{
@foreach (string reviewLabel in review.Labels)
@ -121,12 +146,18 @@
</p>
}
else
{
{
<p>@review.Text</p>
}
}
}
</div>
</div>
<br>
@if (i != Model.Reviews.Count - 1)
{
<div class="ui divider"></div>
}
}
</div>
</div>