Remove the ability to register accounts.

This commit is contained in:
2025-09-11 14:16:01 +01:00
parent 68917c8295
commit 63c33fcfcb
4 changed files with 27 additions and 243 deletions

View File

@@ -1,153 +0,0 @@
@page "/Account/Register"
@using System.ComponentModel.DataAnnotations
@using System.Text
@using System.Text.Encodings.Web
@using Microsoft.AspNetCore.Identity
@using Microsoft.AspNetCore.WebUtilities
@inject UserManager<IdentityUser> UserManager
@inject IUserStore<IdentityUser> UserStore
@inject SignInManager<IdentityUser> SignInManager
@inject IEmailSender<IdentityUser> EmailSender
@inject ILogger<Register> Logger
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager
<PageTitle>Register</PageTitle>
<h1>Register</h1>
<div class="row">
<div class="col-md-4">
<StatusMessage Message="@Message"/>
<EditForm asp-route-returnUrl="@ReturnUrl" FormName="register" method="post" Model="Input" OnValidSubmit="RegisterUser">
<DataAnnotationsValidator/>
<h2>Create a new account.</h2>
<hr/>
<ValidationSummary class="text-danger" role="alert"/>
<div class="form-floating mb-3">
<InputText aria-required="true" autocomplete="username" @bind-Value="Input.Email" class="form-control" placeholder="name@example.com"/>
<label for="email">Email</label>
<ValidationMessage class="text-danger" For="() => Input.Email"/>
</div>
<div class="form-floating mb-3">
<InputText aria-required="true" autocomplete="new-password" @bind-Value="Input.Password" class="form-control" placeholder="password" type="password"/>
<label for="password">Password</label>
<ValidationMessage class="text-danger" For="() => Input.Password"/>
</div>
<div class="form-floating mb-3">
<InputText aria-required="true" autocomplete="new-password" @bind-Value="Input.ConfirmPassword" class="form-control" placeholder="password" type="password"/>
<label for="confirm-password">Confirm Password</label>
<ValidationMessage class="text-danger" For="() => Input.ConfirmPassword"/>
</div>
<button class="btn btn-lg btn-primary w-100" type="submit">Register</button>
</EditForm>
</div>
<div class="col-md-6 col-md-offset-2">
<section>
<h3>Use another service to register.</h3>
<hr/>
<ExternalLoginPicker/>
</section>
</div>
</div>
@code {
private IEnumerable<IdentityError>? identityErrors;
[SupplyParameterFromForm]
private InputModel Input { get; set; } = new();
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
private string? Message => identityErrors is null ? null : $"Error: {string.Join(", ", identityErrors.Select(error => error.Description))}";
public async Task RegisterUser(EditContext editContext)
{
IdentityUser user = CreateUser();
await UserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
IUserEmailStore<IdentityUser> emailStore = GetEmailStore();
await emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
IdentityResult result = await UserManager.CreateAsync(user, Input.Password);
if(!result.Succeeded)
{
identityErrors = result.Errors;
return;
}
Logger.LogInformation("User created a new account with password.");
string userId = await UserManager.GetUserIdAsync(user);
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
string callbackUrl = NavigationManager.GetUriWithQueryParameters(NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri,
new Dictionary<string, object?>
{
["userId"] = userId,
["code"] = code,
["returnUrl"] = ReturnUrl
});
await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl));
if(UserManager.Options.SignIn.RequireConfirmedAccount)
{
RedirectManager.RedirectTo("Account/RegisterConfirmation",
new Dictionary<string, object?>
{
["email"] = Input.Email,
["returnUrl"] = ReturnUrl
});
}
await SignInManager.SignInAsync(user, false);
RedirectManager.RedirectTo(ReturnUrl);
}
private IdentityUser CreateUser()
{
try
{
return Activator.CreateInstance<IdentityUser>();
}
catch
{
throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " + $"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor.");
}
}
private IUserEmailStore<IdentityUser> GetEmailStore()
{
if(!UserManager.SupportsUserEmail)
{
throw new NotSupportedException("The default UI requires a user store with email support.");
}
return (IUserEmailStore<IdentityUser>)UserStore;
}
private sealed class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; } = "";
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; } = "";
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; } = "";
}
}

View File

@@ -1,73 +0,0 @@
@page "/Account/RegisterConfirmation"
@using System.Text
@using Microsoft.AspNetCore.Identity
@using Microsoft.AspNetCore.WebUtilities
@inject UserManager<IdentityUser> UserManager
@inject IEmailSender<IdentityUser> EmailSender
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager
<PageTitle>Register confirmation</PageTitle>
<h1>Register confirmation</h1>
<StatusMessage Message="@statusMessage"/>
@if(emailConfirmationLink is not null)
{
<p>
This app does not currently have a real email sender registered, see <a href="https://aka.ms/aspaccountconf">these docs</a> for how to configure a real email sender.
Normally this would be emailed: <a href="@emailConfirmationLink">Click here to confirm your account</a>
</p>
}
else
{
<p>Please check your email to confirm your account.</p>
}
@code {
private string? emailConfirmationLink;
private string? statusMessage;
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
[SupplyParameterFromQuery]
private string? Email { get; set; }
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
protected override async Task OnInitializedAsync()
{
if(Email is null)
{
RedirectManager.RedirectTo("");
}
IdentityUser? user = await UserManager.FindByEmailAsync(Email);
if(user is null)
{
HttpContext.Response.StatusCode = StatusCodes.Status404NotFound;
statusMessage = "Error finding user for unspecified email";
}
else if(EmailSender is IdentityNoOpEmailSender)
{
// Once you add a real email sender, you should remove this code that lets you confirm the account
string userId = await UserManager.GetUserIdAsync(user);
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
emailConfirmationLink = NavigationManager.GetUriWithQueryParameters(NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri,
new Dictionary<string, object?>
{
["userId"] = userId,
["code"] = code,
["returnUrl"] = ReturnUrl
});
}
}
}

View File

@@ -52,11 +52,6 @@
</div>
</Authorized>
<NotAuthorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Account/Register">
<span aria-hidden="true" class="bi bi-person-nav-menu"></span> Register
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Account/Login">
<span aria-hidden="true" class="bi bi-person-badge-nav-menu"></span> Login

View File

@@ -8,8 +8,8 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Sentry.OpenTelemetry;
using Serilog;
using Serilog.Events;
@@ -114,12 +114,13 @@ builder.Services.AddOpenTelemetry()
.AddHttpClientInstrumentation() // <-- Adds HttpClient telemetry sources
.AddSentry() // <-- Configure OpenTelemetry to send trace information to Sentry
)
.WithMetrics(metricsProviderBuilder =>
metricsProviderBuilder
.WithMetrics(metricsProviderBuilder => metricsProviderBuilder
.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService(
serviceName: "Aaru.Server",
serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString() ?? "unknown"))
.AddService("Aaru.Server",
serviceVersion:
typeof(Program).Assembly.GetName()
.Version?.ToString() ??
"unknown"))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation()
@@ -176,8 +177,22 @@ builder.Services.AddControllers();
builder.Services.AddHostedService<UpdateTask>();
WebApplication app = builder.Build();
// Block registration route and redirect
app.Use(async (context, next) =>
{
if(context.Request.Path.StartsWithSegments("/Account/Register", StringComparison.OrdinalIgnoreCase))
{
context.Response.Redirect("/Account/Login");
return;
}
await next();
});
// Configure the HTTP request pipeline.
if(app.Environment.IsDevelopment())
app.UseMigrationsEndPoint();