From ffbf4aa05a5dfb533601b5311556467982d0cc47 Mon Sep 17 00:00:00 2001 From: Frank Tovar Date: Thu, 5 Feb 2026 17:13:09 +0100 Subject: [PATCH] Add phase requirement filter for vote/results endpoints --- Endpoints/ResultsEndpoints.cs | 5 +++- Endpoints/VoteEndpoints.cs | 5 +++- Infrastructure/PhaseRequirementFilter.cs | 31 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 Infrastructure/PhaseRequirementFilter.cs diff --git a/Endpoints/ResultsEndpoints.cs b/Endpoints/ResultsEndpoints.cs index c418ede..7af6a0d 100644 --- a/Endpoints/ResultsEndpoints.cs +++ b/Endpoints/ResultsEndpoints.cs @@ -1,6 +1,7 @@ using GameList.Data; using GameList.Domain; using Microsoft.EntityFrameworkCore; +using GameList.Infrastructure; namespace GameList.Endpoints; @@ -8,7 +9,9 @@ public static class ResultsEndpoints { public static void MapResultsEndpoints(this IEndpointRouteBuilder app) { - var group = app.MapGroup("/api/results").RequireAuthorization(); + var group = app.MapGroup("/api/results") + .RequireAuthorization() + .AddEndpointFilter(new PhaseRequirementFilter(Phase.Results)); group.MapGet( "/", diff --git a/Endpoints/VoteEndpoints.cs b/Endpoints/VoteEndpoints.cs index d1b7162..5f13577 100644 --- a/Endpoints/VoteEndpoints.cs +++ b/Endpoints/VoteEndpoints.cs @@ -3,6 +3,7 @@ using GameList.Data; using GameList.Domain; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using GameList.Infrastructure; namespace GameList.Endpoints; @@ -10,7 +11,9 @@ public static class VoteEndpoints { public static void MapVoteEndpoints(this IEndpointRouteBuilder app) { - var group = app.MapGroup("/api/votes").RequireAuthorization(); + var group = app.MapGroup("/api/votes") + .RequireAuthorization() + .AddEndpointFilter(new PhaseRequirementFilter(Phase.Vote)); group.MapGet("/mine", async (HttpContext ctx, AppDbContext db) => { diff --git a/Infrastructure/PhaseRequirementFilter.cs b/Infrastructure/PhaseRequirementFilter.cs new file mode 100644 index 0000000..e9640be --- /dev/null +++ b/Infrastructure/PhaseRequirementFilter.cs @@ -0,0 +1,31 @@ +using GameList.Data; +using GameList.Domain; +using GameList.Endpoints; + +namespace GameList.Infrastructure; + +public class PhaseRequirementFilter : IEndpointFilter +{ + private readonly Phase _required; + + public PhaseRequirementFilter(Phase required) + { + _required = required; + } + + public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + var httpContext = context.HttpContext; + var db = httpContext.RequestServices.GetRequiredService(); + var player = await EndpointHelpers.GetAuthenticatedPlayer(httpContext, db); + if (player is null) return Results.Unauthorized(); + + var phase = await EndpointHelpers.GetPhase(db, player.Id); + if (phase != _required) + { + return EndpointHelpers.PhaseMismatch(_required, phase); + } + + return await next(context); + } +}