Return namespace markdown paths to fine-grained tokens

What does this MR do and why?

A fine-grained personal access token that can read a namespace gets null from markdownPaths, because its three types declare no authorize_granular_token directive. Their parent already checks the token, so each type now declares parent_authorizes: :read_namespace and leaves authorization_todo.txt:

Types Returned by Token checked at
GroupNamespaceMarkdownPaths, ProjectNamespaceMarkdownPaths, UserNamespaceMarkdownPaths Namespace.markdownPaths read_namespace on the group, project or user
GroupNamespaceMarkdownPaths Group.markdownPaths read_group and read_namespace on the group

The three types share the MarkdownPaths interface, so they declare one permission, and read_group cannot be checked on a project. Through group, markdownPaths therefore needs Namespace: Read as well as Group: Read.

The checks for the user stay as they are.

Why three types stay on the list

GroupNamespaceMetadata, GroupNamespaceLinks and ProjectNamespaceLinks stay on the list: hasProjects runs GroupProjectsFinder as the user, and the links return the user's notification email, RSS and calendar paths with a token derived from the user's feed token, and, for projects, an email address with the user's incoming email token.

This MR no longer changes ProjectNamespaceMetadata, UserNamespaceMetadata and UserNamespaceLinks, which stay on the list for a later MR: since !266839 (merged), gitlab:permissions:validate wants every type of the NamespaceMetadata and NamespacesLinkPaths interfaces to declare the same permission, and both interfaces also have types that stay on the list.

One domain, groups and namespaces, and one pattern, as suggested in !267273 (comment 4150389469).

References

  • Part of #638957, the Organizations GraphQL types for fine-grained tokens.
  • Related to #593878, the GraphQL gaps for fine-grained tokens.
  • !267320 (merged) did the same for NamespacePlan and GroupStats.

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 group with a private project, create a fine-grained token with Namespace: Read for the project, and run:

    query {
      namespace(fullPath: "<group>/<project>") {
        markdownPaths { uploadsPath }
      }
    }
  2. On master markdownPaths is null; on this branch it returns the project's uploads path.

  3. With a token with Group: Read for the group, group(fullPath: "<group>") { markdownPaths { uploadsPath } } returns the group with markdownPaths set to null. Add Namespace: Read to the token: it now returns the group's uploads path.

I ran these steps as examples of namespace_query_spec.rb and group_query_spec.rb, which also cover a group and a personal namespace through namespace.

Checks I ran (Ruby 3.3.11)
  • With the parent's permission and read_namespace, the paths are null on master's code and return data on this branch; without them they stay null; through group, a token with read_group alone gets the group without the paths.
  • With master's types and todo list, the examples this MR adds give 9 examples, 4 failures: every example that expects the paths fails.
  • On this branch, the two changed specs and the markdown paths type specs: 123 examples, 0 failures, and the 3 pending examples master already has.
  • gitlab:permissions:validate (with both documentation checks), RuboCop and the commit linter pass, and with skip_reason: :parent_authorizes instead the task fails on the three types; the compile_docs tasks change 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.

Edited by José M. Requena Plens

Merge request reports

Loading
Loading