Switch to signed cookie auth and stop leaking player IDs

This commit is contained in:
2026-02-05 16:28:22 +01:00
parent 67453d0756
commit a6265e8656
12 changed files with 100 additions and 84 deletions

View File

@@ -3,6 +3,7 @@ using GameList.Data;
using GameList.Domain;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
namespace GameList.Endpoints;
@@ -10,12 +11,24 @@ internal static class EndpointHelpers
{
public static async Task<Player?> GetAuthenticatedPlayer(HttpContext ctx, AppDbContext db)
{
if (!ctx.Items.TryGetValue(Infrastructure.PlayerIdentityExtensions.PlayerCookieName, out var value) || value is not Guid playerId)
if (ctx?.User?.Identity?.IsAuthenticated != true)
{
return null;
}
var idValue = ctx.User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(idValue) || !Guid.TryParse(idValue, out var playerId))
{
// Auth cookie is present but malformed; clear and reject.
await Infrastructure.PlayerIdentityExtensions.SignOutPlayerAsync(ctx);
return null;
}
var existing = await db.Players.FindAsync(playerId);
if (existing is null)
{
await Infrastructure.PlayerIdentityExtensions.SignOutPlayerAsync(ctx);
}
return existing;
}
@@ -43,7 +56,11 @@ internal static class EndpointHelpers
player.VotesFinal = false;
}
await db.SaveChangesAsync();
var changed = db.ChangeTracker.HasChanges();
if (changed)
{
await db.SaveChangesAsync();
}
return player.CurrentPhase;
}
@@ -152,8 +169,7 @@ internal static class EndpointHelpers
var player = await GetAuthenticatedPlayer(ctx, db);
if (player?.IsAdmin == true) return true;
var provided = ctx.Request.Headers["X-Admin-Key"].FirstOrDefault()
?? ctx.Request.Query["key"].FirstOrDefault();
var provided = ctx.Request.Headers["X-Admin-Key"].FirstOrDefault();
var expected = config["ADMIN_PASSWORD"];
return !string.IsNullOrWhiteSpace(expected) && provided == expected;
}