From f075ab1b79ca9aa1f9b8b7ac8969a069835b71d7 Mon Sep 17 00:00:00 2001 From: Ayush Date: Fri, 17 Jan 2025 16:25:57 +0530 Subject: [PATCH] Generate custom permission for Protected Environments - Add rule in group and project policies. - Update relevant documentation. - Update group and project policy specs. - Add custom ability file to hold metadata. - Add request specs for the new ability. Add custom permission in Projects::ProtectedEnvironmentsController and update settings_menu to allow admin_protected_environment Update controller to conditionally display the protected env Add wip feature flag and update files accordingly Add featureflag stub in cicd controller spec Move permission check to EE section + Add specs Add custom permission at projects level - Add :admin_protected_environment ability in controller and view - Update project settings menu to show CI/CI when oermitted - Update setting_menu_spec - Update request_spec to include project level changes Add custom permission at projects level - Add :admin_protected_environment ability in controller and view - Update project settings menu to show CI/CI when oermitted - Update setting_menu_spec - Update request_spec to include project level changes Make code review suggestions - Update policy name to admin_protected_environments - Remove redundant methods - Remove redundant feature flag check - Update docs - Keep items in array in alphabatical order Change admin_protected_environment to admin_protected_environments Add admin_protected_environments to base project policy Add enabled access_levels for groups and projects for permission Apply custom policy to Controller and API of protectedenvironments Generate custom permission for Protected Environments - Add custom permission in Projects::ProtectedEnvironmentsController and update settings_menu to allow admin_protected_environment - Update controller to conditionally display the protected env - Add wip feature flag and update files accordingly - Add featureflag stub in cicd controller spec - Move permission check to EE section + Add specs - Add custom permission at projects level - Add :admin_protected_environment ability in controller and view - Update project settings menu to show CI/CI when oermitted - Update setting_menu_spec - Update request_spec to include project level changes - Add custom permission at projects level - Add :admin_protected_environment ability in controller and view - Update project settings menu to show CI/CI when oermitted - Update setting_menu_spec - Update request_spec to include project level changes --- .../groups/settings/ci_cd_controller.rb | 1 + .../projects/settings/ci_cd_controller.rb | 1 + app/policies/group_policy.rb | 1 + app/policies/project_policy.rb | 1 + .../json_schemas/member_role_permissions.json | 3 + .../groups/settings/ci_cd/show.html.haml | 1 + .../projects/settings/ci_cd/show.html.haml | 1 + doc/api/graphql/reference/_index.md | 2 + .../protected_environments_controller.rb | 6 +- .../protected_environments_controller.rb | 2 +- ee/app/policies/ee/group_policy.rb | 6 +- ee/app/policies/ee/project_policy.rb | 4 + .../admin_protected_environments.yml | 12 ++ ...m_ability_admin_protected_environments.yml | 9 + ee/lib/api/protected_environments.rb | 4 +- .../ee/sidebars/groups/menus/settings_menu.rb | 3 +- .../sidebars/projects/menus/settings_menu.rb | 1 + .../groups/menus/settings_menu_spec.rb | 1 + .../projects/menus/settings_menu_spec.rb | 1 + ee/spec/policies/group_policy_spec.rb | 7 + ee/spec/policies/project_policy_spec.rb | 7 + .../groups_request_spec.rb | 200 ++++++++++++++++++ .../projects_request_spec.rb | 179 ++++++++++++++++ 23 files changed, 445 insertions(+), 8 deletions(-) create mode 100644 ee/config/custom_abilities/admin_protected_environments.yml create mode 100644 ee/config/feature_flags/wip/custom_ability_admin_protected_environments.yml create mode 100644 ee/spec/requests/custom_roles/admin_protected_environments/groups_request_spec.rb create mode 100644 ee/spec/requests/custom_roles/admin_protected_environments/projects_request_spec.rb diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 5699925ae9df2e..e6de6d4df5b675 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -54,6 +54,7 @@ def update_auto_devops def authorize_show_cicd_settings! return if can_any?(current_user, [ :admin_cicd_variables, + :admin_protected_environments, :admin_runner ], group) diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 21deac8b74cb8b..3b3b5cb78a6a33 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -113,6 +113,7 @@ def authorize_reset_cache! def authorize_show_cicd_settings! return if can_any?(current_user, [ :admin_cicd_variables, + :admin_protected_environments, :admin_runner ], project) diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 295cc0eb5e8b4b..b3e5f65e303e3c 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -283,6 +283,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :admin_package enable :admin_runner enable :admin_integrations + enable :admin_protected_environments enable :change_visibility_level enable :read_usage_quotas diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 5fb96269292023..3c782fd7cce5d4 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -665,6 +665,7 @@ class ProjectPolicy < BasePolicy enable :change_restrict_user_defined_variables enable :create_protected_branch enable :admin_protected_branch + enable :admin_protected_environments end rule { can?(:manage_protected_tags) }.policy do diff --git a/app/validators/json_schemas/member_role_permissions.json b/app/validators/json_schemas/member_role_permissions.json index b365412c333be1..dc5a9f81b96ca1 100644 --- a/app/validators/json_schemas/member_role_permissions.json +++ b/app/validators/json_schemas/member_role_permissions.json @@ -22,6 +22,9 @@ "admin_protected_branch": { "type": "boolean" }, + "admin_protected_environments": { + "type": "boolean" + }, "admin_push_rules": { "type": "boolean" }, diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml index a066eee31f6d2a..2ffb61291a6e19 100644 --- a/app/views/groups/settings/ci_cd/show.html.haml +++ b/app/views/groups/settings/ci_cd/show.html.haml @@ -50,4 +50,5 @@ - c.with_body do = render 'groups/settings/ci_cd/auto_devops_form', group: @group +- if can?(current_user, :admin_protected_environments, @group) = render_if_exists 'groups/settings/ci_cd/protected_environments', expanded: expanded diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index f36d4b5bf443ce..1583f2ff3b120c 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -29,6 +29,7 @@ - c.with_body do = render 'autodevops_form', auto_devops_enabled: @project.auto_devops_enabled? +- if can?(current_user, :admin_protected_environments, @project) = render_if_exists 'projects/settings/ci_cd/protected_environments', expanded: expanded - if can?(current_user, :admin_runner, @project) diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index a56622dc9936c2..025ef77dbf0e46 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -41214,6 +41214,7 @@ Member role permission. | `ADMIN_INTEGRATIONS` | Create, read, update, and delete integrations with external applications. | | `ADMIN_MERGE_REQUEST` | Allows approval of merge requests. | | `ADMIN_PROTECTED_BRANCH` | Create, read, update, and delete protected branches for a project. | +| `ADMIN_PROTECTED_ENVIRONMENTS` | Create, read, update, and delete environments. | | `ADMIN_PUSH_RULES` | Configure push rules for repositories at the group or project level. | | `ADMIN_RUNNERS` | Create, view, edit, and delete group or project Runners. Includes configuring Runner settings. | | `ADMIN_SECURITY_TESTING` | Edit and manage security testing configurations and settings. | @@ -41253,6 +41254,7 @@ Member role standard permission. | `ADMIN_INTEGRATIONS` | Create, read, update, and delete integrations with external applications. | | `ADMIN_MERGE_REQUEST` | Allows approval of merge requests. | | `ADMIN_PROTECTED_BRANCH` | Create, read, update, and delete protected branches for a project. | +| `ADMIN_PROTECTED_ENVIRONMENTS` | Create, read, update, and delete environments. | | `ADMIN_PUSH_RULES` | Configure push rules for repositories at the group or project level. | | `ADMIN_RUNNERS` | Create, view, edit, and delete group or project Runners. Includes configuring Runner settings. | | `ADMIN_SECURITY_TESTING` | Edit and manage security testing configurations and settings. | diff --git a/ee/app/controllers/groups/protected_environments_controller.rb b/ee/app/controllers/groups/protected_environments_controller.rb index 793999d888a83d..7a2c4d7c613bc8 100644 --- a/ee/app/controllers/groups/protected_environments_controller.rb +++ b/ee/app/controllers/groups/protected_environments_controller.rb @@ -2,7 +2,7 @@ module Groups class ProtectedEnvironmentsController < Groups::ApplicationController - before_action :authorize_admin_protected_environment! + before_action :authorize_admin_protected_environments! before_action :protected_environment, except: [:create] feature_category :continuous_delivery @@ -62,8 +62,8 @@ def deploy_access_level_attributes %i[id _destroy group_id] end - def authorize_admin_protected_environment! - not_found unless can?(current_user, :admin_protected_environment, group) + def authorize_admin_protected_environments! + not_found unless can?(current_user, :admin_protected_environments, group) end def serialized_protected_environment diff --git a/ee/app/controllers/projects/protected_environments_controller.rb b/ee/app/controllers/projects/protected_environments_controller.rb index 5044edd869f443..9279a2cc999265 100644 --- a/ee/app/controllers/projects/protected_environments_controller.rb +++ b/ee/app/controllers/projects/protected_environments_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Projects::ProtectedEnvironmentsController < Projects::ApplicationController - before_action :authorize_admin_project! + before_action :authorize_admin_protected_environments! before_action :protected_environment, except: [:create, :search] feature_category :continuous_delivery diff --git a/ee/app/policies/ee/group_policy.rb b/ee/app/policies/ee/group_policy.rb index d88d7393feb2de..3f05693d461ce8 100644 --- a/ee/app/policies/ee/group_policy.rb +++ b/ee/app/policies/ee/group_policy.rb @@ -348,7 +348,7 @@ module GroupPolicy end rule { owner }.policy do - enable :admin_protected_environment + enable :admin_protected_environments enable :admin_licensed_seat end @@ -630,6 +630,10 @@ module GroupPolicy enable :admin_cicd_variables end + rule { custom_role_enables_admin_protected_environments }.policy do + enable :admin_protected_environments + end + rule { custom_role_enables_admin_compliance_framework }.policy do enable :admin_compliance_framework enable :admin_compliance_pipeline_configuration diff --git a/ee/app/policies/ee/project_policy.rb b/ee/app/policies/ee/project_policy.rb index 670c33a46f48da..60236bce79f898 100644 --- a/ee/app/policies/ee/project_policy.rb +++ b/ee/app/policies/ee/project_policy.rb @@ -298,6 +298,10 @@ module ProjectPolicy enable :admin_cicd_variables end + rule { custom_role_enables_admin_protected_environments }.policy do + enable :admin_protected_environments + end + rule { custom_role_enables_admin_push_rules }.policy do enable :admin_push_rules end diff --git a/ee/config/custom_abilities/admin_protected_environments.yml b/ee/config/custom_abilities/admin_protected_environments.yml new file mode 100644 index 00000000000000..7f45448bde3211 --- /dev/null +++ b/ee/config/custom_abilities/admin_protected_environments.yml @@ -0,0 +1,12 @@ +--- +title: Manage Protected Environments +name: admin_protected_environments +description: Create, read, update, and delete environments +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/471385 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178283 +feature_category: continuous_delivery +milestone: '17.9' +group_ability: true +enabled_for_group_access_levels: [50] +project_ability: true +enabled_for_project_access_levels: [40, 50] diff --git a/ee/config/feature_flags/wip/custom_ability_admin_protected_environments.yml b/ee/config/feature_flags/wip/custom_ability_admin_protected_environments.yml new file mode 100644 index 00000000000000..7b8b9bbb25aaa0 --- /dev/null +++ b/ee/config/feature_flags/wip/custom_ability_admin_protected_environments.yml @@ -0,0 +1,9 @@ +--- +name: custom_ability_admin_protected_environments +feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/471385 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178283 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/514698 +milestone: '17.9' +group: group::authorization +type: wip +default_enabled: false diff --git a/ee/lib/api/protected_environments.rb b/ee/lib/api/protected_environments.rb index c82f52cf90f133..ebfa03caf214ae 100644 --- a/ee/lib/api/protected_environments.rb +++ b/ee/lib/api/protected_environments.rb @@ -97,7 +97,7 @@ def protected_environment end end - before { authorize_admin_project } + before { authorize! :admin_protected_environments, user_project } desc 'List protected environments' do detail 'Gets a list of protected environments from a project. This feature was introduced in GitLab 12.8.' @@ -232,7 +232,7 @@ def protected_environment end before do - authorize! :admin_protected_environment, user_group + authorize! :admin_protected_environments, user_group end desc 'List group-level protected environments' do diff --git a/ee/lib/ee/sidebars/groups/menus/settings_menu.rb b/ee/lib/ee/sidebars/groups/menus/settings_menu.rb index 26bd314b11521b..e3fcb17bd599c9 100644 --- a/ee/lib/ee/sidebars/groups/menus/settings_menu.rb +++ b/ee/lib/ee/sidebars/groups/menus/settings_menu.rb @@ -34,7 +34,8 @@ def configure_menu_items add_menu_item_for_abilities(integrations_menu_item, :admin_integrations) add_menu_item_for_abilities(access_tokens_menu_item, :read_resource_access_tokens) add_menu_item_for_abilities(repository_menu_item, [:admin_push_rules, :manage_deploy_tokens]) - add_menu_item_for_abilities(ci_cd_menu_item, [:admin_cicd_variables, :admin_runner]) + add_menu_item_for_abilities(ci_cd_menu_item, [:admin_cicd_variables, + :admin_protected_environments, :admin_runner]) add_menu_item_for_abilities(billing_menu_item, :read_billing) add_menu_item_for_abilities(workspaces_menu_item, :read_remote_development_cluster_agent_mapping) end diff --git a/ee/lib/ee/sidebars/projects/menus/settings_menu.rb b/ee/lib/ee/sidebars/projects/menus/settings_menu.rb index 41d2fc1e8ba2e2..185829ab19f958 100644 --- a/ee/lib/ee/sidebars/projects/menus/settings_menu.rb +++ b/ee/lib/ee/sidebars/projects/menus/settings_menu.rb @@ -25,6 +25,7 @@ module SettingsMenu ], ci_cd_menu_item: [ :admin_cicd_variables, + :admin_protected_environments, :admin_runner ], integrations_menu_item: [ diff --git a/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb b/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb index af775c736b4558..304f26b0c66dfd 100644 --- a/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb +++ b/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb @@ -439,6 +439,7 @@ :admin_cicd_variables | 'CI/CD' :admin_compliance_framework | 'General' :admin_push_rules | 'Repository' + :admin_protected_environments | 'CI/CD' :admin_runners | 'CI/CD' :manage_deploy_tokens | 'Repository' :manage_group_access_tokens | 'Access tokens' diff --git a/ee/spec/lib/ee/sidebars/projects/menus/settings_menu_spec.rb b/ee/spec/lib/ee/sidebars/projects/menus/settings_menu_spec.rb index ab09edf5cfe36f..251ecc4b6a97f4 100644 --- a/ee/spec/lib/ee/sidebars/projects/menus/settings_menu_spec.rb +++ b/ee/spec/lib/ee/sidebars/projects/menus/settings_menu_spec.rb @@ -90,6 +90,7 @@ :admin_push_rules | 'Repository' :manage_protected_tags | 'Repository' :admin_protected_branch | 'Repository' + :admin_protected_environments | 'CI/CD' :admin_runners | 'CI/CD' :manage_deploy_tokens | 'Repository' :manage_merge_request_settings | 'Merge requests' diff --git a/ee/spec/policies/group_policy_spec.rb b/ee/spec/policies/group_policy_spec.rb index ce737440e5976d..7f217113f928b1 100644 --- a/ee/spec/policies/group_policy_spec.rb +++ b/ee/spec/policies/group_policy_spec.rb @@ -3888,6 +3888,13 @@ def create_member_role(member, abilities = member_role_abilities) it_behaves_like 'custom roles abilities' end + context 'for a custom role with the `admin_protected_environments` ability' do + let(:member_role_abilities) { { admin_protected_environments: true } } + let(:allowed_abilities) { [:admin_protected_environments] } + + it_behaves_like 'custom roles abilities' + end + context 'for a member role with admin_compliance_framework true' do let(:member_role_abilities) { { read_compliance_dashboard: true, admin_compliance_framework: true } } diff --git a/ee/spec/policies/project_policy_spec.rb b/ee/spec/policies/project_policy_spec.rb index 067bbfa4ef277a..d4e494a6cbd4cd 100644 --- a/ee/spec/policies/project_policy_spec.rb +++ b/ee/spec/policies/project_policy_spec.rb @@ -2966,6 +2966,13 @@ def create_member_role(member, abilities = member_role_abilities) it_behaves_like 'custom roles abilities' end + context 'for a custom role with the `admin_protected_environments` ability' do + let(:member_role_abilities) { { admin_protected_environments: true } } + let(:allowed_abilities) { [:admin_protected_environments] } + + it_behaves_like 'custom roles abilities' + end + context 'for a custom role with the `admin_push_rules` ability' do let(:member_role_abilities) { { admin_push_rules: true } } let(:allowed_abilities) { [:admin_push_rules] } diff --git a/ee/spec/requests/custom_roles/admin_protected_environments/groups_request_spec.rb b/ee/spec/requests/custom_roles/admin_protected_environments/groups_request_spec.rb new file mode 100644 index 00000000000000..a786b2629f1fb5 --- /dev/null +++ b/ee/spec/requests/custom_roles/admin_protected_environments/groups_request_spec.rb @@ -0,0 +1,200 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User with admin_protected_environments custom role', feature_category: :continuous_delivery do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:protected_environment) { create(:protected_environment, :production, :group_level, group: group) } + + shared_context 'with protected environment setting' do |enabled| + let_it_be(:role) { create(:member_role, :guest, namespace: group, admin_protected_environments: enabled) } + let_it_be(:group_member) { create(:group_member, :guest, member_role: role, user: user, group: group) } + end + + before do + stub_licensed_features(custom_roles: true) + sign_in(user) + end + + describe Groups::Settings::CiCdController do + let(:settings_page_path) { group_settings_ci_cd_path(group) } + let(:update_params) { { group: { max_artifacts_size: 100 } } } + + context 'when user has protected environment access' do + include_context 'with protected environment setting', true + + describe '#GET show' do + subject(:view_settings_page) { get settings_page_path } + + it 'displays the CI/CD settings page successfully' do + view_settings_page + + expect(response).to have_gitlab_http_status(:ok) + expect(response.body).to include('CI/CD Settings') + end + end + + describe '#PUT update' do + subject(:update_settings) { put settings_page_path, params: update_params } + + it 'prevents modification of CI/CD settings' do + update_settings + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when user lacks protected environment access' do + include_context 'with protected environment setting', false + + describe '#GET show' do + subject(:view_settings_page) { get settings_page_path } + + it 'denies access to the CI/CD settings page' do + view_settings_page + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#PUT update' do + subject(:update_settings) { put settings_page_path, params: update_params } + + it 'prevents modification of CI/CD settings' do + update_settings + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end + + describe Groups::ProtectedEnvironmentsController do + let_it_be(:group) { create(:group) } + let_it_be(:protected_environment) { create(:protected_environment, :group_level, group: group, name: 'production') } + + let(:environment_params) do + { + protected_environment: { + name: 'staging', + deploy_access_levels_attributes: [{ group_id: group.id }] + } + } + end + + let(:base_path) { group_protected_environments_path(group) } + let(:environment_path) { group_protected_environment_path(group, protected_environment) } + let(:settings_redirect) { group_settings_ci_cd_path(group, anchor: 'js-protected-environments-settings') } + + context 'when user has protected environment access' do + include_context 'with protected environment setting', true + + describe '#POST create' do + subject(:create_environment) { post base_path, params: environment_params, as: :json } + + it 'creates a new protected environment' do + expect { create_environment }.to change { ProtectedEnvironment.count } + + expect(response).to have_gitlab_http_status(:found) + expect(flash[:notice]).to eq('Your environment has been protected.') + expect(response).to redirect_to(settings_redirect) + end + end + + describe '#PUT update' do + let(:update_params) do + { + protected_environment: { + name: protected_environment.name, + deploy_access_levels_attributes: [ + { id: protected_environment.deploy_access_levels.first.id, group_id: group.id } + ] + } + } + end + + subject(:update_environment) { put environment_path, params: update_params } + + it 'updates the protected environment' do + expect { update_environment } + .not_to change { protected_environment.reload.name } + + expect(response).to have_gitlab_http_status(:ok) + end + end + + describe '#DELETE destroy' do + let_it_be(:deletable_environment) do + create(:protected_environment, :group_level, + group: group, + name: 'testing' + ) + end + + subject(:delete_environment) { delete group_protected_environment_path(group, deletable_environment) } + + it 'removes the protected environment' do + expect { delete_environment }.to change { ProtectedEnvironment.count } + + expect(response).to have_gitlab_http_status(:found) + expect(flash[:notice]).to eq('Your environment has been unprotected') + expect(response).to redirect_to(settings_redirect) + end + end + end + + context 'when user lacks protected environment access' do + include_context 'with protected environment setting', false + + describe '#POST create' do + subject(:create_environment) { post base_path, params: environment_params, as: :json } + + it 'denies environment creation' do + expect { create_environment }.not_to change { ProtectedEnvironment.count } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#PUT update' do + let(:update_params) do + { + protected_environment: { + name: protected_environment.name, + deploy_access_levels_attributes: [ + { id: protected_environment.deploy_access_levels.first.id, group_id: group.id } + ] + } + } + end + + subject(:update_environment) { put environment_path, params: update_params } + + it 'denies environment update' do + update_environment + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#DELETE destroy' do + let_it_be(:deletable_environment) do + create(:protected_environment, :group_level, + group: group, + name: 'testing' + ) + end + + subject(:delete_environment) { delete group_protected_environment_path(group, deletable_environment) } + + it 'denies environment deletion' do + expect { delete_environment }.not_to change { ProtectedEnvironment.count } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end +end diff --git a/ee/spec/requests/custom_roles/admin_protected_environments/projects_request_spec.rb b/ee/spec/requests/custom_roles/admin_protected_environments/projects_request_spec.rb new file mode 100644 index 00000000000000..74b1ce7065c901 --- /dev/null +++ b/ee/spec/requests/custom_roles/admin_protected_environments/projects_request_spec.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User with admin_protected_environments custom role', feature_category: :continuous_delivery do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:protected_environment) { create(:protected_environment, project: project) } + + before do + stub_licensed_features(custom_roles: true) + sign_in(user) + end + + shared_context 'with protected environment value' do |env| + let_it_be(:role) { create(:member_role, :guest, namespace: group, admin_protected_environments: env) } + let_it_be(:member) { create(:project_member, :guest, member_role: role, user: user, project: project) } + end + + describe Projects::Settings::CiCdController do + let(:settings_page_path) { project_settings_ci_cd_path(project) } + let(:update_params) { { namespace_id: project.namespace, project_id: project } } + + context 'when user has protected environment access' do + include_context 'with protected environment value', true + + describe '#GET show' do + subject(:view_settings_page) { get settings_page_path } + + it 'displays the CI/CD settings page successfully' do + view_settings_page + + expect(response).to have_gitlab_http_status(:ok) + expect(response.body).to include('CI/CD Settings') + end + end + + describe '#PUT update' do + subject(:update_settings) { put settings_page_path, params: update_params } + + it 'prevents modification of CI/CD settings' do + update_settings + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when user lacks protected environment access' do + include_context 'with protected environment value', false + + describe '#GET show' do + subject(:view_settings_page) { get settings_page_path } + + it 'denies access to the CI/CD settings page' do + view_settings_page + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#PUT update' do + subject(:update_settings) { put settings_page_path, params: update_params } + + it 'prevents modification of CI/CD settings' do + update_settings + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end + + describe Projects::ProtectedEnvironmentsController do + let(:environment_params) do + { + name: 'testenv', + deploy_access_levels_attributes: [ + { access_level: Gitlab::Access::DEVELOPER } + ] + } + end + + let(:base_path) { project_protected_environments_path(project) } + let(:environment_path) { project_protected_environment_path(project, protected_environment) } + let(:search_path) { search_project_protected_environments_path(project) } + + context 'when user has protected environment access' do + include_context 'with protected environment value', true + + describe '#POST create' do + subject(:create_environment) { post base_path, params: { protected_environment: environment_params } } + + it 'creates a new protected environment' do + create_environment + + expect(response).to have_gitlab_http_status(:found) + expect(flash[:notice]).to eq('Your environment has been protected.') + end + end + + describe '#PUT update' do + subject(:update_environment) { put environment_path, params: { protected_environment: environment_params } } + + it 'updates the protected environment' do + update_environment + + expect(response).to have_gitlab_http_status(:ok) + end + end + + describe '#DELETE destroy' do + subject(:delete_environment) { delete environment_path } + + it 'removes the protected environment' do + delete_environment + + expect(response).to have_gitlab_http_status(:found) + expect(flash[:notice]).to eq('Your environment has been unprotected') + end + end + + describe '#GET search' do + subject(:search_environments) { get search_path, params: { query: 'prod' } } + + it 'performs environment search' do + search_environments + + expect(response).to have_gitlab_http_status(:ok) + end + end + end + + context 'when user lacks protected environment access' do + include_context 'with protected environment value', false + + describe '#POST create' do + subject(:create_environment) { post base_path, params: { protected_environment: environment_params } } + + it 'denies environment creation' do + create_environment + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#PUT update' do + subject(:update_environment) { put environment_path, params: { protected_environment: environment_params } } + + it 'denies environment update' do + update_environment + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#DELETE destroy' do + subject(:delete_environment) { delete environment_path } + + it 'denies environment deletion' do + delete_environment + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe '#GET search' do + subject(:search_environments) { get search_path, params: { query: 'prod' } } + + it 'denies environment search' do + search_environments + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end +end -- GitLab