1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2024-11-22 08:42:44 +01:00
Minecraft-Phantom-Panel/Server/Phantom.Server.Web/Pages/Setup.razor

122 lines
3.8 KiB
Plaintext

@page "/setup"
@using Phantom.Server.Services
@using Phantom.Server.Services.Audit
@using Phantom.Server.Web.Identity.Authentication
@using Microsoft.AspNetCore.Identity
@using System.ComponentModel.DataAnnotations
@using Phantom.Utils.Cryptography
@using System.Security.Cryptography
@attribute [AllowAnonymous]
@inject ServiceConfiguration ServiceConfiguration
@inject PhantomLoginManager LoginManager
@inject UserManager<IdentityUser> UserManager
@inject AuditLog AuditLog
<h1>Administrator Setup</h1>
<Form Model="form" OnSubmit="DoLogin">
<div style="max-width: 400px;">
<div class="row">
<div class="mb-3">
<FormTextInput Id="account-username" Label="Username" @bind-Value="form.Username" autocomplete="off" />
</div>
</div>
<div class="row">
<div class="mb-3">
<FormTextInput Id="account-password" Label="Password" Type="FormTextInputType.Password" @bind-Value="form.Password" autocomplete="new-password" />
</div>
</div>
<div class="row">
<div class="mb-3">
<FormTextInput Id="administration-token" Label="Administration Token" Type="FormTextInputType.Password" @bind-Value="form.AdministrationToken" autocomplete="off" />
</div>
</div>
<FormButtonSubmit Label="Continue" class="btn btn-primary" />
</div>
<FormSubmitError />
</Form>
@code {
private readonly CreateAdministratorAccountFormModel form = new();
private sealed class CreateAdministratorAccountFormModel : FormModel {
[Required]
public string Username { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
[Required]
public string AdministrationToken { get; set; } = string.Empty;
}
private async Task DoLogin(EditContext context) {
await form.SubmitModel.StartSubmitting();
if (!IsAdministratorTokenValid()) {
form.SubmitModel.StopSubmitting("Invalid administrator token.");
return;
}
var createUserResult = await CreateOrUpdateAdministrator();
if (!createUserResult.Succeeded) {
form.SubmitModel.StopSubmitting(GetErrors(createUserResult));
return;
}
var signInResult = await LoginManager.SignIn(form.Username, form.Password);
if (!signInResult.Succeeded) {
form.SubmitModel.StopSubmitting("Error logging in.");
}
}
private bool IsAdministratorTokenValid() {
byte[] formTokenBytes;
try {
formTokenBytes = TokenGenerator.GetBytesOrThrow(form.AdministrationToken);
} catch (Exception) {
return false;
}
return CryptographicOperations.FixedTimeEquals(formTokenBytes, ServiceConfiguration.AdministratorToken);
}
private async Task<IdentityResult> CreateOrUpdateAdministrator() {
var existingUser = await UserManager.FindByNameAsync(form.Username);
return existingUser == null ? await CreateAdministrator() : await UpdateAdministrator(existingUser);
}
private async Task<IdentityResult> CreateAdministrator() {
var newUser = new IdentityUser(form.Username);
var createUserResult = await UserManager.CreateAsync(newUser, form.Password);
if (!createUserResult.Succeeded) {
return createUserResult;
}
await AuditLog.AddAdministratorUserCreatedEvent(newUser);
var addToRoleResult = await UserManager.AddToRoleAsync(newUser, Role.Administrator.Name);
return addToRoleResult;
}
private async Task<IdentityResult> UpdateAdministrator(IdentityUser existingUser) {
await UserManager.RemovePasswordAsync(existingUser);
var result = await UserManager.AddPasswordAsync(existingUser, form.Password);
if (result.Succeeded) {
await AuditLog.AddAdministratorUserModifiedEvent(existingUser);
}
return result;
}
private string GetErrors(IdentityResult result) {
return string.Join("\n", result.Errors.Select(static error => error.Description));
}
}