Return namespace plan, group stats and bans to fine-grained tokens

What does this MR do and why?

A fine-grained personal access token gets null for the fields below, even when it can read the group or remove the ban, because their types declare no authorize_granular_token directive. Each type is returned only by these fields, whose parent already authorizes the token, so each now declares skip_reason: :parent_authorizes and leaves authorization_todo.txt:

Type Returned only by Token checked at
NamespacePlan Namespace.plan, inherited by Group Namespace, read_namespace; Group, read_group
GroupStats Group.stats Group, read_group
NamespaceBan NamespaceBanDestroyPayload.namespaceBan NamespaceBanDestroy, delete_namespace_ban

The checks for the user stay: admin_namespace on plan, read_group on GroupStats and unban_group_member on the mutation.

GroupReleaseStats (GroupStats.releaseStats) stays on the list: it needs a release permission of its own. TargetedMessage is left to #636861, which plans to remove it in 19.7.

If !266839 (merged) lands first, I will add parent_permissions: [:read_namespace, :read_group] to NamespacePlan, like NamespaceAvailableFeatures there.

References

  • Related to #593878, the GraphQL gaps for fine-grained tokens.
  • !252874 (merged) gave the MLOps child types the same annotation.

I found this while working on gitlab-mcp-server.

Screenshots or screen recordings

No UI change.

How to set up and validate locally

  1. In a private top-level group you own, create a fine-grained token with Group: Read and Namespace: Read for it, and run:

    query {
      group(fullPath: "<group>") { plan { name } stats { __typename } }
      namespace(fullPath: "<group>") { plan { name } }
    }
  2. On master plan and stats are null; on this branch they return data.

  3. Ban a user in the Rails console (Namespaces::NamespaceBan.create!(namespace: group, user: other_user)), then run mutation { namespaceBanDestroy(input: { id: "<ban global ID>" }) { namespaceBan { id } } } with a token that has Namespace Ban: Delete: namespaceBan is null on master and the removed ban on this branch.

I ran steps 1 to 3 as the new examples of the EE request specs group_query_spec.rb, namespace_query_spec.rb and namespace_bans/destroy_spec.rb: with a fine-grained token holding the parent's permission, the fields are null on master's code and return data on this branch.

Checks I ran (Ruby 3.3.11)
  • With master's types and todo list, the new examples give 7 examples, 4 failures: every example that expects data fails.
  • Putting back any one type file from master fails only the examples that read that type.
  • On this branch, the three changed specs and the GroupStats and NamespacePlan type specs: 49 examples, 0 failures.
  • gitlab:permissions:validate, RuboCop and the commit linter pass; gitlab:permissions:graphql:compile_docs changes nothing. Left to the pipeline: Ruby 3.4.10 and the FOSS run.

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.

Merge request reports

Loading
Loading