From 2ca4981a9bd4aaab91514607576ae7456fe0fcb5 Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Wed, 29 Dec 2021 18:05:02 +0100 Subject: [PATCH 1/5] Add read_group_runners permissions Replaces admin_group usage --- app/finders/ci/runners_finder.rb | 2 +- app/policies/group_policy.rb | 2 ++ lib/sidebars/groups/menus/ci_cd_menu.rb | 4 +--- spec/policies/group_policy_spec.rb | 2 ++ .../policies/group_policy_shared_context.rb | 23 ++++++++++--------- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb index a514d2e8d03434..3ebf6bd1562f4b 100644 --- a/app/finders/ci/runners_finder.rb +++ b/app/finders/ci/runners_finder.rb @@ -47,7 +47,7 @@ def all_runners end def group_runners - raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :admin_group, @group) + raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :read_group_runners, @group) @runners = case @params[:membership] when :direct diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 5c4990ffd9bd41..7b98f6b1170a1d 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -180,6 +180,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :admin_group_member enable :change_visibility_level + enable :read_group_runners + enable :set_note_created_at enable :set_emails_disabled enable :change_prevent_sharing_groups_outside_hierarchy diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb index f5bce57f496131..a1f98b918e6ce0 100644 --- a/lib/sidebars/groups/menus/ci_cd_menu.rb +++ b/lib/sidebars/groups/menus/ci_cd_menu.rb @@ -34,10 +34,8 @@ def runners_menu_item ) end - # TODO Proper policies, such as `read_group_runners`, should be implemented per - # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802 def show_runners? - can?(context.current_user, :admin_group, context.group) && + can?(context.current_user, :read_group_runners, context.group) && Feature.enabled?(:runner_list_group_view_vue_ui, context.group, default_enabled: :yaml) end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 7822ee2b92e277..3f986711f4b576 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -36,6 +36,7 @@ it { expect_disallowed(:read_crm_organization) } it { expect_disallowed(:read_crm_contact) } it { expect_disallowed(:read_counts) } + it { expect_disallowed(:read_group_runners) } it { expect_disallowed(*read_group_permissions) } end @@ -51,6 +52,7 @@ it { expect_disallowed(:read_crm_organization) } it { expect_disallowed(:read_crm_contact) } it { expect_disallowed(:read_counts) } + it { expect_disallowed(:read_group_runners) } it { expect_disallowed(*read_group_permissions) } end diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb index ad6462dc36711d..d531de417115d6 100644 --- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -53,17 +53,18 @@ end let(:owner_permissions) do - [ - :owner_access, - :admin_group, - :admin_namespace, - :admin_group_member, - :change_visibility_level, - :set_note_created_at, - :create_subgroup, - :read_statistics, - :update_default_branch_protection - ].compact + %i[ + owner_access + admin_group + admin_namespace + admin_group_member + change_visibility_level + set_note_created_at + create_subgroup + read_statistics + update_default_branch_protection + read_group_runners + ] end let(:admin_permissions) { %i[read_confidential_issues] } -- GitLab From ba148a2051b0895cbd7cde74cca4302e0aa8e89c Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Wed, 29 Dec 2021 18:11:26 +0100 Subject: [PATCH 2/5] Use new rules instead of admin_group in controller --- app/controllers/groups/application_controller.rb | 12 ++++++++++++ app/controllers/groups/runners_controller.rb | 7 +++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index ab67a007bd9f55..f9c875b80b2f2d 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -37,6 +37,18 @@ def authorize_admin_group! end end + def authorize_admin_group_runners! + unless can?(current_user, :admin_group_runners, group) + render_404 + end + end + + def authorize_read_group_runners! + unless can?(current_user, :read_group_runners, group) + render_404 + end + end + def authorize_create_deploy_token! unless can?(current_user, :create_deploy_token, group) render_404 diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index 5c21c7b023c3ad..f602d02a165cbf 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true class Groups::RunnersController < Groups::ApplicationController - # TODO Proper policies, such as `read_group_runners, should be implemented per - # https://gitlab.com/gitlab-org/gitlab/-/issues/334802 - before_action :authorize_admin_group! + before_action :authorize_read_group_runners!, only: [:index, :show] + before_action :authorize_admin_group_runners!, only: [:edit, :update, :destroy, :pause, :resume] before_action :runner_list_group_view_vue_ui_enabled, only: [:index] before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show] @@ -17,7 +16,7 @@ def index end def runner_list_group_view_vue_ui_enabled - return render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml) + render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml) end def show -- GitLab From 2e8cfb3b99ef1aed7b0347a0b92b5e863823817d Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Wed, 29 Dec 2021 18:12:02 +0100 Subject: [PATCH 3/5] Make register rule independent of admin rule --- app/policies/group_policy.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 7b98f6b1170a1d..047151fd58950a 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -163,6 +163,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :create_projects enable :admin_pipeline enable :admin_group_runners + enable :register_group_runners enable :admin_build enable :read_cluster enable :add_cluster @@ -207,10 +208,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :read_nested_project_resources end - rule { can?(:admin_group_runners) }.policy do - enable :register_group_runners - end - rule { owner }.enable :create_subgroup rule { maintainer & maintainer_can_create_group }.enable :create_subgroup -- GitLab From 9edc206e14acd6bc2fb1c6fac493fe5a9c2bf176 Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Wed, 29 Dec 2021 18:40:11 +0100 Subject: [PATCH 4/5] Docs: Clarify permissions for group runners --- doc/user/permissions.md | 325 ++++++++++++++++++++-------------------- 1 file changed, 163 insertions(+), 162 deletions(-) diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 3cb07ecfe99205..36c49e39151170 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -46,168 +46,169 @@ The following table lists project permissions available for each role: -| Action | Guest | Reporter | Developer | Maintainer | Owner | -|-------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------| -| [Analytics](analytics/index.md):
View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ | -| [Application security](application_security/index.md):
Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ | -| [CI/CD](../ci/index.md):
Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Cancel and retry jobs | | | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Manage CI/CD variables | | | | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Manage job triggers | | | | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Manage runners | | | | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ | -| [CI/CD](../ci/index.md):
Delete pipelines | | | | | ✓ | -| [Clusters](infrastructure/clusters/index.md):
View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ | -| [Clusters](infrastructure/clusters/index.md):
Manage clusters | | | | ✓ | ✓ | -| [Container Registry](packages/container_registry/index.md):
Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ | -| [Container Registry](packages/container_registry/index.md):
Remove a container registry image | | | ✓ | ✓ | ✓ | -| [Container Registry](packages/container_registry/index.md):
Update container registry | | | ✓ | ✓ | ✓ | -| [GitLab Pages](project/pages/index.md):
View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ | -| [GitLab Pages](project/pages/index.md):
Manage | | | | ✓ | ✓ | -| [GitLab Pages](project/pages/index.md):
Manage GitLab Pages domains and certificates | | | | ✓ | ✓ | -| [GitLab Pages](project/pages/index.md):
Remove GitLab Pages | | | | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
Assign an alert | ✓| ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
View [incident](../operations/incident_management/incidents.md) | ✓| ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
Create [incident](../operations/incident_management/incidents.md) | (*17*) | ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
Participate in on-call rotation | ✓| ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ | -| [Incident Management](../operations/incident_management/index.md):
Manage [escalation policies](../operations/incident_management/escalation_policies.md)| | | | ✓ | ✓ | -| [Issues](project/issues/index.md):
Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Create | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
View related issues | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Close / reopen | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Lock threads | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Manage related issues | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Manage tracker | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Move issues (*15*) | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Delete | | | | | ✓ | -| [License Compliance](compliance/license_compliance/index.md):
View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [License Compliance](compliance/license_compliance/index.md):
View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [License Compliance](compliance/license_compliance/index.md):
View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | -| [License Compliance](compliance/license_compliance/index.md):
Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Assign reviewer | | ✓ | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
See list | | ✓ | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Apply code change suggestions | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Approve (*9*) | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Assign | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Create (*18*) | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Add labels | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Lock threads | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Manage or accept | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Manage merge approval rules (project settings) | | | | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Delete | | | | | ✓ | -| [Metrics dashboards](../operations/metrics/dashboards/index.md):
Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Metrics dashboards](../operations/metrics/dashboards/index.md):
View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ | -| [Metrics dashboards](../operations/metrics/dashboards/index.md):
Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ | -| [Package registry](packages/index.md):
Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Package registry](packages/index.md):
Publish package | | | ✓ | ✓ | ✓ | -| [Package registry](packages/index.md):
Delete package | | | | ✓ | ✓ | -| [Project operations](../operations/index.md):
View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ | -| [Project operations](../operations/index.md):
Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ | -| [Project operations](../operations/index.md):
Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ | -| [Projects](project/index.md):
Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ | -| [Projects](project/index.md):
View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Manage labels | | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) | -| [Projects](project/index.md):
Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Enable Review Apps | | | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ | -| [Projects](project/index.md):
Add deploy keys | | | | ✓ | ✓ | -| [Projects](project/index.md):
Add new team members | | | | ✓ | ✓ | -| [Projects](project/index.md):
Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ | -| [Projects](project/index.md):
Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ | -| [Projects](project/index.md):
Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
Edit comments (posted by any user) | | | | ✓ | ✓ | -| [Projects](project/index.md):
Edit project badges | | | | ✓ | ✓ | -| [Projects](project/index.md):
Edit project settings | | | | ✓ | ✓ | -| [Projects](project/index.md):
Export project | | | | ✓ | ✓ | -| [Projects](project/index.md):
Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*12*) | | | | ✓ | ✓ | -| [Projects](project/index.md):
Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ | -| [Projects](project/index.md):
Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) | -| [Projects](project/index.md):
View 2FA status of members | | | | ✓ | ✓ | -| [Projects](project/index.md):
Administer project compliance frameworks | | | | | ✓ | -| [Projects](project/index.md):
Archive project | | | | | ✓ | -| [Projects](project/index.md):
Change project visibility level | | | | | ✓ | -| [Projects](project/index.md):
Delete project | | | | | ✓ | -| [Projects](project/index.md):
Disable notification emails | | | | | ✓ | -| [Projects](project/index.md):
Rename project | | | | | ✓ | -| [Projects](project/index.md):
Transfer project to another namespace | | | | | ✓ | -| [Repository](project/repository/index.md):
Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
View a commit status | | ✓ | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Add tags | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Create new branches | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Create or update commit status | | | ✓ (*5*) | ✓ | ✓ | -| [Repository](project/repository/index.md):
Force push to non-protected branches | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Push to non-protected branches | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Remove non-protected branches | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Rewrite or remove Git tags | | | ✓ | ✓ | ✓ | -| [Repository](project/repository/index.md):
Enable or disable branch protection | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Enable or disable tag protection | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Push to protected branches (*5*) | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Turn on or off protected branch push for developers | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Remove fork relationship | | | | | ✓ | -| [Repository](project/repository/index.md):
Force push to protected branches (*4*) | | | | | | -| [Repository](project/repository/index.md):
Remove protected branches (*4*) | | | | | | -| [Requirements Management](project/requirements/index.md):
Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | -| [Requirements Management](project/requirements/index.md):
Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | -| [Requirements Management](project/requirements/index.md):
Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Revert vulnerability to detected state **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Terraform](infrastructure/index.md):
Read Terraform state | | | ✓ | ✓ | ✓ | -| [Terraform](infrastructure/index.md):
Manage Terraform state | | | | ✓ | ✓ | -| [Test cases](../ci/test_cases/index.md):
Archive | | ✓ | ✓ | ✓ | ✓ | -| [Test cases](../ci/test_cases/index.md):
Create | | ✓ | ✓ | ✓ | ✓ | -| [Test cases](../ci/test_cases/index.md):
Move | | ✓ | ✓ | ✓ | ✓ | -| [Test cases](../ci/test_cases/index.md):
Reopen | | ✓ | ✓ | ✓ | ✓ | +| Action | Guest | Reporter | Developer | Maintainer | Owner | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------| +| [Analytics](analytics/index.md):
View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Application security](application_security/index.md):
Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ | +| [Application security](application_security/index.md):
Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ | +| [CI/CD](../ci/index.md):
Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Cancel and retry jobs | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Manage CI/CD variables | | | | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Manage job triggers | | | | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Manage group runners | | | | | ✓ | +| [CI/CD](../ci/index.md):
Manage project runners | | | | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ | +| [CI/CD](../ci/index.md):
Delete pipelines | | | | | ✓ | +| [Clusters](infrastructure/clusters/index.md):
View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ | +| [Clusters](infrastructure/clusters/index.md):
Manage clusters | | | | ✓ | ✓ | +| [Container Registry](packages/container_registry/index.md):
Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ | +| [Container Registry](packages/container_registry/index.md):
Remove a container registry image | | | ✓ | ✓ | ✓ | +| [Container Registry](packages/container_registry/index.md):
Update container registry | | | ✓ | ✓ | ✓ | +| [GitLab Pages](project/pages/index.md):
View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ | +| [GitLab Pages](project/pages/index.md):
Manage | | | | ✓ | ✓ | +| [GitLab Pages](project/pages/index.md):
Manage GitLab Pages domains and certificates | | | | ✓ | ✓ | +| [GitLab Pages](project/pages/index.md):
Remove GitLab Pages | | | | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
Assign an alert | ✓| ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
View [incident](../operations/incident_management/incidents.md) | ✓| ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
Create [incident](../operations/incident_management/incidents.md) | (*17*) | ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
Participate in on-call rotation | ✓| ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ | +| [Incident Management](../operations/incident_management/index.md):
Manage [escalation policies](../operations/incident_management/escalation_policies.md) | | | | ✓ | ✓ | +| [Issues](project/issues/index.md):
Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Create | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
View related issues | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Close / reopen | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Lock threads | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Manage related issues | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Manage tracker | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Move issues (*15*) | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Delete | | | | | ✓ | +| [License Compliance](compliance/license_compliance/index.md):
View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [License Compliance](compliance/license_compliance/index.md):
View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [License Compliance](compliance/license_compliance/index.md):
View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | +| [License Compliance](compliance/license_compliance/index.md):
Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Assign reviewer | | ✓ | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
See list | | ✓ | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Apply code change suggestions | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Approve (*9*) | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Assign | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Create (*18*) | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Add labels | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Lock threads | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Manage or accept | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Manage merge approval rules (project settings) | | | | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Delete | | | | | ✓ | +| [Metrics dashboards](../operations/metrics/dashboards/index.md):
Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Metrics dashboards](../operations/metrics/dashboards/index.md):
View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ | +| [Metrics dashboards](../operations/metrics/dashboards/index.md):
Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ | +| [Package registry](packages/index.md):
Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Package registry](packages/index.md):
Publish package | | | ✓ | ✓ | ✓ | +| [Package registry](packages/index.md):
Delete package | | | | ✓ | ✓ | +| [Project operations](../operations/index.md):
View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ | +| [Project operations](../operations/index.md):
Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ | +| [Project operations](../operations/index.md):
Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ | +| [Projects](project/index.md):
Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ | +| [Projects](project/index.md):
View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Manage labels | | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) | +| [Projects](project/index.md):
Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Enable Review Apps | | | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ | +| [Projects](project/index.md):
Add deploy keys | | | | ✓ | ✓ | +| [Projects](project/index.md):
Add new team members | | | | ✓ | ✓ | +| [Projects](project/index.md):
Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ | +| [Projects](project/index.md):
Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ | +| [Projects](project/index.md):
Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Edit comments (posted by any user) | | | | ✓ | ✓ | +| [Projects](project/index.md):
Edit project badges | | | | ✓ | ✓ | +| [Projects](project/index.md):
Edit project settings | | | | ✓ | ✓ | +| [Projects](project/index.md):
Export project | | | | ✓ | ✓ | +| [Projects](project/index.md):
Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*12*) | | | | ✓ | ✓ | +| [Projects](project/index.md):
Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ | +| [Projects](project/index.md):
Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) | +| [Projects](project/index.md):
View 2FA status of members | | | | ✓ | ✓ | +| [Projects](project/index.md):
Administer project compliance frameworks | | | | | ✓ | +| [Projects](project/index.md):
Archive project | | | | | ✓ | +| [Projects](project/index.md):
Change project visibility level | | | | | ✓ | +| [Projects](project/index.md):
Delete project | | | | | ✓ | +| [Projects](project/index.md):
Disable notification emails | | | | | ✓ | +| [Projects](project/index.md):
Rename project | | | | | ✓ | +| [Projects](project/index.md):
Transfer project to another namespace | | | | | ✓ | +| [Repository](project/repository/index.md):
Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
View a commit status | | ✓ | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Add tags | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Create new branches | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Create or update commit status | | | ✓ (*5*) | ✓ | ✓ | +| [Repository](project/repository/index.md):
Force push to non-protected branches | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Push to non-protected branches | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Remove non-protected branches | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Rewrite or remove Git tags | | | ✓ | ✓ | ✓ | +| [Repository](project/repository/index.md):
Enable or disable branch protection | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Enable or disable tag protection | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Push to protected branches (*5*) | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Turn on or off protected branch push for developers | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Remove fork relationship | | | | | ✓ | +| [Repository](project/repository/index.md):
Force push to protected branches (*4*) | | | | | | +| [Repository](project/repository/index.md):
Remove protected branches (*4*) | | | | | | +| [Requirements Management](project/requirements/index.md):
Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | +| [Requirements Management](project/requirements/index.md):
Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | +| [Requirements Management](project/requirements/index.md):
Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Revert vulnerability to detected state **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | +| [Terraform](infrastructure/index.md):
Read Terraform state | | | ✓ | ✓ | ✓ | +| [Terraform](infrastructure/index.md):
Manage Terraform state | | | | ✓ | ✓ | +| [Test cases](../ci/test_cases/index.md):
Archive | | ✓ | ✓ | ✓ | ✓ | +| [Test cases](../ci/test_cases/index.md):
Create | | ✓ | ✓ | ✓ | ✓ | +| [Test cases](../ci/test_cases/index.md):
Move | | ✓ | ✓ | ✓ | ✓ | +| [Test cases](../ci/test_cases/index.md):
Reopen | | ✓ | ✓ | ✓ | ✓ | 1. On self-managed GitLab instances, guest users are able to perform this action only on public and internal projects (not on private projects). [External users](#external-users) -- GitLab From aa65354d7c0bc48f8f4c779b4f2e01b3fd246d73 Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Thu, 30 Dec 2021 09:25:00 +0100 Subject: [PATCH 5/5] Make admin/register runners only available to owners --- app/policies/group_policy.rb | 4 +-- .../projects/runners/_group_runners.html.haml | 4 +-- locale/gitlab.pot | 8 +++--- spec/features/runners_spec.rb | 25 ++++++++++++++++--- spec/policies/group_policy_spec.rb | 4 +-- .../policies/group_policy_shared_context.rb | 3 ++- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 047151fd58950a..6e316f1306dfdf 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -162,8 +162,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :destroy_package enable :create_projects enable :admin_pipeline - enable :admin_group_runners - enable :register_group_runners enable :admin_build enable :read_cluster enable :add_cluster @@ -182,6 +180,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :change_visibility_level enable :read_group_runners + enable :admin_group_runners + enable :register_group_runners enable :set_note_created_at enable :set_emails_disabled diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml index 183e747afddda5..c25fd7a7587592 100644 --- a/app/views/projects/runners/_group_runners.html.haml +++ b/app/views/projects/runners/_group_runners.html.haml @@ -29,9 +29,9 @@ - if can?(current_user, :admin_group_runners, @project.group) - group_link = link_to _("group's CI/CD settings."), group_settings_ci_cd_path(@project.group) - = _('Group maintainers can register group runners in the %{link}').html_safe % { link: group_link } + = _('Group owners can register group runners in the %{link}').html_safe % { link: group_link } - else - = _('Ask your group maintainer to set up a group runner.') + = _('Ask your group owner to set up a group runner.') - else %h4.underlined-title diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e2210cc0592395..c1f48f6d70234a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4796,7 +4796,7 @@ msgstr "" msgid "Ask someone with write access to resolve it." msgstr "" -msgid "Ask your group maintainer to set up a group runner." +msgid "Ask your group owner to set up a group runner." msgstr "" msgid "Assertion consumer service URL" @@ -16721,9 +16721,6 @@ msgstr "" msgid "Group jobs by" msgstr "" -msgid "Group maintainers can register group runners in the %{link}" -msgstr "" - msgid "Group members" msgstr "" @@ -16748,6 +16745,9 @@ msgstr "" msgid "Group overview content" msgstr "" +msgid "Group owners can register group runners in the %{link}" +msgstr "" + msgid "Group path is already taken. We've suggested one that is available." msgstr "" diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index 22de77f7cd0149..49c468976b9ea7 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -268,10 +268,27 @@ it 'group runners are not available' do visit project_runners_path(project) + expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).to have_content 'Ask your group owner to set up a group runner' + end + end + end + + context 'as project maintainer and group owner' do + before do + group.add_owner(user) + end + + context 'project with a group but no group runner' do + let(:project) { create :project, group: group } + + it 'group runners are available' do + visit project_runners_path(project) + expect(page).to have_content 'This group does not have any group runners yet.' - expect(page).to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.' - expect(page).not_to have_content 'Ask your group maintainer to set up a group runner' + expect(page).to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).not_to have_content 'Ask your group owner to set up a group runner' end end end @@ -296,8 +313,8 @@ expect(page).to have_content 'This group does not have any group runners yet.' - expect(page).not_to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.' - expect(page).to have_content 'Ask your group maintainer to set up a group runner.' + expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).to have_content 'Ask your group owner to set up a group runner.' end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 3f986711f4b576..c533aa557cd10a 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -1085,9 +1085,7 @@ context 'with maintainer' do let(:current_user) { maintainer } - it { is_expected.to be_allowed(:register_group_runners) } - - it_behaves_like 'expected outcome based on runner registration control' + it { is_expected.to be_disallowed(:register_group_runners) } end context 'with reporter' do diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb index d531de417115d6..4fb9792182a3d7 100644 --- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -48,7 +48,6 @@ destroy_package create_projects read_cluster create_cluster update_cluster admin_cluster add_cluster - admin_group_runners ] end @@ -64,6 +63,8 @@ read_statistics update_default_branch_protection read_group_runners + admin_group_runners + register_group_runners ] end -- GitLab