From bce6d1e2effe7ceb55357f35cf3b4b2d7529c421 Mon Sep 17 00:00:00 2001 From: jvyden Date: Thu, 14 Oct 2021 23:49:22 -0400 Subject: [PATCH 1/5] Fix PlanetHash being null on user creation --- ProjectLighthouse/Database.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index a8372e49..dc33f549 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -28,7 +28,8 @@ namespace ProjectLighthouse { Username = username, LocationId = l.Id, Biography = "No biography provided", - Pins = "" + Pins = "", + PlanetHash = "", }; this.Users.Add(user); From 5052d19656fbe2136e1e3f2a241f391613953e87 Mon Sep 17 00:00:00 2001 From: jvyden Date: Thu, 14 Oct 2021 23:50:08 -0400 Subject: [PATCH 2/5] Basic testing framework --- ProjectLighthouse.Tests/DatabaseFact.cs | 11 +++++++ ProjectLighthouse.Tests/LighthouseTest.cs | 19 ++++++++++++ .../ProjectLighthouse.Tests.csproj | 29 +++++++++++++++++++ ...ProjectLighthouse.Tests.csproj.DotSettings | 2 ++ .../Tests/AuthenticationTest.cs | 28 ++++++++++++++++++ ProjectLighthouse.sln | 6 ++++ .../Controllers/LoginController.cs | 3 -- ProjectLighthouse/Types/ServerSettings.cs | 3 +- 8 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 ProjectLighthouse.Tests/DatabaseFact.cs create mode 100644 ProjectLighthouse.Tests/LighthouseTest.cs create mode 100644 ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj create mode 100644 ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj.DotSettings create mode 100644 ProjectLighthouse.Tests/Tests/AuthenticationTest.cs diff --git a/ProjectLighthouse.Tests/DatabaseFact.cs b/ProjectLighthouse.Tests/DatabaseFact.cs new file mode 100644 index 00000000..ecb8216f --- /dev/null +++ b/ProjectLighthouse.Tests/DatabaseFact.cs @@ -0,0 +1,11 @@ +using ProjectLighthouse.Types; +using Xunit; + +namespace ProjectLighthouse.Tests { + public sealed class DatabaseFact : FactAttribute { + public DatabaseFact() { + ServerSettings.DbConnectionString = "server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse"; + if(!ServerSettings.DbConnected) Skip = "Database not available"; + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse.Tests/LighthouseTest.cs b/ProjectLighthouse.Tests/LighthouseTest.cs new file mode 100644 index 00000000..0cacb69c --- /dev/null +++ b/ProjectLighthouse.Tests/LighthouseTest.cs @@ -0,0 +1,19 @@ +using System; +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using ProjectLighthouse.Types; + +namespace ProjectLighthouse.Tests { + public class LighthouseTest { + public readonly TestServer Server; + public readonly HttpClient Client; + + public LighthouseTest() { + this.Server = new TestServer(new WebHostBuilder() + .UseStartup()); + this.Client = this.Server.CreateClient(); + + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj new file mode 100644 index 00000000..cd72611b --- /dev/null +++ b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj @@ -0,0 +1,29 @@ + + + + enable + + false + + net5.0;net6.0 + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj.DotSettings b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj.DotSettings new file mode 100644 index 00000000..eccc8454 --- /dev/null +++ b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs new file mode 100644 index 00000000..e06ee7b3 --- /dev/null +++ b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs @@ -0,0 +1,28 @@ +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Xunit; + +namespace ProjectLighthouse.Tests { + public class AuthenticationTest : LighthouseTest { + [Fact] + public async Task ShouldReturnErrorOnNoPostData() { + var response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!); + Assert.False(response.IsSuccessStatusCode); + #if NET6_0_OR_GREATER + Assert.True(response.StatusCode == HttpStatusCode.BadRequest); + #else + Assert.True(response.StatusCode == HttpStatusCode.NotAcceptable); + #endif + } + + [DatabaseFact] + public async Task ShouldAuthenticateWithValidData() { + const char nullChar = (char)0x00; + const char sepChar = (char)0x20; + + var response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", new StringContent($"{nullChar}{sepChar}jvyden{nullChar}")); + Assert.True(response.StatusCode == HttpStatusCode.OK); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse.sln b/ProjectLighthouse.sln index 12322461..96db324b 100644 --- a/ProjectLighthouse.sln +++ b/ProjectLighthouse.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse", "ProjectLighthouse\ProjectLighthouse.csproj", "{C6CFD4AD-47ED-4C86-B0C4-A4216D82E0DC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests", "ProjectLighthouse.Tests\ProjectLighthouse.Tests.csproj", "{AFC74569-B289-4ACC-B21C-313A3A62C017}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {C6CFD4AD-47ED-4C86-B0C4-A4216D82E0DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {C6CFD4AD-47ED-4C86-B0C4-A4216D82E0DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {C6CFD4AD-47ED-4C86-B0C4-A4216D82E0DC}.Release|Any CPU.Build.0 = Release|Any CPU + {AFC74569-B289-4ACC-B21C-313A3A62C017}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFC74569-B289-4ACC-B21C-313A3A62C017}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFC74569-B289-4ACC-B21C-313A3A62C017}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFC74569-B289-4ACC-B21C-313A3A62C017}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index 5b137aa4..dfb6a0fa 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -14,9 +14,6 @@ namespace ProjectLighthouse.Controllers { public class LoginController : ControllerBase { [HttpPost] public async Task Login() { - if(!this.Request.Query.TryGetValue("titleID", out StringValues _)) - return this.BadRequest(""); - string body = await new StreamReader(Request.Body).ReadToEndAsync(); LoginData loginData; diff --git a/ProjectLighthouse/Types/ServerSettings.cs b/ProjectLighthouse/Types/ServerSettings.cs index 39fc79d9..bde98a9c 100644 --- a/ProjectLighthouse/Types/ServerSettings.cs +++ b/ProjectLighthouse/Types/ServerSettings.cs @@ -16,10 +16,11 @@ namespace ProjectLighthouse.Types { public static string DbConnectionString { get { if(dbConnectionString == null) { - return dbConnectionString = Environment.GetEnvironmentVariable("LIGHTHOUSE_DB_CONNECTION_STRING") ?? ""; + return dbConnectionString = Environment.GetEnvironmentVariable("") ?? ""; } return dbConnectionString; } + set => dbConnectionString = value; } public static bool DbConnected { From bd8b86b65cef8c3b555c0c336d48c85702a4a18b Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 15 Oct 2021 00:38:33 -0400 Subject: [PATCH 3/5] Add CanSerializeBack, CanUseToken, and ShouldReturnForbiddenWhenNotAuthenticated authentication tests --- ProjectLighthouse.Tests/LighthouseTest.cs | 34 +++++++++++++- .../Tests/AuthenticationTest.cs | 44 ++++++++++++++++--- ProjectLighthouse/Types/LoginResult.cs | 5 +++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/ProjectLighthouse.Tests/LighthouseTest.cs b/ProjectLighthouse.Tests/LighthouseTest.cs index 0cacb69c..f76a6e60 100644 --- a/ProjectLighthouse.Tests/LighthouseTest.cs +++ b/ProjectLighthouse.Tests/LighthouseTest.cs @@ -1,7 +1,10 @@ -using System; +using System.IO; using System.Net.Http; +using System.Threading.Tasks; +using System.Xml.Serialization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; +using ProjectLighthouse.Serialization; using ProjectLighthouse.Types; namespace ProjectLighthouse.Tests { @@ -12,8 +15,37 @@ namespace ProjectLighthouse.Tests { public LighthouseTest() { this.Server = new TestServer(new WebHostBuilder() .UseStartup()); + this.Client = this.Server.CreateClient(); + } + public async Task AuthenticateResponse(int number = 0) { + const char nullChar = (char)0x00; + const char sepChar = (char)0x20; + const string username = "unitTestUser"; + + string stringContent = $"{nullChar}{sepChar}{username}{number}{nullChar}"; + + HttpResponseMessage response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", new StringContent(stringContent)); + return response; + } + + public async Task Authenticate(int number = 0) { + HttpResponseMessage response = await this.AuthenticateResponse(number); + + string responseContent = LbpSerializer.StringElement("loginResult", await response.Content.ReadAsStringAsync()); + + XmlSerializer serializer = new(typeof(LoginResult)); + return (LoginResult)serializer.Deserialize(new StringReader(responseContent))!; + } + + public Task AuthenticatedRequest(string endpoint, string mmAuth) => AuthenticatedRequest(endpoint, mmAuth, HttpMethod.Get); + + public Task AuthenticatedRequest(string endpoint, string mmAuth, HttpMethod method) { + using var requestMessage = new HttpRequestMessage(method, endpoint); + requestMessage.Headers.Add("Cookie", mmAuth); + + return this.Client.SendAsync(requestMessage); } } } \ No newline at end of file diff --git a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs index e06ee7b3..2cc09083 100644 --- a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs +++ b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs @@ -1,13 +1,15 @@ +using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Threading.Tasks; +using ProjectLighthouse.Types; using Xunit; namespace ProjectLighthouse.Tests { public class AuthenticationTest : LighthouseTest { [Fact] public async Task ShouldReturnErrorOnNoPostData() { - var response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!); + HttpResponseMessage response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!); Assert.False(response.IsSuccessStatusCode); #if NET6_0_OR_GREATER Assert.True(response.StatusCode == HttpStatusCode.BadRequest); @@ -17,12 +19,42 @@ namespace ProjectLighthouse.Tests { } [DatabaseFact] - public async Task ShouldAuthenticateWithValidData() { - const char nullChar = (char)0x00; - const char sepChar = (char)0x20; + public async Task ShouldReturnWithValidData() { + HttpResponseMessage response = await this.AuthenticateResponse(); + Assert.True(response.IsSuccessStatusCode); + string responseContent = await response.Content.ReadAsStringAsync(); + Assert.Contains("MM_AUTH=", responseContent); + Assert.Contains(ServerSettings.ServerName, responseContent); + } + + [DatabaseFact] + public async Task CanSerializeBack() { + LoginResult loginResult = await this.Authenticate(); - var response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", new StringContent($"{nullChar}{sepChar}jvyden{nullChar}")); - Assert.True(response.StatusCode == HttpStatusCode.OK); + Assert.NotNull(loginResult); + Assert.NotNull(loginResult.AuthTicket); + Assert.NotNull(loginResult.LbpEnvVer); + + Assert.Contains("MM_AUTH=", loginResult.AuthTicket); + Assert.Equal(ServerSettings.ServerName, loginResult.LbpEnvVer); + } + + [DatabaseFact] + public async Task CanUseToken() { + LoginResult loginResult = await this.Authenticate(); + + HttpResponseMessage response = await AuthenticatedRequest("/LITTLEBIGPLANETPS3_XML/eula", loginResult.AuthTicket); + string responseContent = await response.Content.ReadAsStringAsync(); + + Assert.True(response.IsSuccessStatusCode); + Assert.Contains("You are logged in", responseContent); + } + + [DatabaseFact] + public async Task ShouldReturnForbiddenWhenNotAuthenticated() { + HttpResponseMessage response = await this.Client.GetAsync("/LITTLEBIGPLANETPS3_XML/eula"); + Assert.False(response.IsSuccessStatusCode); + Assert.True(response.StatusCode == HttpStatusCode.Forbidden); } } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/LoginResult.cs b/ProjectLighthouse/Types/LoginResult.cs index f9c20260..64bc5be0 100644 --- a/ProjectLighthouse/Types/LoginResult.cs +++ b/ProjectLighthouse/Types/LoginResult.cs @@ -1,12 +1,17 @@ using System.Collections.Generic; +using System.Xml.Serialization; using ProjectLighthouse.Serialization; namespace ProjectLighthouse.Types { /// /// Response to POST /login /// + [XmlRoot("loginResult"), XmlType("loginResult")] public class LoginResult { + [XmlElement("authTicket")] public string AuthTicket { get; set; } + + [XmlElement("lbpEnvVer")] public string LbpEnvVer { get; set; } public string Serialize() { From 0df715045dbe4db14119e874cb718c1dcf21d205 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 15 Oct 2021 00:44:08 -0400 Subject: [PATCH 4/5] Cleanup imports --- ProjectLighthouse.Tests/Tests/AuthenticationTest.cs | 1 - ProjectLighthouse/Controllers/LoginController.cs | 3 --- ProjectLighthouse/Controllers/MessageController.cs | 1 - ProjectLighthouse/Database.cs | 1 - ProjectLighthouse/Helpers/BinaryHelper.cs | 1 - 5 files changed, 7 deletions(-) diff --git a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs index 2cc09083..42a3ffca 100644 --- a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs +++ b/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Threading.Tasks; diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index dfb6a0fa..00c21c38 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -1,10 +1,7 @@ #nullable enable -using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Primitives; using ProjectLighthouse.Types; namespace ProjectLighthouse.Controllers { diff --git a/ProjectLighthouse/Controllers/MessageController.cs b/ProjectLighthouse/Controllers/MessageController.cs index c6a4089c..89e4b89a 100644 --- a/ProjectLighthouse/Controllers/MessageController.cs +++ b/ProjectLighthouse/Controllers/MessageController.cs @@ -1,6 +1,5 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; using ProjectLighthouse.Types; namespace ProjectLighthouse.Controllers { diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index dc33f549..298851aa 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -1,5 +1,4 @@ #nullable enable -using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; diff --git a/ProjectLighthouse/Helpers/BinaryHelper.cs b/ProjectLighthouse/Helpers/BinaryHelper.cs index c62d14c8..6b66ff1c 100644 --- a/ProjectLighthouse/Helpers/BinaryHelper.cs +++ b/ProjectLighthouse/Helpers/BinaryHelper.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Text; From 5e31bb8c3174e95b4410ad77f27347b0b90ab509 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 15 Oct 2021 00:54:21 -0400 Subject: [PATCH 5/5] Add SerializerTests --- ...ticationTest.cs => AuthenticationTests.cs} | 2 +- .../Tests/SerializerTests.cs | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) rename ProjectLighthouse.Tests/Tests/{AuthenticationTest.cs => AuthenticationTests.cs} (97%) create mode 100644 ProjectLighthouse.Tests/Tests/SerializerTests.cs diff --git a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs b/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs similarity index 97% rename from ProjectLighthouse.Tests/Tests/AuthenticationTest.cs rename to ProjectLighthouse.Tests/Tests/AuthenticationTests.cs index 42a3ffca..e79bf903 100644 --- a/ProjectLighthouse.Tests/Tests/AuthenticationTest.cs +++ b/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs @@ -5,7 +5,7 @@ using ProjectLighthouse.Types; using Xunit; namespace ProjectLighthouse.Tests { - public class AuthenticationTest : LighthouseTest { + public class AuthenticationTests : LighthouseTest { [Fact] public async Task ShouldReturnErrorOnNoPostData() { HttpResponseMessage response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!); diff --git a/ProjectLighthouse.Tests/Tests/SerializerTests.cs b/ProjectLighthouse.Tests/Tests/SerializerTests.cs new file mode 100644 index 00000000..1f89c2f1 --- /dev/null +++ b/ProjectLighthouse.Tests/Tests/SerializerTests.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using ProjectLighthouse.Serialization; +using Xunit; + +namespace ProjectLighthouse.Tests { + public class SerializerTests : LighthouseTest { + [Fact] + public void BlankElementWorks() { + Assert.Equal("", LbpSerializer.BlankElement("test")); + } + + [Fact] + public void StringElementWorks() { + Assert.Equal("asd", LbpSerializer.StringElement("test", "asd")); + Assert.Equal("asd", LbpSerializer.StringElement(new KeyValuePair("test", "asd"))); + } + + [Fact] + public void TaggedStringElementWorks() { + Assert.Equal("asd", LbpSerializer.TaggedStringElement("test", "asd", "foo", "bar")); + Assert.Equal("asd", LbpSerializer.TaggedStringElement(new KeyValuePair("test", "asd"), + new KeyValuePair("foo", "bar"))); + } + + [Fact] + public void ElementsWorks() { + Assert.Equal("asdbar", LbpSerializer.Elements(new KeyValuePair("test", "asd"), + new KeyValuePair("foo", "bar"))); + } + } +} \ No newline at end of file