Return userPermissions to fine-grained tokens for namespaces and users
What does this MR do and why?
ProjectPermissions, GroupPermissions, NamespacePermissions, UserPermissions, GroupMemberPermissions and OrganizationUserPermissions have no authorize_granular_token directive, so they are denied to fine-grained tokens. userPermissions is non-nullable, so a token with read_project that selects it gets Cannot return null for non-nullable field Project.userPermissions and a null project.
Each is only reachable through userPermissions on a parent that authorizes the token:
| Type | Parents |
|---|---|
ProjectPermissions |
Project (read_project), ProjectMember (read_member) |
GroupPermissions |
Group (read_group) |
NamespacePermissions |
Namespace (read_namespace) |
UserPermissions |
UserCore and the types built on it (read_user) |
GroupMemberPermissions |
GroupMember (read_member) |
OrganizationUserPermissions |
OrganizationUser (read_organization_user) |
This MR gives them skip_reason: :parent_authorizes, as CustomEmojiPermissions has, removes them from authorization_todo.txt, and adds a request spec per parent type with the skipped child type shared examples. For the user types that means UserCore and CurrentUser: the others built on UserType inherit its read_user directive and its userPermissions field. ProjectMinimalAccess and GroupMinimalAccess also expose two of them, but are still listed and keep refusing these tokens.
Would you prefer one skip on BasePermissionType? It would also cover the permission types still listed.
References
- Related to #593878, the GraphQL gaps for fine-grained tokens.
- !260586 (merged) gave
CustomEmojiPermissionsthe same skip.
I found this while working on gitlab-mcp-server.
Screenshots or screen recordings
Not applicable.
How to set up and validate locally
- Create a fine-grained token for a private project with
read_project(Step 7 ofdoc/development/permissions/granular_access/graphql_implementation_guide.md). - Send
{ project(fullPath: "<project>") { name userPermissions { readProject } } }to/api/graphqlwith it. - On master
projectisnullwith the error above. On this branch it returnsuserPermissions.
I ran steps 2 and 3 as a request spec: the new example in spec/requests/api/graphql/project_query_spec.rb whose fine-grained token holds read_project posts the same query, without name, to /api/graphql. On master's code it gets that error, and on this branch userPermissions with no error.
Checks I ran (Ruby 3.3.11)
- On master's code, the new examples give 16 examples, 8 failures, each
Cannot return null for non-nullable field <Parent>.userPermissions. - On this branch, the eight request specs and the type specs of the six permission types: 306 examples, 0 failures, 11 pending (all already pending on master).
gitlab:permissions:validatepasses andcompile_docschanges nothing. RuboCop and the commit linter: no findings.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.