Add game-scoped user-profile and permission queries for Head Admin team management - #867
Conversation
Co-authored-by: frasermolyneux <34033625+frasermolyneux@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
There are compatibility/performance concerns (public interface source-breaking for implementers and a potentially unbounded IN expansion in the permissions report query) that should be addressed before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR extends the V1 user-profile and permissions-report endpoints to support game-scoped filtering, enabling portal-web to build per-game Head Admin management views without client-side filtering and to correctly include server-scoped permission claims tied to a game via server GUIDs.
Changes:
- Added an optional
gameTypequery parameter toGET /v1.0/user-profiles(API, abstractions, typed client, and testing fake), with same-claim game scoping for game-based role filters. - Enhanced
GetPermissionsReport(gameType, claimType)to include both game-scoped claims and server-scoped claims whose server IDs belong to the requested game. - Added/extended unit, typed-client, fake-behavior, and V1 HTTP integration tests to cover composition, pagination metadata, and inclusion/exclusion rules.
File summaries
| File | Description |
|---|---|
| src/XtremeIdiots.Portal.Repository.Api.V1/Controllers/V1/UserProfileController.cs | Adds gameType-aware filtering for user profiles and expands permissions report to include server-scoped claims for servers in the requested game. |
| src/XtremeIdiots.Portal.Repository.Api.Tests.V1/Controllers/V1/UserProfileControllerTests.cs | Adds unit tests covering same-claim semantics, pagination/count correctness, and permissions-report inclusion/exclusion. |
| src/XtremeIdiots.Portal.Repository.Api.IntegrationTests.V1/UserProfilesTests.cs | Adds HTTP integration tests for /user-profiles and /permissions-report with gameType, asserting payloads and pagination. |
| src/XtremeIdiots.Portal.Repository.Api.Client.V1/Api/V1/UserProfileApi.cs | Adds an overload that emits gameType as a query parameter when provided. |
| src/XtremeIdiots.Portal.Repository.Api.Client.Tests.V1/UserProfileApiQuerySerializationTests.cs | Verifies typed-client query serialization behavior for gameType (present/absent) and legacy overload behavior. |
| src/XtremeIdiots.Portal.Repository.Api.Client.Testing/Fakes/FakeUserProfileApi.cs | Implements real filter/search/order/pagination semantics including the new game-scoped role filtering. |
| src/XtremeIdiots.Portal.Repository.Api.Client.Testing.Tests/FakeUserProfileApiTests.cs | Adds behavioral tests for fake filtering and pagination semantics. |
| src/XtremeIdiots.Portal.Repository.Abstractions.V1/Interfaces/V1/IUserProfileApi.cs | Extends the public V1 interface surface with a new GetUserProfiles(..., GameType? gameType, ...) overload. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
⛔ Superseded — A newer run has replaced this result.🏗️ Terraform Plan
✅ Validate — Passed ✅ Plan
|
Co-authored-by: frasermolyneux <34033625+frasermolyneux@users.noreply.github.com>
Head branch was pushed to by a user without write access
|
🏗️ Terraform Plan
✅ Validate — Passed ✅ Plan
|



GET /v1/user-profilescould filter moderators/admins by role claim but not by a specificGameType, forcingportal-webto fetch and filter in memory to build a per-game Head Admin management view.GetPermissionsReportalso only matched game-scoped claim values, silently dropping server-scoped additional permissions that belong to a game via their game-server GUID.Game-scoped user-profile filtering
GetUserProfilesoverload (IUserProfileApi, controller, typed V1 client,FakeUserProfileApi) accepting an optionalGameType? gameType; existing 6-arg callers are unaffected.HeadAdmins/GameAdmins/Moderatorsnow filterClaimType == role && ClaimValue == gameType, so an unrelated additional permission on another game no longer leaks a profile into the wrong game's list.AnyAdminkeepsWebmaster/SeniorAdminglobal while requiring game-scoped roles to match the requested game.GameType.Unknownis treated as no game filter (consistent with existingGetPermissionsReportbehavior).filteredCount, ordering,Skip/Take, so pagination metadata reflects the game-scoped result set.FakeUserProfileApinow implements real filter/search/order/pagination semantics instead of a stub.Game-filtered permissions report
GetPermissionsReport(gameType, claimType)now includes both game-scoped claims (ClaimValue == gameType) and server-scoped claims whoseClaimValueresolves to aGameServerbelonging to that game, via a small bounded server-ID lookup (no full table/claim scan).Tests
UserProfileControllerTestswith same-claim matching, exclusion, multi-game, search+pagination composition, andAnyAdmin/Unknownsemantics cases.gameTypeis only emitted when supplied.FakeUserProfileApibehavioral tests.