Ajoute une page utilisateur et une persistance MySQL

This commit is contained in:
2026-04-14 20:03:26 +02:00
parent d0f9c76b26
commit 5cf46dce31
14 changed files with 1106 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
using System.Security.Claims;
using ChessCubing.Server.Auth;
using ChessCubing.Server.Data;
using ChessCubing.Server.Users;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
@@ -17,6 +19,20 @@ builder.Services.AddOptions<KeycloakAuthOptions>()
options.AdminPassword = configuration["KEYCLOAK_ADMIN_PASSWORD"] ?? options.AdminPassword;
});
builder.Services.AddOptions<SiteDataOptions>()
.Configure<IConfiguration>((options, configuration) =>
{
options.Host = configuration["SITE_DB_HOST"] ?? options.Host;
options.Database = configuration["SITE_DB_NAME"] ?? options.Database;
options.Username = configuration["SITE_DB_USER"] ?? options.Username;
options.Password = configuration["SITE_DB_PASSWORD"] ?? options.Password;
if (int.TryParse(configuration["SITE_DB_PORT"], out var port) && port > 0)
{
options.Port = port;
}
});
builder.Services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
@@ -44,9 +60,16 @@ builder.Services
builder.Services.AddAuthorization();
builder.Services.AddHttpClient<KeycloakAuthService>();
builder.Services.AddSingleton<MySqlUserProfileStore>();
var app = builder.Build();
await using (var scope = app.Services.CreateAsyncScope())
{
var profileStore = scope.ServiceProvider.GetRequiredService<MySqlUserProfileStore>();
await profileStore.InitializeAsync(CancellationToken.None);
}
app.UseAuthentication();
app.UseAuthorization();
@@ -55,6 +78,44 @@ app.MapGet("/api/health", () => TypedResults.Ok(new { status = "ok" }));
app.MapGet("/api/auth/session", (ClaimsPrincipal user) =>
TypedResults.Ok(AuthSessionResponse.FromUser(user)));
app.MapGet("/api/users/me", async Task<IResult> (
ClaimsPrincipal user,
MySqlUserProfileStore profileStore,
CancellationToken cancellationToken) =>
{
var siteUser = AuthenticatedSiteUserFactory.FromClaimsPrincipal(user);
if (siteUser is null)
{
return TypedResults.BadRequest(new ApiErrorResponse("La session utilisateur est incomplete."));
}
var profile = await profileStore.GetOrCreateAsync(siteUser, cancellationToken);
return TypedResults.Ok(profile);
}).RequireAuthorization();
app.MapPut("/api/users/me", async Task<IResult> (
UpdateUserProfileRequest request,
ClaimsPrincipal user,
MySqlUserProfileStore profileStore,
CancellationToken cancellationToken) =>
{
var siteUser = AuthenticatedSiteUserFactory.FromClaimsPrincipal(user);
if (siteUser is null)
{
return TypedResults.BadRequest(new ApiErrorResponse("La session utilisateur est incomplete."));
}
try
{
var profile = await profileStore.UpdateAsync(siteUser, request, cancellationToken);
return TypedResults.Ok(profile);
}
catch (UserProfileValidationException exception)
{
return TypedResults.BadRequest(new ApiErrorResponse(exception.Message));
}
}).RequireAuthorization();
app.MapPost("/api/auth/login", async Task<IResult> (
LoginRequest request,
HttpContext httpContext,