Skip to content

🐛 fix: cannot get project list by access tokens#878

Merged
deleteLater merged 8 commits intomainfrom
fix/only-return-user-accessible-envs
Mar 17, 2026
Merged

🐛 fix: cannot get project list by access tokens#878
deleteLater merged 8 commits intomainfrom
fix/only-return-user-accessible-envs

Conversation

@deleteLater
Copy link
Copy Markdown
Contributor

@deleteLater deleteLater commented Mar 16, 2026

  1. cannot get project list by access token
  2. filter out user-inaccessible environment when get project
  3. should return project even if it has no accessible environments

@deleteLater deleteLater self-assigned this Mar 16, 2026
@deleteLater deleteLater added bug Something isn't working api labels Mar 16, 2026
@deleteLater deleteLater moved this to In Progress in FeatBit Mar 16, 2026
@deleteLater deleteLater changed the title 🐛 fix: can get user-inaccessible environments by OpenAPI 🐛 fix: cannot get project list by access tokens Mar 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes project retrieval via access tokens by centralizing request permission resolution and using those permissions to filter returned projects/environments (and to deny access when appropriate).

Changes:

  • Switched permissions shapes from IEnumerable<PolicyStatement> to PolicyStatement[] across access tokens and member permission retrieval.
  • Added scoped IRequestPermissions service to resolve/cached request permissions for both JWT users and OpenAPI access tokens, and wired it into authorization + controllers.
  • Updated project “get” and “list” flows to filter environments based on the resolved permissions and return 403 via a new ForbiddenException path.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
modules/back-end/src/Infrastructure/Services/MongoDb/MemberService.cs Return permissions as PolicyStatement[] (materialized).
modules/back-end/src/Infrastructure/Services/EntityFrameworkCore/MemberService.cs Same as above for EF Core implementation.
modules/back-end/src/Domain/AccessTokens/AccessToken.cs Store token permissions as PolicyStatement[] (better for persistence/serialization).
modules/back-end/src/Application/Services/IMemberService.cs Updated signature to return PolicyStatement[].
modules/back-end/src/Application/Projects/GetProjectList.cs Accept request permissions and filter projects/envs based on them.
modules/back-end/src/Application/Projects/GetProject.cs Enforce project access and filter returned environments based on permissions.
modules/back-end/src/Application/Bases/Exceptions/ForbiddenException.cs New exception used to signal 403 from application layer.
modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs Updated permissions type to array and adjusted validation predicate.
modules/back-end/src/Api/Setup/ServicesRegister.cs Registers IRequestPermissions as a scoped service.
modules/back-end/src/Api/Middlewares/ApiExceptionMiddlewareExtension.cs Maps ForbiddenException to HTTP 403 + ErrorCodes.Forbidden.
modules/back-end/src/Api/Controllers/ProjectController.cs Fetches request permissions and passes them into MediatR requests.
modules/back-end/src/Api/Controllers/ApiControllerBase.cs Adds helper to retrieve PolicyStatement[] via IRequestPermissions.
modules/back-end/src/Api/Authorization/RequestPermissions.cs Implements permission resolution for JWT vs OpenAPI access tokens (with request-scope caching).
modules/back-end/src/Api/Authorization/IRequestPermissions.cs New interface for request permission resolution.
modules/back-end/src/Api/Authorization/DefaultPermissionChecker.cs Now consumes IRequestPermissions instead of duplicating resolution logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes authorization behavior for project listing when authenticated via OpenApi access tokens, and adds env-level filtering based on the current request’s permissions.

Changes:

  • Introduce a scoped IRequestPermissions service to resolve/cache PolicyStatement[] for the current request (JWT user vs OpenApi access token).
  • Pass resolved permissions into GetProjectList/GetProject handlers and filter out inaccessible projects/environments.
  • Add a ForbiddenException and map it to a 403 response in the API exception middleware.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
modules/back-end/src/Infrastructure/Services/MongoDb/MemberService.cs Change permissions return type to PolicyStatement[] and materialize statements.
modules/back-end/src/Infrastructure/Services/EntityFrameworkCore/MemberService.cs Change permissions return type to PolicyStatement[] and materialize statements.
modules/back-end/src/Domain/AccessTokens/AccessToken.cs Change Permissions to PolicyStatement[] on the domain entity.
modules/back-end/src/Application/Services/IMemberService.cs Update GetPermissionsAsync signature to return PolicyStatement[].
modules/back-end/src/Application/Projects/GetProjectList.cs Remove ICurrentUser dependency; filter projects/envs using request-provided permissions.
modules/back-end/src/Application/Projects/GetProject.cs Enforce project permission + filter environments using request-provided permissions.
modules/back-end/src/Application/Bases/Exceptions/ForbiddenException.cs Add a dedicated exception type for 403 flows.
modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs Change request Permissions to PolicyStatement[] and adjust validation.
modules/back-end/src/Api/Setup/ServicesRegister.cs Register IRequestPermissions as scoped.
modules/back-end/src/Api/Middlewares/ApiExceptionMiddlewareExtension.cs Map ForbiddenException to a 403 response with ErrorCodes.Forbidden.
modules/back-end/src/Api/Controllers/ProjectController.cs Resolve request permissions and pass into project queries; remove action-level permission attribute on Get-by-id.
modules/back-end/src/Api/Controllers/ApiControllerBase.cs Add helper to resolve request permissions via DI.
modules/back-end/src/Api/Authorization/RequestPermissions.cs New service resolving permissions based on auth scheme and caching per request.
modules/back-end/src/Api/Authorization/IRequestPermissions.cs New interface for request-scoped permission resolution.
modules/back-end/src/Api/Authorization/DefaultPermissionChecker.cs Refactor to use IRequestPermissions instead of duplicating resolution logic.
Comments suppressed due to low confidence (1)

modules/back-end/src/Domain/AccessTokens/AccessToken.cs:36

  • AccessToken.Permissions is now a non-nullable array, but it can still be null at runtime (e.g., existing rows/documents with a missing/NULL Permissions field, or personal tokens created without permissions). This can later cause 500s when code assumes an enumerable (e.g., permission checks). Consider default-initializing the property (e.g., empty array) and/or normalizing permissions to an empty array in the constructor to enforce a non-null invariant.
    public PolicyStatement[] Permissions { get; set; }

    public DateTime? LastUsedAt { get; set; }

    public AccessToken(
        Guid organizationId,
        Guid creatorId,
        string name,
        string type,
        PolicyStatement[] permissions)
    {
        OrganizationId = organizationId;
        CreatorId = creatorId;
        Name = name;

        Status = AccessTokenStatus.Active;
        Type = type;
        Permissions = permissions;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes project retrieval/listing when authenticated via OpenAPI access tokens by resolving permissions from the current request context (instead of ICurrentUser), filtering inaccessible environments, and ensuring projects still appear even when no environments are accessible.

Changes:

  • Standardize permissions payloads to PolicyStatement[] (member permissions + access token stored permissions) to avoid serialization/materialization issues.
  • Introduce IRequestPermissions/RequestPermissions (scoped) and reuse it in DefaultPermissionChecker and controllers to obtain per-request permissions for both JWT and OpenAPI schemes.
  • Filter environments by permission in GetProject/GetProjectList, and return projects even when the accessible env list is empty; add a dedicated ForbiddenException mapped to HTTP 403.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
modules/back-end/src/Infrastructure/Services/MongoDb/MemberService.cs Return permissions as PolicyStatement[] to provide a concrete, materialized collection.
modules/back-end/src/Infrastructure/Services/EntityFrameworkCore/MemberService.cs Same as Mongo: return a materialized PolicyStatement[].
modules/back-end/src/Domain/AccessTokens/AccessToken.cs Change stored token permissions to PolicyStatement[] to support persistence/materialization.
modules/back-end/src/Application/Services/IMemberService.cs Update contract to return PolicyStatement[] for permissions.
modules/back-end/src/Application/Projects/GetProjectList.cs Use request-provided permissions to filter projects/envs; keep projects even with zero accessible envs.
modules/back-end/src/Application/Projects/GetProject.cs Enforce project access + filter envs based on request permissions; throw ForbiddenException when disallowed.
modules/back-end/src/Application/Bases/Exceptions/ForbiddenException.cs Add a dedicated exception to represent forbidden access at the application layer.
modules/back-end/src/Application/AccessTokens/CreateAccessToken.cs Store permissions as an array and validate permissions presence/emptiness for non-personal tokens.
modules/back-end/src/Api/Setup/ServicesRegister.cs Register IRequestPermissions as scoped for per-request permission resolution.
modules/back-end/src/Api/Middlewares/ApiExceptionMiddlewareExtension.cs Map ForbiddenException to HTTP 403 with ErrorCodes.Forbidden.
modules/back-end/src/Api/Controllers/ProjectController.cs Pass per-request permissions into project queries to support access-token auth and env filtering.
modules/back-end/src/Api/Controllers/ApiControllerBase.cs Add GetRequestPermissionsAsync() helper to fetch request permissions via DI.
modules/back-end/src/Api/Authorization/RequestPermissions.cs New scoped service computing permissions for JWT vs OpenAPI access token requests.
modules/back-end/src/Api/Authorization/IRequestPermissions.cs New interface for request-scoped permission resolution.
modules/back-end/src/Api/Authorization/DefaultPermissionChecker.cs Consume IRequestPermissions instead of duplicating permission-resolution logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@deleteLater deleteLater moved this from In Progress to PR Ready in FeatBit Mar 17, 2026
Copy link
Copy Markdown
Contributor

@cosmos-explorer cosmos-explorer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@deleteLater deleteLater merged commit 3f71ba1 into main Mar 17, 2026
5 checks passed
@github-project-automation github-project-automation bot moved this from PR Ready to Done in FeatBit Mar 17, 2026
@deleteLater deleteLater deleted the fix/only-return-user-accessible-envs branch March 17, 2026 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants