diff options
Diffstat (limited to 'spec/policies')
-rw-r--r-- | spec/policies/ci/build_policy_spec.rb | 32 | ||||
-rw-r--r-- | spec/policies/ci/pipeline_policy_spec.rb | 2 | ||||
-rw-r--r-- | spec/policies/ci/pipeline_schedule_policy_spec.rb | 6 | ||||
-rw-r--r-- | spec/policies/concerns/crud_policy_helpers_spec.rb | 50 | ||||
-rw-r--r-- | spec/policies/concerns/readonly_abilities_spec.rb | 27 | ||||
-rw-r--r-- | spec/policies/design_management/design_policy_spec.rb | 53 | ||||
-rw-r--r-- | spec/policies/group_deploy_key_policy_spec.rb | 27 | ||||
-rw-r--r-- | spec/policies/group_deploy_keys_group_policy_spec.rb | 24 | ||||
-rw-r--r-- | spec/policies/group_policy_spec.rb | 20 | ||||
-rw-r--r-- | spec/policies/issue_policy_spec.rb | 6 | ||||
-rw-r--r-- | spec/policies/merge_request_policy_spec.rb | 6 | ||||
-rw-r--r-- | spec/policies/personal_access_token_policy_spec.rb | 63 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 16 | ||||
-rw-r--r-- | spec/policies/user_policy_spec.rb | 28 |
14 files changed, 317 insertions, 43 deletions
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb index d2547338855..098efd7daa6 100644 --- a/spec/policies/ci/build_policy_spec.rb +++ b/spec/policies/ci/build_policy_spec.rb @@ -146,7 +146,7 @@ RSpec.describe Ci::BuildPolicy do create(:protected_tag, :no_one_can_create, name: build.ref, project: project) - build.update(tag: true) + build.update!(tag: true) end it 'does not include ability to update build' do @@ -247,6 +247,36 @@ RSpec.describe Ci::BuildPolicy do it { expect(policy).to be_disallowed :erase_build } end end + + context 'when an admin erases a build', :enable_admin_mode do + let(:owner) { create(:user) } + + before do + user.update!(admin: true) + end + + context 'when the build was created for a protected branch' do + before do + create(:protected_branch, :developers_can_push, + name: build.ref, project: project) + end + + it { expect(policy).to be_allowed :erase_build } + end + + context 'when the build was created for a protected tag' do + before do + create(:protected_tag, :developers_can_create, + name: build.ref, project: project) + end + + it { expect(policy).to be_allowed :erase_build } + end + + context 'when the build was created for an unprotected ref' do + it { expect(policy).to be_allowed :erase_build } + end + end end end diff --git a/spec/policies/ci/pipeline_policy_spec.rb b/spec/policies/ci/pipeline_policy_spec.rb index fcd96bc6653..9a65823c950 100644 --- a/spec/policies/ci/pipeline_policy_spec.rb +++ b/spec/policies/ci/pipeline_policy_spec.rb @@ -45,7 +45,7 @@ RSpec.describe Ci::PipelinePolicy, :models do create(:protected_tag, :no_one_can_create, name: pipeline.ref, project: project) - pipeline.update(tag: true) + pipeline.update!(tag: true) end it 'does not include ability to update pipeline' do diff --git a/spec/policies/ci/pipeline_schedule_policy_spec.rb b/spec/policies/ci/pipeline_schedule_policy_spec.rb index b455384d17a..1e36f455f6f 100644 --- a/spec/policies/ci/pipeline_schedule_policy_spec.rb +++ b/spec/policies/ci/pipeline_schedule_policy_spec.rb @@ -43,7 +43,7 @@ RSpec.describe Ci::PipelineSchedulePolicy, :models do let(:tag) { 'v1.0.0' } before do - pipeline_schedule.update(ref: tag) + pipeline_schedule.update!(ref: tag) create(:protected_tag, :no_one_can_create, name: pipeline_schedule.ref, project: project) @@ -69,7 +69,7 @@ RSpec.describe Ci::PipelineSchedulePolicy, :models do describe 'rules for owner of schedule' do before do project.add_developer(user) - pipeline_schedule.update(owner: user) + pipeline_schedule.update!(owner: user) end it 'includes abilities to do all operations on pipeline schedule' do @@ -97,7 +97,7 @@ RSpec.describe Ci::PipelineSchedulePolicy, :models do before do project.add_maintainer(owner) project.add_maintainer(user) - pipeline_schedule.update(owner: owner) + pipeline_schedule.update!(owner: owner) end it 'includes abilities to take ownership' do diff --git a/spec/policies/concerns/crud_policy_helpers_spec.rb b/spec/policies/concerns/crud_policy_helpers_spec.rb new file mode 100644 index 00000000000..69bf9ad12d6 --- /dev/null +++ b/spec/policies/concerns/crud_policy_helpers_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe CrudPolicyHelpers do + let(:policy_test_class) do + Class.new do + include CrudPolicyHelpers + end + end + + let(:feature_name) { :foo } + + before do + stub_const('PolicyTestClass', policy_test_class) + end + + describe '.create_read_update_admin_destroy' do + it 'returns an array of the appropriate abilites given a feature name' do + expect(PolicyTestClass.create_read_update_admin_destroy(feature_name)).to eq([ + :read_foo, + :create_foo, + :update_foo, + :admin_foo, + :destroy_foo + ]) + end + end + + describe '.create_update_admin_destroy' do + it 'returns an array of the appropriate abilites given a feature name' do + expect(PolicyTestClass.create_update_admin_destroy(feature_name)).to eq([ + :create_foo, + :update_foo, + :admin_foo, + :destroy_foo + ]) + end + end + + describe '.create_update_admin' do + it 'returns an array of the appropriate abilites given a feature name' do + expect(PolicyTestClass.create_update_admin(feature_name)).to eq([ + :create_foo, + :update_foo, + :admin_foo + ]) + end + end +end diff --git a/spec/policies/concerns/readonly_abilities_spec.rb b/spec/policies/concerns/readonly_abilities_spec.rb new file mode 100644 index 00000000000..864924a091d --- /dev/null +++ b/spec/policies/concerns/readonly_abilities_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ReadonlyAbilities do + let(:test_class) do + Class.new do + include ReadonlyAbilities + end + end + + before do + stub_const('TestClass', test_class) + end + + describe '.readonly_abilities' do + it 'returns an array of abilites to be prevented when readonly' do + expect(TestClass.readonly_abilities).to include(*described_class::READONLY_ABILITIES) + end + end + + describe '.readonly_features' do + it 'returns an array of features to be prevented when readonly' do + expect(TestClass.readonly_features).to include(*described_class::READONLY_FEATURES) + end + end +end diff --git a/spec/policies/design_management/design_policy_spec.rb b/spec/policies/design_management/design_policy_spec.rb index 5dde5f896c9..5cf2f376edf 100644 --- a/spec/policies/design_management/design_policy_spec.rb +++ b/spec/policies/design_management/design_policy_spec.rb @@ -1,22 +1,32 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe DesignManagement::DesignPolicy do include DesignManagementTestHelpers - include_context 'ProjectPolicy context' - let(:guest_design_abilities) { %i[read_design] } - let(:developer_design_abilities) do - %i[create_design destroy_design] - end + let(:developer_design_abilities) { %i[create_design destroy_design move_design] } let(:design_abilities) { guest_design_abilities + developer_design_abilities } - let(:issue) { create(:issue, project: project) } + let_it_be(:guest) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:owner) { create(:user) } + let_it_be(:admin) { create(:admin) } + let_it_be(:project) { create(:project, :public, namespace: owner.namespace) } + let_it_be(:issue) { create(:issue, project: project) } let(:design) { create(:design, issue: issue) } subject(:design_policy) { described_class.new(current_user, design) } + before_all do + project.add_guest(guest) + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + end + shared_examples_for "design abilities not available" do context "for owners" do let(:current_user) { owner } @@ -71,11 +81,11 @@ RSpec.describe DesignManagement::DesignPolicy do context "for admins" do let(:current_user) { admin } - context 'when admin mode enabled', :enable_admin_mode do + context "when admin mode enabled", :enable_admin_mode do it { is_expected.to be_allowed(*design_abilities) } end - context 'when admin mode disabled' do + context "when admin mode disabled" do it { is_expected.to be_allowed(*guest_design_abilities) } it { is_expected.to be_disallowed(*developer_design_abilities) } end @@ -121,8 +131,19 @@ RSpec.describe DesignManagement::DesignPolicy do it_behaves_like "design abilities available for members" + context 'when reorder_designs is not enabled' do + before do + stub_feature_flags(reorder_designs: false) + end + + let(:current_user) { developer } + + it { is_expected.to be_allowed(*(developer_design_abilities - [:move_design])) } + it { is_expected.to be_disallowed(:move_design) } + end + context "for guests in private projects" do - let(:project) { create(:project, :private) } + let_it_be(:project) { create(:project, :private) } let(:current_user) { guest } it { is_expected.to be_allowed(*guest_design_abilities) } @@ -137,7 +158,7 @@ RSpec.describe DesignManagement::DesignPolicy do end context "when the issue is confidential" do - let(:issue) { create(:issue, :confidential, project: project) } + let_it_be(:issue) { create(:issue, :confidential, project: project) } it_behaves_like "design abilities available for members" @@ -155,26 +176,24 @@ RSpec.describe DesignManagement::DesignPolicy do end context "when the issue is locked" do + let_it_be(:issue) { create(:issue, :locked, project: project) } let(:current_user) { owner } - let(:issue) { create(:issue, :locked, project: project) } it_behaves_like "read-only design abilities" end context "when the issue has moved" do + let_it_be(:issue) { create(:issue, project: project, moved_to: create(:issue)) } let(:current_user) { owner } - let(:issue) { create(:issue, project: project, moved_to: create(:issue)) } it_behaves_like "read-only design abilities" end context "when the project is archived" do + let_it_be(:project) { create(:project, :public, :archived) } + let_it_be(:issue) { create(:issue, project: project) } let(:current_user) { owner } - before do - project.update!(archived: true) - end - it_behaves_like "read-only design abilities" end end diff --git a/spec/policies/group_deploy_key_policy_spec.rb b/spec/policies/group_deploy_key_policy_spec.rb new file mode 100644 index 00000000000..c3903a3fa55 --- /dev/null +++ b/spec/policies/group_deploy_key_policy_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GroupDeployKeyPolicy do + subject { described_class.new(user, group_deploy_key) } + + let_it_be(:user) { create(:user) } + + describe 'edit a group deploy key' do + context 'when the user does not own the group deploy key' do + let(:group_deploy_key) { create(:group_deploy_key) } + + it { is_expected.to be_disallowed(:update_group_deploy_key) } + end + + context 'when the user owns the group deploy key' do + let(:group_deploy_key) { create(:group_deploy_key, user: user) } + + before do + user.reload + end + + it { is_expected.to be_allowed(:update_group_deploy_key) } + end + end +end diff --git a/spec/policies/group_deploy_keys_group_policy_spec.rb b/spec/policies/group_deploy_keys_group_policy_spec.rb new file mode 100644 index 00000000000..7ad9b655411 --- /dev/null +++ b/spec/policies/group_deploy_keys_group_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GroupDeployKeysGroupPolicy do + subject { described_class.new(user, group_deploy_keys_group) } + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:group_deploy_key) { create(:group_deploy_key) } + let(:group_deploy_keys_group) { create(:group_deploy_keys_group, group: group, group_deploy_key: group_deploy_key) } + + describe 'edit a group deploy key for a given group' do + it 'is allowed when the user is an owner of this group' do + group.add_owner(user) + + expect(subject).to be_allowed(:update_group_deploy_key_for_group) + end + + it 'is not allowed when the user is not an owner of this group' do + expect(subject).to be_disallowed(:update_group_deploy_key_for_group) + end + end +end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 9bd692b45c3..3e0ea164e3d 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -137,7 +137,7 @@ RSpec.describe GroupPolicy do context 'with subgroup_creation level set to maintainer' do before_all do - group.update(subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) + group.update!(subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) end it 'allows every maintainer permission plus creating subgroups' do @@ -409,7 +409,7 @@ RSpec.describe GroupPolicy do context 'transfer_projects' do shared_examples_for 'allowed to transfer projects' do before do - group.update(project_creation_level: project_creation_level) + group.update!(project_creation_level: project_creation_level) end it { is_expected.to be_allowed(:transfer_projects) } @@ -417,7 +417,7 @@ RSpec.describe GroupPolicy do shared_examples_for 'not allowed to transfer projects' do before do - group.update(project_creation_level: project_creation_level) + group.update!(project_creation_level: project_creation_level) end it { is_expected.to be_disallowed(:transfer_projects) } @@ -491,7 +491,7 @@ RSpec.describe GroupPolicy do context 'create_projects' do context 'when group has no project creation level set' do before_all do - group.update(project_creation_level: nil) + group.update!(project_creation_level: nil) end context 'reporter' do @@ -521,7 +521,7 @@ RSpec.describe GroupPolicy do context 'when group has project creation level set to no one' do before_all do - group.update(project_creation_level: ::Gitlab::Access::NO_ONE_PROJECT_ACCESS) + group.update!(project_creation_level: ::Gitlab::Access::NO_ONE_PROJECT_ACCESS) end context 'reporter' do @@ -551,7 +551,7 @@ RSpec.describe GroupPolicy do context 'when group has project creation level set to maintainer only' do before_all do - group.update(project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) + group.update!(project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) end context 'reporter' do @@ -581,7 +581,7 @@ RSpec.describe GroupPolicy do context 'when group has project creation level set to developers + maintainer' do before_all do - group.update(project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + group.update!(project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) end context 'reporter' do @@ -613,7 +613,7 @@ RSpec.describe GroupPolicy do context 'create_subgroup' do context 'when group has subgroup creation level set to owner' do before_all do - group.update(subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS) + group.update!(subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS) end context 'reporter' do @@ -643,7 +643,7 @@ RSpec.describe GroupPolicy do context 'when group has subgroup creation level set to maintainer' do before_all do - group.update(subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) + group.update!(subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) end context 'reporter' do @@ -752,7 +752,7 @@ RSpec.describe GroupPolicy do context 'which does not have design management enabled' do before do - project.update(lfs_enabled: false) + project.update!(lfs_enabled: false) end it { is_expected.not_to be_allowed(:read_design_activity) } diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb index b3ca37b17c2..e352b990159 100644 --- a/spec/policies/issue_policy_spec.rb +++ b/spec/policies/issue_policy_spec.rb @@ -104,7 +104,7 @@ RSpec.describe IssuePolicy do end it 'does not allow issue author to read or update confidential issue moved to an private project' do - confidential_issue.project = build(:project, :private) + confidential_issue.project = create(:project, :private) expect(permissions(author, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue) end @@ -117,7 +117,7 @@ RSpec.describe IssuePolicy do end it 'does not allow issue assignees to read or update confidential issue moved to an private project' do - confidential_issue.project = build(:project, :private) + confidential_issue.project = create(:project, :private) expect(permissions(assignee, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue) end @@ -188,7 +188,7 @@ RSpec.describe IssuePolicy do context 'when issues are private' do before do - project.project_feature.update(issues_access_level: ProjectFeature::PRIVATE) + project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) end let(:issue) { create(:issue, project: project, author: author) } let(:visitor) { create(:user) } diff --git a/spec/policies/merge_request_policy_spec.rb b/spec/policies/merge_request_policy_spec.rb index 2f3cb2e998a..3a46d5b9226 100644 --- a/spec/policies/merge_request_policy_spec.rb +++ b/spec/policies/merge_request_policy_spec.rb @@ -51,7 +51,7 @@ RSpec.describe MergeRequestPolicy do let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: author) } before do - project.project_feature.update(merge_requests_access_level: ProjectFeature::DISABLED) + project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) end describe 'the author' do @@ -83,8 +83,8 @@ RSpec.describe MergeRequestPolicy do let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: author) } before do - project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - project.project_feature.update(merge_requests_access_level: ProjectFeature::PRIVATE) + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + project.project_feature.update!(merge_requests_access_level: ProjectFeature::PRIVATE) end describe 'a non-team-member' do diff --git a/spec/policies/personal_access_token_policy_spec.rb b/spec/policies/personal_access_token_policy_spec.rb new file mode 100644 index 00000000000..71795202e13 --- /dev/null +++ b/spec/policies/personal_access_token_policy_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe PersonalAccessTokenPolicy do + include AdminModeHelper + + subject { described_class.new(current_user, token) } + + context 'current_user is an administrator', :enable_admin_mode do + let_it_be(:current_user) { build(:admin) } + + context 'not the owner of the token' do + let_it_be(:token) { build(:personal_access_token) } + + it { is_expected.to be_allowed(:read_token) } + it { is_expected.to be_allowed(:revoke_token) } + end + + context 'owner of the token' do + let_it_be(:token) { build(:personal_access_token, user: current_user) } + + it { is_expected.to be_allowed(:read_token) } + it { is_expected.to be_allowed(:revoke_token) } + end + end + + context 'current_user is not an administrator' do + let_it_be(:current_user) { build(:user) } + + context 'not the owner of the token' do + let_it_be(:token) { build(:personal_access_token) } + + it { is_expected.to be_disallowed(:read_token) } + it { is_expected.to be_disallowed(:revoke_token) } + end + + context 'owner of the token' do + let_it_be(:token) { build(:personal_access_token, user: current_user) } + + it { is_expected.to be_allowed(:read_token) } + it { is_expected.to be_allowed(:revoke_token) } + end + end + + context 'current_user is a blocked administrator', :enable_admin_mode do + let_it_be(:current_user) { build(:admin, :blocked) } + + context 'owner of the token' do + let_it_be(:token) { build(:personal_access_token, user: current_user) } + + it { is_expected.to be_disallowed(:read_token) } + it { is_expected.to be_disallowed(:revoke_token) } + end + + context 'not the owner of the token' do + let_it_be(:token) { build(:personal_access_token) } + + it { is_expected.to be_disallowed(:read_token) } + it { is_expected.to be_disallowed(:revoke_token) } + end + end +end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index dc6ed94309b..9879fc53461 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -20,7 +20,7 @@ RSpec.describe ProjectPolicy do read_project_for_iids read_issue_iid read_label read_milestone read_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in - award_emoji read_release + award_emoji read_release read_issue_link ] end @@ -30,7 +30,7 @@ RSpec.describe ProjectPolicy do admin_issue admin_label admin_list read_commit_status read_build read_container_image read_pipeline read_environment read_deployment read_merge_request download_wiki_code read_sentry_issue read_metrics_dashboard_annotation - metrics_dashboard read_confidential_issues + metrics_dashboard read_confidential_issues admin_issue_link ] end @@ -46,7 +46,7 @@ RSpec.describe ProjectPolicy do resolve_note create_container_image update_container_image destroy_container_image daily_statistics create_environment update_environment create_deployment update_deployment create_release update_release create_metrics_dashboard_annotation delete_metrics_dashboard_annotation update_metrics_dashboard_annotation - read_terraform_state + read_terraform_state read_pod_logs ] end @@ -105,7 +105,7 @@ RSpec.describe ProjectPolicy do subject { described_class.new(owner, project) } before do - project.project_feature.destroy + project.project_feature.destroy! project.reload end @@ -325,6 +325,7 @@ RSpec.describe ProjectPolicy do allow_collaboration: true ) end + let(:maintainer_abilities) do %w(create_build create_pipeline) end @@ -953,7 +954,12 @@ RSpec.describe ProjectPolicy do context 'when repository is disabled' do before do - project.project_feature.update(repository_access_level: ProjectFeature::DISABLED) + project.project_feature.update!( + # Disable merge_requests and builds as well, since merge_requests and + # builds cannot have higher visibility than repository. + merge_requests_access_level: ProjectFeature::DISABLED, + builds_access_level: ProjectFeature::DISABLED, + repository_access_level: ProjectFeature::DISABLED) end it { is_expected.to be_disallowed(:read_package) } diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb index 1cc3581ebdd..d7338622c86 100644 --- a/spec/policies/user_policy_spec.rb +++ b/spec/policies/user_policy_spec.rb @@ -12,6 +12,34 @@ RSpec.describe UserPolicy do it { is_expected.to be_allowed(:read_user) } end + describe "reading a different user's Personal Access Tokens" do + let(:token) { create(:personal_access_token, user: user) } + + context 'when user is admin' do + let(:current_user) { create(:user, :admin) } + + context 'when admin mode is enabled', :enable_admin_mode do + it { is_expected.to be_allowed(:read_user_personal_access_tokens) } + end + + context 'when admin mode is disabled' do + it { is_expected.not_to be_allowed(:read_user_personal_access_tokens) } + end + end + + context 'when user is not an admin' do + context 'requesting their own personal access tokens' do + subject { described_class.new(current_user, current_user) } + + it { is_expected.to be_allowed(:read_user_personal_access_tokens) } + end + + context "requesting a different user's personal access tokens" do + it { is_expected.not_to be_allowed(:read_user_personal_access_tokens) } + end + end + end + shared_examples 'changing a user' do |ability| context "when a regular user tries to destroy another regular user" do it { is_expected.not_to be_allowed(ability) } |