diff options
Diffstat (limited to 'spec/policies')
-rw-r--r-- | spec/policies/ci/trigger_policy_spec.rb | 94 | ||||
-rw-r--r-- | spec/policies/clusters/instance_policy_spec.rb | 4 | ||||
-rw-r--r-- | spec/policies/global_policy_spec.rb | 28 | ||||
-rw-r--r-- | spec/policies/group_member_policy_spec.rb | 2 | ||||
-rw-r--r-- | spec/policies/group_policy_spec.rb | 142 | ||||
-rw-r--r-- | spec/policies/namespace/root_storage_statistics_policy_spec.rb | 80 | ||||
-rw-r--r-- | spec/policies/namespace_policy_spec.rb | 2 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 133 |
8 files changed, 393 insertions, 92 deletions
diff --git a/spec/policies/ci/trigger_policy_spec.rb b/spec/policies/ci/trigger_policy_spec.rb index d8a63066265..e9a85890082 100644 --- a/spec/policies/ci/trigger_policy_spec.rb +++ b/spec/policies/ci/trigger_policy_spec.rb @@ -3,52 +3,24 @@ require 'spec_helper' describe Ci::TriggerPolicy do let(:user) { create(:user) } let(:project) { create(:project) } - let(:trigger) { create(:ci_trigger, project: project, owner: owner) } + let(:trigger) { create(:ci_trigger, project: project, owner: create(:user)) } - let(:policies) do - described_class.new(user, trigger) - end - - shared_examples 'allows to admin and manage trigger' do - it 'does include ability to admin trigger' do - expect(policies).to be_allowed :admin_trigger - end - - it 'does include ability to manage trigger' do - expect(policies).to be_allowed :manage_trigger - end - end - - shared_examples 'allows to manage trigger' do - it 'does not include ability to admin trigger' do - expect(policies).not_to be_allowed :admin_trigger - end - - it 'does include ability to manage trigger' do - expect(policies).to be_allowed :manage_trigger - end - end - - shared_examples 'disallows to admin and manage trigger' do - it 'does not include ability to admin trigger' do - expect(policies).not_to be_allowed :admin_trigger - end - - it 'does not include ability to manage trigger' do - expect(policies).not_to be_allowed :manage_trigger - end - end + subject { described_class.new(user, trigger) } describe '#rules' do context 'when owner is undefined' do - let(:owner) { nil } + before do + stub_feature_flags(use_legacy_pipeline_triggers: false) + trigger.update_attribute(:owner, nil) + end context 'when user is maintainer of the project' do before do project.add_maintainer(user) end - it_behaves_like 'allows to admin and manage trigger' + it { is_expected.to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } end context 'when user is developer of the project' do @@ -56,35 +28,63 @@ describe Ci::TriggerPolicy do project.add_developer(user) end - it_behaves_like 'disallows to admin and manage trigger' + it { is_expected.not_to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } end - context 'when user is not member of the project' do - it_behaves_like 'disallows to admin and manage trigger' + context 'when :use_legacy_pipeline_triggers feature flag is enabled' do + before do + stub_feature_flags(use_legacy_pipeline_triggers: true) + end + + context 'when user is maintainer of the project' do + before do + project.add_maintainer(user) + end + + it { is_expected.to be_allowed(:manage_trigger) } + it { is_expected.to be_allowed(:admin_trigger) } + end + + context 'when user is developer of the project' do + before do + project.add_developer(user) + end + + it { is_expected.not_to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } + end + + context 'when user is not member of the project' do + it { is_expected.not_to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } + end end end context 'when owner is an user' do - let(:owner) { user } + before do + trigger.update!(owner: user) + end context 'when user is maintainer of the project' do before do project.add_maintainer(user) end - it_behaves_like 'allows to admin and manage trigger' + it { is_expected.to be_allowed(:manage_trigger) } + it { is_expected.to be_allowed(:admin_trigger) } end end context 'when owner is another user' do - let(:owner) { create(:user) } - context 'when user is maintainer of the project' do before do project.add_maintainer(user) end - it_behaves_like 'allows to manage trigger' + it { is_expected.to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } end context 'when user is developer of the project' do @@ -92,11 +92,13 @@ describe Ci::TriggerPolicy do project.add_developer(user) end - it_behaves_like 'disallows to admin and manage trigger' + it { is_expected.not_to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } end context 'when user is not member of the project' do - it_behaves_like 'disallows to admin and manage trigger' + it { is_expected.not_to be_allowed(:manage_trigger) } + it { is_expected.not_to be_allowed(:admin_trigger) } end end end diff --git a/spec/policies/clusters/instance_policy_spec.rb b/spec/policies/clusters/instance_policy_spec.rb index 7b61819e079..2373fef8aa6 100644 --- a/spec/policies/clusters/instance_policy_spec.rb +++ b/spec/policies/clusters/instance_policy_spec.rb @@ -9,6 +9,8 @@ describe Clusters::InstancePolicy do describe 'rules' do context 'when user' do it { expect(policy).to be_disallowed :read_cluster } + it { expect(policy).to be_disallowed :add_cluster } + it { expect(policy).to be_disallowed :create_cluster } it { expect(policy).to be_disallowed :update_cluster } it { expect(policy).to be_disallowed :admin_cluster } end @@ -17,6 +19,8 @@ describe Clusters::InstancePolicy do let(:user) { create(:admin) } it { expect(policy).to be_allowed :read_cluster } + it { expect(policy).to be_allowed :add_cluster } + it { expect(policy).to be_allowed :create_cluster } it { expect(policy).to be_allowed :update_cluster } it { expect(policy).to be_allowed :admin_cluster } end diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb index 12be3927e18..df6cc526eb0 100644 --- a/spec/policies/global_policy_spec.rb +++ b/spec/policies/global_policy_spec.rb @@ -226,4 +226,32 @@ describe GlobalPolicy do it { is_expected.not_to be_allowed(:read_instance_statistics) } end end + + describe 'slash commands' do + context 'regular user' do + it { is_expected.to be_allowed(:use_slash_commands) } + end + + context 'when internal' do + let(:current_user) { User.ghost } + + it { is_expected.not_to be_allowed(:use_slash_commands) } + end + + context 'when blocked' do + before do + current_user.block + end + + it { is_expected.not_to be_allowed(:use_slash_commands) } + end + + context 'when access locked' do + before do + current_user.lock_access! + end + + it { is_expected.not_to be_allowed(:use_slash_commands) } + end + end end diff --git a/spec/policies/group_member_policy_spec.rb b/spec/policies/group_member_policy_spec.rb index 7bd7184cffe..a4f3301a064 100644 --- a/spec/policies/group_member_policy_spec.rb +++ b/spec/policies/group_member_policy_spec.rb @@ -58,7 +58,7 @@ describe GroupMemberPolicy do end end - context 'with the group parent', :postgresql do + context 'with the group parent' do let(:current_user) { create :user } let(:subgroup) { create(:group, :private, parent: group)} diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 59f3a961d50..be55d94daec 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -51,7 +51,7 @@ describe GroupPolicy do it { expect_allowed(:read_label, :read_list) } - context 'in subgroups', :nested_groups do + context 'in subgroups' do let(:subgroup) { create(:group, :private, parent: group) } let(:project) { create(:project, namespace: subgroup) } @@ -98,12 +98,34 @@ describe GroupPolicy do context 'maintainer' do let(:current_user) { maintainer } - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_allowed(*developer_permissions) - expect_allowed(*maintainer_permissions) - expect_disallowed(*owner_permissions) + context 'with subgroup_creation level set to maintainer' do + let(:group) do + create(:group, :private, subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) + end + + it 'allows every maintainer permission plus creating subgroups' do + create_subgroup_permission = [:create_subgroup] + updated_maintainer_permissions = + maintainer_permissions + create_subgroup_permission + updated_owner_permissions = + owner_permissions - create_subgroup_permission + + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*developer_permissions) + expect_allowed(*updated_maintainer_permissions) + expect_disallowed(*updated_owner_permissions) + end + end + + context 'with subgroup_creation_level set to owner' do + it 'allows every maintainer permission' do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*developer_permissions) + expect_allowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + end end end @@ -111,8 +133,6 @@ describe GroupPolicy do let(:current_user) { owner } it do - allow(Group).to receive(:supports_nested_objects?).and_return(true) - expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -125,8 +145,6 @@ describe GroupPolicy do let(:current_user) { admin } it do - allow(Group).to receive(:supports_nested_objects?).and_return(true) - expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -135,38 +153,10 @@ describe GroupPolicy do end end - describe 'when nested group support feature is disabled' do - before do - allow(Group).to receive(:supports_nested_objects?).and_return(false) - end - - context 'admin' do - let(:current_user) { admin } - - it 'allows every owner permission except creating subgroups' do - create_subgroup_permission = [:create_subgroup] - updated_owner_permissions = owner_permissions - create_subgroup_permission - - expect_disallowed(*create_subgroup_permission) - expect_allowed(*updated_owner_permissions) - end - end - - context 'owner' do - let(:current_user) { owner } - - it 'allows every owner permission except creating subgroups' do - create_subgroup_permission = [:create_subgroup] - updated_owner_permissions = owner_permissions - create_subgroup_permission - - expect_disallowed(*create_subgroup_permission) - expect_allowed(*updated_owner_permissions) - end + describe 'private nested group use the highest access level from the group and inherited permissions' do + let(:nested_group) do + create(:group, :private, :owner_subgroup_creation_only, parent: group) end - end - - describe 'private nested group use the highest access level from the group and inherited permissions', :nested_groups do - let(:nested_group) { create(:group, :private, parent: group) } before do nested_group.add_guest(guest) @@ -246,8 +236,6 @@ describe GroupPolicy do let(:current_user) { owner } it do - allow(Group).to receive(:supports_nested_objects?).and_return(true) - expect_allowed(*guest_permissions) expect_allowed(*reporter_permissions) expect_allowed(*developer_permissions) @@ -461,6 +449,72 @@ describe GroupPolicy do end end + context "create_subgroup" do + context 'when group has subgroup creation level set to owner' do + let(:group) do + create( + :group, + subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS) + end + + context 'reporter' do + let(:current_user) { reporter } + + it { is_expected.to be_disallowed(:create_subgroup) } + end + + context 'developer' do + let(:current_user) { developer } + + it { is_expected.to be_disallowed(:create_subgroup) } + end + + context 'maintainer' do + let(:current_user) { maintainer } + + it { is_expected.to be_disallowed(:create_subgroup) } + end + + context 'owner' do + let(:current_user) { owner } + + it { is_expected.to be_allowed(:create_subgroup) } + end + end + + context 'when group has subgroup creation level set to maintainer' do + let(:group) do + create( + :group, + subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS) + end + + context 'reporter' do + let(:current_user) { reporter } + + it { is_expected.to be_disallowed(:create_subgroup) } + end + + context 'developer' do + let(:current_user) { developer } + + it { is_expected.to be_disallowed(:create_subgroup) } + end + + context 'maintainer' do + let(:current_user) { maintainer } + + it { is_expected.to be_allowed(:create_subgroup) } + end + + context 'owner' do + let(:current_user) { owner } + + it { is_expected.to be_allowed(:create_subgroup) } + end + end + end + it_behaves_like 'clusterable policies' do let(:clusterable) { create(:group) } let(:cluster) do diff --git a/spec/policies/namespace/root_storage_statistics_policy_spec.rb b/spec/policies/namespace/root_storage_statistics_policy_spec.rb new file mode 100644 index 00000000000..8d53050fffb --- /dev/null +++ b/spec/policies/namespace/root_storage_statistics_policy_spec.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Namespace::RootStorageStatisticsPolicy do + using RSpec::Parameterized::TableSyntax + + describe '#rules' do + let(:statistics) { create(:namespace_root_storage_statistics, namespace: namespace) } + let(:user) { create(:user) } + + subject { Ability.allowed?(user, :read_statistics, statistics) } + + shared_examples 'deny anonymous users' do + context 'when the users is anonymous' do + let(:user) { nil } + + it { is_expected.to be_falsey } + end + end + + context 'when the namespace is a personal namespace' do + let(:owner) { create(:user) } + let(:namespace) { owner.namespace } + + include_examples 'deny anonymous users' + + context 'when the user is not the owner' do + it { is_expected.to be_falsey } + end + + context 'when the user is the owner' do + let(:user) { owner } + + it { is_expected.to be_truthy } + end + end + + context 'when the namespace is a group' do + let(:user) { create(:user) } + let(:external) { create(:user, :external) } + + shared_examples 'allows only owners' do |group_type| + let(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel.level_value(group_type.to_s)) } + let(:namespace) { group } + + include_examples 'deny anonymous users' + + where(:user_type, :outcome) do + [ + [:non_member, false], + [:guest, false], + [:reporter, false], + [:developer, false], + [:maintainer, false], + [:owner, true] + ] + end + + with_them do + before do + group.add_user(user, user_type) unless user_type == :non_member + end + + it { is_expected.to eq(outcome) } + + context 'when the user is external' do + let(:user) { external } + + it { is_expected.to eq(outcome) } + end + end + end + + include_examples 'allows only owners', :public + include_examples 'allows only owners', :private + include_examples 'allows only owners', :internal + end + end +end diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb index 99fa8b1fe44..216aaae70ee 100644 --- a/spec/policies/namespace_policy_spec.rb +++ b/spec/policies/namespace_policy_spec.rb @@ -6,7 +6,7 @@ describe NamespacePolicy do let(:admin) { create(:admin) } let(:namespace) { create(:namespace, owner: owner) } - let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace] } + let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace, :read_statistics] } subject { described_class.new(current_user, namespace) } diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index fd82150c12a..71ba73d5661 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -94,6 +94,19 @@ describe ProjectPolicy do permissions.each { |p| is_expected.not_to be_allowed(p) } end + context 'with no project feature' do + subject { described_class.new(owner, project) } + + before do + project.project_feature.destroy + project.reload + end + + it 'returns false' do + is_expected.to be_disallowed(:read_build) + end + end + it 'does not include the read_issue permission when the issue author is not a member of the private project' do project = create(:project, :private) issue = create(:issue, project: project, author: create(:user)) @@ -126,6 +139,126 @@ describe ProjectPolicy do end end end + + describe 'read_wiki' do + subject { described_class.new(user, project) } + + member_roles = %i[guest developer] + stranger_roles = %i[anonymous non_member] + + user_roles = stranger_roles + member_roles + + # When a user is anonymous, their `current_user == nil` + let(:user) { create(:user) unless user_role == :anonymous } + + before do + project.visibility = project_visibility + project.project_feature.update_attribute(:wiki_access_level, wiki_access_level) + project.add_user(user, user_role) if member_roles.include?(user_role) + end + + title = ->(project_visibility, wiki_access_level, user_role) do + [ + "project is #{Gitlab::VisibilityLevel.level_name project_visibility}", + "wiki is #{ProjectFeature.str_from_access_level wiki_access_level}", + "user is #{user_role}" + ].join(', ') + end + + describe 'Situations where :read_wiki is always false' do + where(case_names: title, + project_visibility: Gitlab::VisibilityLevel.options.values, + wiki_access_level: [ProjectFeature::DISABLED], + user_role: user_roles) + + with_them do + it { is_expected.to be_disallowed(:read_wiki) } + end + end + + describe 'Situations where :read_wiki is always true' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::PUBLIC], + wiki_access_level: [ProjectFeature::ENABLED], + user_role: user_roles) + + with_them do + it { is_expected.to be_allowed(:read_wiki) } + end + end + + describe 'Situations where :read_wiki requires project membership' do + context 'the wiki is private, and the user is a member' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::PUBLIC, + Gitlab::VisibilityLevel::INTERNAL], + wiki_access_level: [ProjectFeature::PRIVATE], + user_role: member_roles) + + with_them do + it { is_expected.to be_allowed(:read_wiki) } + end + end + + context 'the wiki is private, and the user is not member' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::PUBLIC, + Gitlab::VisibilityLevel::INTERNAL], + wiki_access_level: [ProjectFeature::PRIVATE], + user_role: stranger_roles) + + with_them do + it { is_expected.to be_disallowed(:read_wiki) } + end + end + + context 'the wiki is enabled, and the user is a member' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::PRIVATE], + wiki_access_level: [ProjectFeature::ENABLED], + user_role: member_roles) + + with_them do + it { is_expected.to be_allowed(:read_wiki) } + end + end + + context 'the wiki is enabled, and the user is not a member' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::PRIVATE], + wiki_access_level: [ProjectFeature::ENABLED], + user_role: stranger_roles) + + with_them do + it { is_expected.to be_disallowed(:read_wiki) } + end + end + end + + describe 'Situations where :read_wiki prohibits anonymous access' do + context 'the user is not anonymous' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::INTERNAL], + wiki_access_level: [ProjectFeature::ENABLED, ProjectFeature::PUBLIC], + user_role: user_roles.reject { |u| u == :anonymous }) + + with_them do + it { is_expected.to be_allowed(:read_wiki) } + end + end + + context 'the user is not anonymous' do + where(case_names: title, + project_visibility: [Gitlab::VisibilityLevel::INTERNAL], + wiki_access_level: [ProjectFeature::ENABLED, ProjectFeature::PUBLIC], + user_role: %i[anonymous]) + + with_them do + it { is_expected.to be_disallowed(:read_wiki) } + end + end + end + end end context 'issues feature' do |