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.haml — restricted_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/settingsrequires an administrator (API::Settingshas a blanketauthenticated_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.gitpodEnabledprecedent directly above it inquery_type.rb: a single application setting read fromGitlab::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 restrictedpubliclevel hides user profiles from logged-out visitors). VisibilityLevelsEnumalready serializes asprivate/internal/public, so no new type is introduced.- A
nilsetting (no restrictions configured) is returned as[].
How to set up and validate locally
-
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])). -
Run in GraphiQL as any non-admin (or signed-out) user:
{ restrictedVisibilityLevels } -
Expect
["internal"]; clear the setting and expect[].
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist.