Include granular_scopes in impersonation token API responses

Summary

Admins can create impersonation tokens with granular_scopes, but the API never returns those scopes. Create, list and show responses omit granular_scopes, so a granular impersonation token cannot be inspected through the API.

Affected endpoints

  • POST /users/:user_id/impersonation_tokens - lib/api/users.rb:1254. Accepts granular_scopes (mutually_exclusive with scopes, admin only) but presents with ImpersonationTokenWithToken and no options.
  • GET /users/:user_id/impersonation_tokens - lib/api/users.rb:1220. Presents with ImpersonationToken and no options.
  • GET /users/:user_id/impersonation_tokens/:impersonation_token_id - lib/api/users.rb:1281. Presents with ImpersonationToken and no options.

Cause

API::Entities::PersonalAccessToken (lib/api/entities/personal_access_token.rb:25-27) exposes granular_scopes only when token.granular? && options[:with_granular_scopes]. ImpersonationToken and ImpersonationTokenWithToken inherit from it. The endpoints above present without the option, so the field is never rendered.

Verified on master by rendering each entity for a granular token in a development console: no granular_scopes key without the option, present with it.

Proposed fix

Follow the pattern used by GET /personal_access_tokens, GET /personal_access_tokens/:id and POST /personal_access_tokens/:id/rotate (lib/api/personal_access_tokens.rb:44,69,103, added by !243754 (merged)):

  • Preload granular_scopes: :namespace.
  • Present with with_granular_scopes: true and project_ids_by_namespace_id: project_ids_by_namespace_id_for([token]) (helper in lib/api/helpers/personal_access_tokens_helpers.rb).

For the list route, apply the preload to the paginated relation to avoid N+1, as the PAT list route does with .preload_granular_scopes, and compute project_ids_by_namespace_id for the page.

!259764 (merged) applies the same pattern to GET /personal_access_tokens/self and is a good model, including specs.

The change is additive: the field only appears for granular tokens. Update the matching API docs page for each endpoint.

Acceptance criteria

  • Create, list and show return granular_scopes for granular impersonation tokens.
  • Legacy token responses are unchanged and run no granular_scopes query.
  • A project-scoped granular scope resolves project_id.
  • An N+1 spec covers the list route.
  • API docs are updated for each endpoint.

References