From c7195df74fb2145ed206cab3c8f181c9c16c8d82 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 31 Oct 2022 20:48:09 -0500 Subject: [PATCH] Allow RegistrationTokens to have a username pre-selected (#524) * Add prefilled username to registration token * call toString on query to work with EF * Fix typo in RegisterForm.cshtml * Only show username notice if the user's username hasn't been chosen already * Add confirmation message to DeleteUserCommand --- .../Controllers/UserEndpoints.cs | 4 ++- .../Pages/RegisterForm.cshtml | 14 +++++++-- .../Pages/RegisterForm.cshtml.cs | 7 ++++- .../Maintenance/Commands/DeleteUserCommand.cs | 1 + .../Extensions/BinaryReaderExtensions.cs | 15 +++++----- ...16234831_AddUsernameToRegistrationToken.cs | 30 +++++++++++++++++++ .../PlayerData/RegistrationToken.cs | 2 ++ ProjectLighthouse/PlayerData/Score.cs | 2 +- .../Migrations/DatabaseModelSnapshot.cs | 3 ++ 9 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 ProjectLighthouse/Migrations/20221016234831_AddUsernameToRegistrationToken.cs diff --git a/ProjectLighthouse.Servers.API/Controllers/UserEndpoints.cs b/ProjectLighthouse.Servers.API/Controllers/UserEndpoints.cs index ef4aea40..35cb2886 100644 --- a/ProjectLighthouse.Servers.API/Controllers/UserEndpoints.cs +++ b/ProjectLighthouse.Servers.API/Controllers/UserEndpoints.cs @@ -68,7 +68,8 @@ public class UserEndpoints : ApiEndpointController } [HttpPost("user/inviteToken")] - public async Task CreateUserInviteToken() + [HttpPost("user/inviteToken/{username}")] + public async Task CreateUserInviteToken([FromRoute] string? username) { if (!Configuration.ServerConfiguration.Instance.Authentication.PrivateRegistration && !Configuration.ServerConfiguration.Instance.Authentication.RegistrationEnabled) @@ -86,6 +87,7 @@ public class UserEndpoints : ApiEndpointController { Created = DateTime.Now, Token = CryptoHelper.GenerateAuthToken(), + Username = username, }; this.database.RegistrationTokens.Add(token); diff --git a/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml b/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml index 56ccafa6..39e787d2 100644 --- a/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml @@ -33,7 +33,10 @@ } -

@Model.Translate(RegisterStrings.UsernameNotice)

+@if (Model.Username == null) +{ +

@Model.Translate(RegisterStrings.UsernameNotice)

+}
@Html.AntiForgeryToken() @@ -41,7 +44,14 @@
- + @{ + string extra = ""; + if (Model.Username != null) + { + extra = "value=" + Model.Username + " readonly"; + } + } +
diff --git a/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml.cs index 3f8260d0..e471b3fc 100644 --- a/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/RegisterForm.cshtml.cs @@ -7,7 +7,6 @@ using LBPUnion.ProjectLighthouse.Localization.StringLists; using LBPUnion.ProjectLighthouse.PlayerData; using LBPUnion.ProjectLighthouse.PlayerData.Profiles; using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts; -using LBPUnion.ProjectLighthouse.Types; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -20,6 +19,8 @@ public class RegisterForm : BaseLayout public string? Error { get; private set; } + public string? Username { get; set; } + [UsedImplicitly] [SuppressMessage("ReSharper", "SpecifyStringComparison")] public async Task OnPost(string username, string password, string confirmPassword, string emailAddress) @@ -30,6 +31,8 @@ public class RegisterForm : BaseLayout { if (!this.Database.IsRegistrationTokenValid(this.Request.Query["token"])) return this.StatusCode(403, this.Translate(ErrorStrings.TokenInvalid)); + + username = (await this.Database.RegistrationTokens.FirstAsync(r => r.Token == this.Request.Query["token"].ToString())).Username; } else { @@ -119,6 +122,8 @@ public class RegisterForm : BaseLayout { if (!this.Database.IsRegistrationTokenValid(this.Request.Query["token"])) return this.StatusCode(403, this.Translate(ErrorStrings.TokenInvalid)); + + this.Username = this.Database.RegistrationTokens.First(r => r.Token == this.Request.Query["token"].ToString()).Username; } else { diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs index f61b2bf9..277b8039 100644 --- a/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs +++ b/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs @@ -34,5 +34,6 @@ public class DeleteUserCommand : ICommand } await this.database.RemoveUser(user); + logger.LogSuccess($"Successfully deleted user {user.Username}", LogArea.Command); } } \ No newline at end of file diff --git a/ProjectLighthouse/Extensions/BinaryReaderExtensions.cs b/ProjectLighthouse/Extensions/BinaryReaderExtensions.cs index ef6f045c..f3f27b6d 100644 --- a/ProjectLighthouse/Extensions/BinaryReaderExtensions.cs +++ b/ProjectLighthouse/Extensions/BinaryReaderExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers.Binary; using System.IO; namespace LBPUnion.ProjectLighthouse.Extensions; @@ -15,19 +16,19 @@ public static class BinaryReaderExtensions return b; } - public static ushort ReadUInt16BE(this BinaryReader binRdr) => BitConverter.ToUInt16(binRdr.ReadBytesRequired(sizeof(ushort)).Reverse(), 0); + public static ushort ReadUInt16BE(this BinaryReader binRdr) => BinaryPrimitives.ReadUInt16BigEndian(binRdr.ReadBytesRequired(sizeof(ushort))); - public static short ReadInt16BE(this BinaryReader binRdr) => BitConverter.ToInt16(binRdr.ReadBytesRequired(sizeof(short)).Reverse(), 0); + public static short ReadInt16BE(this BinaryReader binRdr) => BinaryPrimitives.ReadInt16BigEndian(binRdr.ReadBytesRequired(sizeof(short))); - public static uint ReadUInt32BE(this BinaryReader binRdr) => BitConverter.ToUInt32(binRdr.ReadBytesRequired(sizeof(uint)).Reverse(), 0); + public static uint ReadUInt32BE(this BinaryReader binRdr) => BinaryPrimitives.ReadUInt32BigEndian(binRdr.ReadBytesRequired(sizeof(uint))); - public static int ReadInt32BE(this BinaryReader binRdr) => BitConverter.ToInt32(binRdr.ReadBytesRequired(sizeof(int)).Reverse(), 0); + public static int ReadInt32BE(this BinaryReader binRdr) => BinaryPrimitives.ReadInt32BigEndian(binRdr.ReadBytesRequired(sizeof(int))); - public static ulong ReadUInt64BE(this BinaryReader binRdr) => BitConverter.ToUInt32(binRdr.ReadBytesRequired(sizeof(ulong)).Reverse(), 0); + public static ulong ReadUInt64BE(this BinaryReader binRdr) => BinaryPrimitives.ReadUInt64BigEndian(binRdr.ReadBytesRequired(sizeof(ulong))); - public static long ReadInt64BE(this BinaryReader binRdr) => BitConverter.ToInt32(binRdr.ReadBytesRequired(sizeof(long)).Reverse(), 0); + public static long ReadInt64BE(this BinaryReader binRdr) => BinaryPrimitives.ReadInt64BigEndian(binRdr.ReadBytesRequired(sizeof(long))); - public static byte[] ReadBytesRequired(this BinaryReader binRdr, int byteCount) + private static byte[] ReadBytesRequired(this BinaryReader binRdr, int byteCount) { byte[] result = binRdr.ReadBytes(byteCount); diff --git a/ProjectLighthouse/Migrations/20221016234831_AddUsernameToRegistrationToken.cs b/ProjectLighthouse/Migrations/20221016234831_AddUsernameToRegistrationToken.cs new file mode 100644 index 00000000..e0acd22f --- /dev/null +++ b/ProjectLighthouse/Migrations/20221016234831_AddUsernameToRegistrationToken.cs @@ -0,0 +1,30 @@ +using LBPUnion.ProjectLighthouse; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ProjectLighthouse.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20221016234831_AddUsernameToRegistrationToken")] + public partial class AddUsernameToRegistrationToken : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Username", + table: "RegistrationTokens", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Username", + table: "RegistrationTokens"); + } + } +} diff --git a/ProjectLighthouse/PlayerData/RegistrationToken.cs b/ProjectLighthouse/PlayerData/RegistrationToken.cs index 6e0bd7f6..1dee11d8 100644 --- a/ProjectLighthouse/PlayerData/RegistrationToken.cs +++ b/ProjectLighthouse/PlayerData/RegistrationToken.cs @@ -11,6 +11,8 @@ namespace LBPUnion.ProjectLighthouse.PlayerData public string Token { get; set; } public DateTime Created { get; set; } + + public string Username { get; set; } } } diff --git a/ProjectLighthouse/PlayerData/Score.cs b/ProjectLighthouse/PlayerData/Score.cs index b584b43f..0dcaf6ee 100644 --- a/ProjectLighthouse/PlayerData/Score.cs +++ b/ProjectLighthouse/PlayerData/Score.cs @@ -22,7 +22,7 @@ public class Score public Slot Slot { get; set; } [XmlIgnore] - public int? ChildSlotId { get; set; } + public int ChildSlotId { get; set; } [XmlElement("type")] public int Type { get; set; } diff --git a/ProjectLighthouse/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index e4084263..bc21a18a 100644 --- a/ProjectLighthouse/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -873,6 +873,9 @@ namespace ProjectLighthouse.Migrations b.Property("Token") .HasColumnType("longtext"); + b.Property("Username") + .HasColumnType("longtext"); + b.HasKey("TokenId"); b.ToTable("RegistrationTokens");