Remove admin key support; admin must be authenticated
This commit is contained in:
@@ -13,9 +13,9 @@ public static class AdminEndpoints
|
||||
{
|
||||
var admin = app.MapGroup("/api/admin");
|
||||
|
||||
admin.MapPost("/results", async ([FromBody] Contracts.ResultsOpenRequest request, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/results", async ([FromBody] Contracts.ResultsOpenRequest request, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
var state = await db.AppState.FirstAsync();
|
||||
state.ResultsOpen = request.ResultsOpen;
|
||||
@@ -36,9 +36,9 @@ public static class AdminEndpoints
|
||||
return Results.Ok(new { currentState.ResultsOpen, currentState.UpdatedAt });
|
||||
});
|
||||
|
||||
admin.MapGet("/vote-status", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapGet("/vote-status", async (HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
var voters = await db.Players
|
||||
.AsNoTracking()
|
||||
@@ -59,9 +59,9 @@ public static class AdminEndpoints
|
||||
return Results.Ok(new { voters, ready, waiting });
|
||||
});
|
||||
|
||||
admin.MapPost("/joker", async ([FromBody] GrantJokerRequest request, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/joker", async ([FromBody] GrantJokerRequest request, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
var player = await db.Players.FirstOrDefaultAsync(p => p.Id == request.PlayerId);
|
||||
if (player is null) return Results.NotFound(new { error = "Player not found." });
|
||||
|
||||
@@ -76,9 +76,9 @@ public static class AdminEndpoints
|
||||
return Results.Ok(new { player.Id, player.HasJoker });
|
||||
});
|
||||
|
||||
admin.MapDelete("/players/{playerId:guid}", async (Guid playerId, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapDelete("/players/{playerId:guid}", async (Guid playerId, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
var player = await db.Players
|
||||
.Include(p => p.Suggestions)
|
||||
@@ -111,10 +111,10 @@ public static class AdminEndpoints
|
||||
return Results.Ok(new { DeletedPlayerId = playerId });
|
||||
});
|
||||
|
||||
admin.MapPost("/link-suggestions", async ([FromBody] LinkSuggestionsRequest request, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/link-suggestions", async ([FromBody] LinkSuggestionsRequest request, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null || !await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (player is null || !await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
if (phase != Phase.Vote)
|
||||
@@ -183,10 +183,10 @@ public static class AdminEndpoints
|
||||
});
|
||||
});
|
||||
|
||||
admin.MapPost("/unlink-suggestions", async ([FromBody] UnlinkSuggestionsRequest request, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/unlink-suggestions", async ([FromBody] UnlinkSuggestionsRequest request, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null || !await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (player is null || !await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
if (phase != Phase.Vote)
|
||||
@@ -238,9 +238,9 @@ public static class AdminEndpoints
|
||||
});
|
||||
});
|
||||
|
||||
admin.MapPost("/reset", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/reset", async (HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
await db.Votes.ExecuteDeleteAsync();
|
||||
await db.Suggestions.ExecuteDeleteAsync();
|
||||
@@ -256,9 +256,9 @@ public static class AdminEndpoints
|
||||
return Results.Ok(new { Phase = Phase.Suggest, state.ResultsOpen, state.UpdatedAt });
|
||||
});
|
||||
|
||||
admin.MapPost("/factory-reset", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
admin.MapPost("/factory-reset", async (HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
||||
if (!await EndpointHelpers.IsAdmin(ctx, db)) return Results.Unauthorized();
|
||||
|
||||
await using var tx = await db.Database.BeginTransactionAsync();
|
||||
|
||||
|
||||
@@ -235,14 +235,10 @@ internal static class EndpointHelpers
|
||||
return uri.Scheme is "http" or "https";
|
||||
}
|
||||
|
||||
public static async Task<bool> IsAdmin(HttpContext ctx, AppDbContext db, IConfiguration config)
|
||||
public static async Task<bool> IsAdmin(HttpContext ctx, AppDbContext db)
|
||||
{
|
||||
var player = await GetAuthenticatedPlayer(ctx, db);
|
||||
if (player?.IsAdmin == true) return true;
|
||||
|
||||
var provided = ctx.Request.Headers["X-Admin-Key"].FirstOrDefault();
|
||||
var expected = config["ADMIN_PASSWORD"];
|
||||
return !string.IsNullOrWhiteSpace(expected) && provided == expected;
|
||||
return player?.IsAdmin == true;
|
||||
}
|
||||
|
||||
public static AppState NewAppState() => new()
|
||||
|
||||
@@ -109,11 +109,11 @@ public static class SuggestEndpoints
|
||||
return Results.Created($"/api/suggestions/{suggestion.Id}", new { suggestion.Id });
|
||||
});
|
||||
|
||||
group.MapDelete("/{id:int}", async (int id, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
||||
group.MapDelete("/{id:int}", async (int id, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null) return Results.Unauthorized();
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db, config);
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db);
|
||||
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
if (!isAdmin && phase != Phase.Suggest)
|
||||
@@ -138,10 +138,10 @@ public static class SuggestEndpoints
|
||||
return Results.NoContent();
|
||||
});
|
||||
|
||||
group.MapPut("/{id:int}", async (int id, [FromBody] SuggestionRequest request, HttpContext ctx, AppDbContext db, IConfiguration config, IHttpClientFactory http) =>
|
||||
group.MapPut("/{id:int}", async (int id, [FromBody] SuggestionRequest request, HttpContext ctx, AppDbContext db, IHttpClientFactory http) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db, config);
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db);
|
||||
|
||||
if (!isAdmin)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user