Expose restricted visibility levels via GraphQL

What does this MR do and why?

Adds a restrictedVisibilityLevels field to the GraphQL Query root, returning the instance's restricted_visibility_levels application setting as [VisibilityLevelsEnum!].

{ restrictedVisibilityLevels }
{ "data": { "restrictedVisibilityLevels": ["internal"] } }

Why

This MR does not change what is visible to users — only how easily accessible and documented it is. The setting's value is already delivered to users directly, JSON-encoded, in server-rendered page HTML: the fork page embeds it as a data-restricted-visibility-levels attribute on its mount element (app/views/projects/forks/new.html.hamlrestricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json), and the new-project form receives it the same way, which is how those forms know to disable restricted radio options. Any signed-in user can read it out of the page source today — for example, opening https://gitlab.com/gitlab-org/gitlab/-/forks/new and viewing the page source shows the JSON-encoded value in the mount element:

<div id="fork-groups-mount-element" data-restricted-visibility-levels="[10]" ...>

(10 = internal, the level GitLab.com restricts). What is missing is a stable, documented way to read the same value programmatically:

  • GET /api/v4/application/settings requires an administrator (API::Settings has a blanket authenticated_as_admin!).
  • The value is not exposed anywhere in GraphQL.

Non-browser clients (mobile apps, CLI tools, integrations) therefore cannot tell which visibility levels are actually available when creating or forking a project. Worse, they cannot even detect the restriction after the fact through an error: Projects::ForkService#target_visibility_level runs the requested level through Gitlab::VisibilityLevel.closest_allowed_level, which silently downgrades a restricted level (for example, requesting internal on GitLab.com quietly creates a private fork).

With this field, a client can mirror exactly what the Web fork/new-project forms do: fetch the restricted set once and disable those options up front.

Implementation notes

  • The field follows the Query.gitpodEnabled precedent directly above it in query_type.rb: a single application setting read from Gitlab::CurrentSettings, no authorization gate. The value is not sensitive — as described above, it is already disclosed to every signed-in user in page HTML, and it shapes anonymous-facing behavior too (a restricted public level hides user profiles from logged-out visitors).
  • VisibilityLevelsEnum already serializes as private / internal / public, so no new type is introduced.
  • A nil setting (no restrictions configured) is returned as [].

How to set up and validate locally

  1. In the Admin Area, set Settings → General → Visibility and access controls → Restricted visibility levels to, for example, Internal (or in the Rails console: ApplicationSetting.current.update!(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])).

  2. Run in GraphiQL as any non-admin (or signed-out) user:

    { restrictedVisibilityLevels }
  3. Expect ["internal"]; clear the setting and expect [].

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist.

Edited by Marcel van Remmerden

Merge request reports

Loading
Loading