From a7d91b9368cc79dea6d084d87036ae6e9084a3f5 Mon Sep 17 00:00:00 2001 From: Mia Winter Date: Tue, 16 Jan 2024 21:05:14 +0100 Subject: [PATCH] Added tool to promote user to admin if there are no admins --- Wave/Components/Pages/Admin.razor | 81 +++++++++++++++++++++++++++++++ Wave/Program.cs | 10 ++++ 2 files changed, 91 insertions(+) create mode 100644 Wave/Components/Pages/Admin.razor diff --git a/Wave/Components/Pages/Admin.razor b/Wave/Components/Pages/Admin.razor new file mode 100644 index 0000000..6129b0d --- /dev/null +++ b/Wave/Components/Pages/Admin.razor @@ -0,0 +1,81 @@ +@page "/Admin" + +@using Microsoft.AspNetCore.Identity +@using Wave.Components.Account +@using Wave.Components.Account.Shared +@using Wave.Data +@using Microsoft.AspNetCore.Authorization + +@attribute [Authorize] +@inject IdentityUserAccessor UserAccessor +@inject RoleManager RoleManager +@inject UserManager UserManager +@inject SignInManager SignInManager +@inject IdentityRedirectManager RedirectManager + + + + + + + + +@code { + [CascadingParameter] + private HttpContext HttpContext { get; set; } = default!; + private ApplicationUser User { get; set; } = default!; + private string Password { get; set; } = string.Empty; + [SupplyParameterFromForm] + private InputModel Model { get; set; } = new(); + + private string? Message { get; set; } + + protected override async Task OnInitializedAsync() { + User = await UserAccessor.GetRequiredUserAsync(HttpContext); + + string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "admin.txt"); + if (File.Exists(path)) Password = await File.ReadAllTextAsync(path); + } + + private async Task Promote() { + if (string.IsNullOrWhiteSpace(Password)) { + RedirectManager.RedirectToWithStatus("/Admin", "Error: This tool is not enabled.", HttpContext); + return; + } + + if (Password != Model.Password) { + RedirectManager.RedirectToWithStatus("/Admin", "Error: Password Invalid.", HttpContext); + return; + } + + if (!await RoleManager.RoleExistsAsync("Admin")) { + var result = await RoleManager.CreateAsync(new IdentityRole("Admin")); + + if (!result.Succeeded) { + RedirectManager.RedirectToWithStatus("/Admin", "Error: Could not create Admin role, check logs.", HttpContext); + return; + } + } + await UserManager.AddToRoleAsync(User, "Admin"); + File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "admin.txt")); + await SignInManager.RefreshSignInAsync(User); + Message = "You have been promoted, this tool is now disabled."; + } + + private sealed class InputModel { + public string Password { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Wave/Program.cs b/Wave/Program.cs index 3c91f77..1490da7 100644 --- a/Wave/Program.cs +++ b/Wave/Program.cs @@ -95,6 +95,16 @@ using var scope = app.Services.CreateScope(); using var context = scope.ServiceProvider.GetRequiredService(); context.Database.Migrate(); + + var userManager = scope.ServiceProvider.GetRequiredService>(); + + if (userManager.GetUsersInRoleAsync("Admin").Result.Any() is false) { + string admin = Guid.NewGuid().ToString("N")[..16]; + Console.WriteLine( + "There is currently no user in your installation with the admin role, " + + "go to /Admin and use the following password to self promote your account: " + admin); + File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "admin.txt"), admin); + } } app.Run();