summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2019-03-28 06:42:50 +0000
committerLin Jen-Shin <godfat@godfat.org>2019-03-28 06:42:50 +0000
commit7753648a2e9e1e5407b729d650384961807b6e6f (patch)
tree3893775e3a6bf24fdd896e23de57e77fa3e1eefe
parent5a2be4c8a548331df011e9de0bc77d7bbe48f700 (diff)
parent65441cfdda18e1233021b2633552e101dd3b36a1 (diff)
downloadgitlab-ce-7753648a2e9e1e5407b729d650384961807b6e6f.tar.gz
Merge branch 'ce-reduce-ee-diff-in-spec-policies' into 'master'
[CE] Reduce diff with EE in `spec/policies` See merge request gitlab-org/gitlab-ce!26593
-rw-r--r--spec/policies/board_policy_spec.rb8
-rw-r--r--spec/policies/group_policy_spec.rb58
-rw-r--r--spec/policies/namespace_policy_spec.rb2
-rw-r--r--spec/policies/project_policy_spec.rb324
-rw-r--r--spec/policies/project_snippet_policy_spec.rb109
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/helpers/policy_helpers.rb11
-rw-r--r--spec/support/shared_context/policies/project_policy_shared_context.rb88
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb47
-rw-r--r--spec/support/shared_examples/policies/project_policy_shared_examples.rb231
10 files changed, 432 insertions, 447 deletions
diff --git a/spec/policies/board_policy_spec.rb b/spec/policies/board_policy_spec.rb
index 4b76d65ef69..52c23951e37 100644
--- a/spec/policies/board_policy_spec.rb
+++ b/spec/policies/board_policy_spec.rb
@@ -17,14 +17,6 @@ describe BoardPolicy do
]
end
- def expect_allowed(*permissions)
- permissions.each { |p| is_expected.to be_allowed(p) }
- end
-
- def expect_disallowed(*permissions)
- permissions.each { |p| is_expected.not_to be_allowed(p) }
- end
-
context 'group board' do
subject { described_class.new(user, group_board) }
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 92bdaa8b8b8..dc98baca6dc 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -1,63 +1,7 @@
require 'spec_helper'
describe GroupPolicy do
- let(:guest) { create(:user) }
- let(:reporter) { create(:user) }
- let(:developer) { create(:user) }
- let(:maintainer) { create(:user) }
- let(:owner) { create(:user) }
- let(:admin) { create(:admin) }
- let(:group) { create(:group, :private) }
-
- let(:guest_permissions) do
- [:read_label, :read_group, :upload_file, :read_namespace, :read_group_activity,
- :read_group_issues, :read_group_boards, :read_group_labels, :read_group_milestones,
- :read_group_merge_requests]
- end
-
- let(:reporter_permissions) { [:admin_label] }
-
- let(:developer_permissions) { [:admin_milestone] }
-
- let(:maintainer_permissions) do
- [
- :create_projects,
- :read_cluster,
- :create_cluster,
- :update_cluster,
- :admin_cluster,
- :add_cluster
- ]
- end
-
- let(:owner_permissions) do
- [
- :admin_group,
- :admin_namespace,
- :admin_group_member,
- :change_visibility_level,
- :set_note_created_at,
- (Gitlab::Database.postgresql? ? :create_subgroup : nil)
- ].compact
- end
-
- before do
- group.add_guest(guest)
- group.add_reporter(reporter)
- group.add_developer(developer)
- group.add_maintainer(maintainer)
- group.add_owner(owner)
- end
-
- subject { described_class.new(current_user, group) }
-
- def expect_allowed(*permissions)
- permissions.each { |p| is_expected.to be_allowed(p) }
- end
-
- def expect_disallowed(*permissions)
- permissions.each { |p| is_expected.not_to be_allowed(p) }
- end
+ include_context 'GroupPolicy context'
context 'with no user' do
let(:group) { create(:group, :public) }
diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb
index 1fdf95ad716..99fa8b1fe44 100644
--- a/spec/policies/namespace_policy_spec.rb
+++ b/spec/policies/namespace_policy_spec.rb
@@ -30,7 +30,7 @@ describe NamespacePolicy do
context 'user who has exceeded project limit' do
let(:owner) { create(:user, projects_limit: 0) }
- it { is_expected.not_to be_allowed(:create_projects) }
+ it { is_expected.to be_disallowed(:create_projects) }
end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 772d1fbee2b..726ccba8807 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1,96 +1,7 @@
require 'spec_helper'
describe ProjectPolicy do
- set(:guest) { create(:user) }
- set(:reporter) { create(:user) }
- set(:developer) { create(:user) }
- set(:maintainer) { create(:user) }
- set(:owner) { create(:user) }
- set(:admin) { create(:admin) }
- let(:project) { create(:project, :public, namespace: owner.namespace) }
-
- let(:base_guest_permissions) do
- %i[
- read_project read_board read_list read_wiki read_issue
- read_project_for_iids read_issue_iid read_label
- read_milestone read_project_snippet read_project_member read_note
- create_project create_issue create_note upload_file create_merge_request_in
- award_emoji read_release
- ]
- end
-
- let(:base_reporter_permissions) do
- %i[
- download_code fork_project create_project_snippet update_issue
- 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
- ]
- end
-
- let(:team_member_reporter_permissions) do
- %i[build_download_code build_read_container_image]
- end
-
- let(:developer_permissions) do
- %i[
- admin_milestone admin_merge_request update_merge_request create_commit_status
- update_commit_status create_build update_build create_pipeline
- update_pipeline create_merge_request_from create_wiki push_code
- resolve_note create_container_image update_container_image
- create_environment create_deployment create_release update_release
- ]
- end
-
- let(:base_maintainer_permissions) do
- %i[
- push_to_delete_protected_branch update_project_snippet update_environment
- update_deployment admin_project_snippet admin_project_member admin_note admin_wiki admin_project
- admin_commit_status admin_build admin_container_image
- admin_pipeline admin_environment admin_deployment destroy_release add_cluster
- daily_statistics
- ]
- end
-
- let(:public_permissions) do
- %i[
- download_code fork_project read_commit_status read_pipeline
- read_container_image build_download_code build_read_container_image
- download_wiki_code read_release
- ]
- end
-
- let(:owner_permissions) do
- %i[
- change_namespace change_visibility_level rename_project remove_project
- archive_project remove_fork_project destroy_merge_request destroy_issue
- set_issue_iid set_issue_created_at set_note_created_at
- ]
- end
-
- # Used in EE specs
- let(:additional_guest_permissions) { [] }
- let(:additional_reporter_permissions) { [] }
- let(:additional_maintainer_permissions) { [] }
-
- let(:guest_permissions) { base_guest_permissions + additional_guest_permissions }
- let(:reporter_permissions) { base_reporter_permissions + additional_reporter_permissions }
- let(:maintainer_permissions) { base_maintainer_permissions + additional_maintainer_permissions }
-
- before do
- project.add_guest(guest)
- project.add_maintainer(maintainer)
- project.add_developer(developer)
- project.add_reporter(reporter)
- end
-
- def expect_allowed(*permissions)
- permissions.each { |p| is_expected.to be_allowed(p) }
- end
-
- def expect_disallowed(*permissions)
- permissions.each { |p| is_expected.not_to be_allowed(p) }
- end
+ include_context 'ProjectPolicy context'
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)
@@ -140,7 +51,7 @@ describe ProjectPolicy do
end
it 'disables boards and lists permissions' do
- expect_disallowed :read_board, :create_board, :update_board, :admin_board
+ expect_disallowed :read_board, :create_board, :update_board
expect_disallowed :read_list, :create_list, :update_list, :admin_list
end
@@ -237,237 +148,6 @@ describe ProjectPolicy do
end
end
- shared_examples 'archived project policies' do
- let(:feature_write_abilities) do
- described_class::READONLY_FEATURES_WHEN_ARCHIVED.flat_map do |feature|
- described_class.create_update_admin_destroy(feature)
- end
- end
-
- let(:other_write_abilities) do
- %i[
- create_merge_request_in
- create_merge_request_from
- push_to_delete_protected_branch
- push_code
- request_access
- upload_file
- resolve_note
- award_emoji
- ]
- end
-
- context 'when the project is archived' do
- before do
- project.archived = true
- end
-
- it 'disables write actions on all relevant project features' do
- expect_disallowed(*feature_write_abilities)
- end
-
- it 'disables some other important write actions' do
- expect_disallowed(*other_write_abilities)
- end
-
- it 'does not disable other abilities' do
- expect_allowed(*(regular_abilities - feature_write_abilities - other_write_abilities))
- end
- end
- end
-
- shared_examples 'project policies as anonymous' do
- context 'abilities for public projects' do
- context 'when a project has pending invites' do
- let(:group) { create(:group, :public) }
- let(:project) { create(:project, :public, namespace: group) }
- let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file, :award_emoji] }
- let(:anonymous_permissions) { guest_permissions - user_permissions }
-
- subject { described_class.new(nil, project) }
-
- before do
- create(:group_member, :invited, group: group)
- end
-
- it 'does not grant owner access' do
- expect_allowed(*anonymous_permissions)
- expect_disallowed(*user_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { anonymous_permissions }
- end
- end
- end
-
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(nil, project) }
-
- it { is_expected.to be_banned }
- end
- end
-
- shared_examples 'project policies as guest' do
- subject { described_class.new(guest, project) }
-
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
- let(:reporter_public_build_permissions) do
- reporter_permissions - [:read_build, :read_pipeline]
- end
-
- it do
- expect_allowed(*guest_permissions)
- expect_disallowed(*reporter_public_build_permissions)
- expect_disallowed(*team_member_reporter_permissions)
- expect_disallowed(*developer_permissions)
- expect_disallowed(*maintainer_permissions)
- expect_disallowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { guest_permissions }
- end
-
- context 'public builds enabled' do
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(:read_build, :read_pipeline)
- end
- end
-
- context 'when public builds disabled' do
- before do
- project.update(public_builds: false)
- end
-
- it do
- expect_allowed(*guest_permissions)
- expect_disallowed(:read_build, :read_pipeline)
- end
- end
-
- context 'when builds are disabled' do
- before do
- project.project_feature.update(builds_access_level: ProjectFeature::DISABLED)
- end
-
- it do
- expect_disallowed(:read_build)
- expect_allowed(:read_pipeline)
- end
- end
- end
- end
-
- shared_examples 'project policies as reporter' do
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(reporter, project) }
-
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(*reporter_permissions)
- expect_allowed(*team_member_reporter_permissions)
- expect_disallowed(*developer_permissions)
- expect_disallowed(*maintainer_permissions)
- expect_disallowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { reporter_permissions }
- end
- end
- end
-
- shared_examples 'project policies as developer' do
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(developer, project) }
-
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(*reporter_permissions)
- expect_allowed(*team_member_reporter_permissions)
- expect_allowed(*developer_permissions)
- expect_disallowed(*maintainer_permissions)
- expect_disallowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { developer_permissions }
- end
- end
- end
-
- shared_examples 'project policies as maintainer' do
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(maintainer, project) }
-
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(*reporter_permissions)
- expect_allowed(*team_member_reporter_permissions)
- expect_allowed(*developer_permissions)
- expect_allowed(*maintainer_permissions)
- expect_disallowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { maintainer_permissions }
- end
- end
- end
-
- shared_examples 'project policies as owner' do
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(owner, project) }
-
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(*reporter_permissions)
- expect_allowed(*team_member_reporter_permissions)
- expect_allowed(*developer_permissions)
- expect_allowed(*maintainer_permissions)
- expect_allowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { owner_permissions }
- end
- end
- end
-
- shared_examples 'project policies as admin' do
- context 'abilities for non-public projects' do
- let(:project) { create(:project, namespace: owner.namespace) }
-
- subject { described_class.new(admin, project) }
-
- it do
- expect_allowed(*guest_permissions)
- expect_allowed(*reporter_permissions)
- expect_disallowed(*team_member_reporter_permissions)
- expect_allowed(*developer_permissions)
- expect_allowed(*maintainer_permissions)
- expect_allowed(*owner_permissions)
- end
-
- it_behaves_like 'archived project policies' do
- let(:regular_abilities) { owner_permissions }
- end
- end
- end
-
it_behaves_like 'project policies as anonymous'
it_behaves_like 'project policies as guest'
it_behaves_like 'project policies as reporter'
diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb
index d6329e84579..2e9ef1e89fd 100644
--- a/spec/policies/project_snippet_policy_spec.rb
+++ b/spec/policies/project_snippet_policy_spec.rb
@@ -5,7 +5,7 @@ describe ProjectSnippetPolicy do
let(:regular_user) { create(:user) }
let(:external_user) { create(:user, :external) }
let(:project) { create(:project, :public) }
-
+ let(:snippet) { create(:project_snippet, snippet_visibility, project: project) }
let(:author_permissions) do
[
:update_project_snippet,
@@ -13,23 +13,13 @@ describe ProjectSnippetPolicy do
]
end
- def abilities(user, snippet_visibility)
- snippet = create(:project_snippet, snippet_visibility, project: project)
-
- described_class.new(user, snippet)
- end
-
- def expect_allowed(*permissions)
- permissions.each { |p| is_expected.to be_allowed(p) }
- end
-
- def expect_disallowed(*permissions)
- permissions.each { |p| is_expected.not_to be_allowed(p) }
- end
+ subject { described_class.new(current_user, snippet) }
context 'public snippet' do
+ let(:snippet_visibility) { :public }
+
context 'no user' do
- subject { abilities(nil, :public) }
+ let(:current_user) { nil }
it do
expect_allowed(:read_project_snippet)
@@ -38,7 +28,7 @@ describe ProjectSnippetPolicy do
end
context 'regular user' do
- subject { abilities(regular_user, :public) }
+ let(:current_user) { regular_user }
it do
expect_allowed(:read_project_snippet, :create_note)
@@ -47,7 +37,7 @@ describe ProjectSnippetPolicy do
end
context 'external user' do
- subject { abilities(external_user, :public) }
+ let(:current_user) { external_user }
it do
expect_allowed(:read_project_snippet, :create_note)
@@ -57,8 +47,10 @@ describe ProjectSnippetPolicy do
end
context 'internal snippet' do
+ let(:snippet_visibility) { :internal }
+
context 'no user' do
- subject { abilities(nil, :internal) }
+ let(:current_user) { nil }
it do
expect_disallowed(:read_project_snippet)
@@ -67,7 +59,7 @@ describe ProjectSnippetPolicy do
end
context 'regular user' do
- subject { abilities(regular_user, :internal) }
+ let(:current_user) { regular_user }
it do
expect_allowed(:read_project_snippet, :create_note)
@@ -76,31 +68,31 @@ describe ProjectSnippetPolicy do
end
context 'external user' do
- subject { abilities(external_user, :internal) }
+ let(:current_user) { external_user }
it do
expect_disallowed(:read_project_snippet, :create_note)
expect_disallowed(*author_permissions)
end
- end
- context 'project team member external user' do
- subject { abilities(external_user, :internal) }
-
- before do
- project.add_developer(external_user)
- end
+ context 'project team member' do
+ before do
+ project.add_developer(external_user)
+ end
- it do
- expect_allowed(:read_project_snippet, :create_note)
- expect_disallowed(*author_permissions)
+ it do
+ expect_allowed(:read_project_snippet, :create_note)
+ expect_disallowed(*author_permissions)
+ end
end
end
end
context 'private snippet' do
+ let(:snippet_visibility) { :private }
+
context 'no user' do
- subject { abilities(nil, :private) }
+ let(:current_user) { nil }
it do
expect_disallowed(:read_project_snippet)
@@ -109,53 +101,52 @@ describe ProjectSnippetPolicy do
end
context 'regular user' do
- subject { abilities(regular_user, :private) }
+ let(:current_user) { regular_user }
it do
expect_disallowed(:read_project_snippet, :create_note)
expect_disallowed(*author_permissions)
end
- end
-
- context 'snippet author' do
- let(:snippet) { create(:project_snippet, :private, author: regular_user, project: project) }
- subject { described_class.new(regular_user, snippet) }
+ context 'snippet author' do
+ let(:snippet) { create(:project_snippet, :private, author: regular_user, project: project) }
- it do
- expect_allowed(:read_project_snippet, :create_note)
- expect_allowed(*author_permissions)
+ it do
+ expect_allowed(:read_project_snippet, :create_note)
+ expect_allowed(*author_permissions)
+ end
end
- end
- context 'project team member normal user' do
- subject { abilities(regular_user, :private) }
-
- before do
- project.add_developer(regular_user)
- end
+ context 'project team member normal user' do
+ before do
+ project.add_developer(regular_user)
+ end
- it do
- expect_allowed(:read_project_snippet, :create_note)
- expect_disallowed(*author_permissions)
+ it do
+ expect_allowed(:read_project_snippet, :create_note)
+ expect_disallowed(*author_permissions)
+ end
end
end
- context 'project team member external user' do
- subject { abilities(external_user, :private) }
+ context 'external user' do
+ context 'project team member' do
+ let(:current_user) { external_user }
- before do
- project.add_developer(external_user)
- end
+ before do
+ project.add_developer(external_user)
+ end
- it do
- expect_allowed(:read_project_snippet, :create_note)
- expect_disallowed(*author_permissions)
+ it do
+ expect_allowed(:read_project_snippet, :create_note)
+ expect_disallowed(*author_permissions)
+ end
end
end
context 'admin user' do
- subject { abilities(create(:admin), :private) }
+ let(:snippet_visibility) { :private }
+ let(:current_user) { create(:admin) }
it do
expect_allowed(:read_project_snippet, :create_note)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e8d7b18bf04..b3bd453ebd6 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -96,6 +96,7 @@ RSpec.configure do |config|
config.include MigrationsHelpers, :migration
config.include RedisHelpers
config.include Rails.application.routes.url_helpers, type: :routing
+ config.include PolicyHelpers, type: :policy
if ENV['CI']
# This includes the first try, i.e. tests will be run 4 times before failing.
diff --git a/spec/support/helpers/policy_helpers.rb b/spec/support/helpers/policy_helpers.rb
new file mode 100644
index 00000000000..3d780eb5fb1
--- /dev/null
+++ b/spec/support/helpers/policy_helpers.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module PolicyHelpers
+ def expect_allowed(*permissions)
+ permissions.each { |p| is_expected.to be_allowed(p) }
+ end
+
+ def expect_disallowed(*permissions)
+ permissions.each { |p| is_expected.not_to be_allowed(p) }
+ end
+end
diff --git a/spec/support/shared_context/policies/project_policy_shared_context.rb b/spec/support/shared_context/policies/project_policy_shared_context.rb
new file mode 100644
index 00000000000..8bcd26ec0cd
--- /dev/null
+++ b/spec/support/shared_context/policies/project_policy_shared_context.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'ProjectPolicy context' do
+ set(:guest) { create(:user) }
+ set(:reporter) { create(:user) }
+ set(:developer) { create(:user) }
+ set(:maintainer) { create(:user) }
+ set(:owner) { create(:user) }
+ set(:admin) { create(:admin) }
+ let(:project) { create(:project, :public, namespace: owner.namespace) }
+
+ let(:base_guest_permissions) do
+ %i[
+ read_project read_board read_list read_wiki read_issue
+ read_project_for_iids read_issue_iid read_label
+ read_milestone read_project_snippet read_project_member read_note
+ create_project create_issue create_note upload_file create_merge_request_in
+ award_emoji read_release
+ ]
+ end
+
+ let(:base_reporter_permissions) do
+ %i[
+ download_code fork_project create_project_snippet update_issue
+ 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
+ ]
+ end
+
+ let(:team_member_reporter_permissions) do
+ %i[build_download_code build_read_container_image]
+ end
+
+ let(:developer_permissions) do
+ %i[
+ admin_milestone admin_merge_request update_merge_request create_commit_status
+ update_commit_status create_build update_build create_pipeline
+ update_pipeline create_merge_request_from create_wiki push_code
+ resolve_note create_container_image update_container_image
+ create_environment create_deployment create_release update_release
+ ]
+ end
+
+ let(:base_maintainer_permissions) do
+ %i[
+ push_to_delete_protected_branch update_project_snippet update_environment
+ update_deployment admin_project_snippet admin_project_member admin_note admin_wiki admin_project
+ admin_commit_status admin_build admin_container_image
+ admin_pipeline admin_environment admin_deployment destroy_release add_cluster
+ daily_statistics
+ ]
+ end
+
+ let(:public_permissions) do
+ %i[
+ download_code fork_project read_commit_status read_pipeline
+ read_container_image build_download_code build_read_container_image
+ download_wiki_code read_release
+ ]
+ end
+
+ let(:base_owner_permissions) do
+ %i[
+ change_namespace change_visibility_level rename_project remove_project
+ archive_project remove_fork_project destroy_merge_request destroy_issue
+ set_issue_iid set_issue_created_at set_note_created_at
+ ]
+ end
+
+ # Used in EE specs
+ let(:additional_guest_permissions) { [] }
+ let(:additional_reporter_permissions) { [] }
+ let(:additional_maintainer_permissions) { [] }
+ let(:additional_owner_permissions) { [] }
+
+ let(:guest_permissions) { base_guest_permissions + additional_guest_permissions }
+ let(:reporter_permissions) { base_reporter_permissions + additional_reporter_permissions }
+ let(:maintainer_permissions) { base_maintainer_permissions + additional_maintainer_permissions }
+ let(:owner_permissions) { base_owner_permissions + additional_owner_permissions }
+
+ before do
+ project.add_guest(guest)
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ end
+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
new file mode 100644
index 00000000000..b4808ac0068
--- /dev/null
+++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'GroupPolicy context' do
+ let(:guest) { create(:user) }
+ let(:reporter) { create(:user) }
+ let(:developer) { create(:user) }
+ let(:maintainer) { create(:user) }
+ let(:owner) { create(:user) }
+ let(:admin) { create(:admin) }
+ let(:group) { create(:group, :private) }
+
+ let(:guest_permissions) do
+ %i[
+ read_label read_group upload_file read_namespace read_group_activity
+ read_group_issues read_group_boards read_group_labels read_group_milestones
+ read_group_merge_requests
+ ]
+ end
+ let(:reporter_permissions) { [:admin_label] }
+ let(:developer_permissions) { [:admin_milestone] }
+ let(:maintainer_permissions) do
+ %i[
+ create_projects
+ read_cluster create_cluster update_cluster admin_cluster add_cluster
+ ]
+ end
+ let(:owner_permissions) do
+ [
+ :admin_group,
+ :admin_namespace,
+ :admin_group_member,
+ :change_visibility_level,
+ :set_note_created_at,
+ (Gitlab::Database.postgresql? ? :create_subgroup : nil)
+ ].compact
+ end
+
+ before do
+ group.add_guest(guest)
+ group.add_reporter(reporter)
+ group.add_developer(developer)
+ group.add_maintainer(maintainer)
+ group.add_owner(owner)
+ end
+
+ subject { described_class.new(current_user, group) }
+end
diff --git a/spec/support/shared_examples/policies/project_policy_shared_examples.rb b/spec/support/shared_examples/policies/project_policy_shared_examples.rb
new file mode 100644
index 00000000000..7a71e2ee370
--- /dev/null
+++ b/spec/support/shared_examples/policies/project_policy_shared_examples.rb
@@ -0,0 +1,231 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'archived project policies' do
+ let(:feature_write_abilities) do
+ described_class::READONLY_FEATURES_WHEN_ARCHIVED.flat_map do |feature|
+ described_class.create_update_admin_destroy(feature)
+ end + additional_reporter_permissions + additional_maintainer_permissions
+ end
+
+ let(:other_write_abilities) do
+ %i[
+ create_merge_request_in
+ create_merge_request_from
+ push_to_delete_protected_branch
+ push_code
+ request_access
+ upload_file
+ resolve_note
+ award_emoji
+ ]
+ end
+
+ context 'when the project is archived' do
+ before do
+ project.archived = true
+ end
+
+ it 'disables write actions on all relevant project features' do
+ expect_disallowed(*feature_write_abilities)
+ end
+
+ it 'disables some other important write actions' do
+ expect_disallowed(*other_write_abilities)
+ end
+
+ it 'does not disable other abilities' do
+ expect_allowed(*(regular_abilities - feature_write_abilities - other_write_abilities))
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as anonymous' do
+ context 'abilities for public projects' do
+ context 'when a project has pending invites' do
+ let(:group) { create(:group, :public) }
+ let(:project) { create(:project, :public, namespace: group) }
+ let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file, :award_emoji] }
+ let(:anonymous_permissions) { guest_permissions - user_permissions }
+
+ subject { described_class.new(nil, project) }
+
+ before do
+ create(:group_member, :invited, group: group)
+ end
+
+ it 'does not grant owner access' do
+ expect_allowed(*anonymous_permissions)
+ expect_disallowed(*user_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { anonymous_permissions }
+ end
+ end
+ end
+
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+
+ subject { described_class.new(nil, project) }
+
+ it { is_expected.to be_banned }
+ end
+end
+
+RSpec.shared_examples 'project policies as guest' do
+ subject { described_class.new(guest, project) }
+
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+ let(:reporter_public_build_permissions) do
+ reporter_permissions - [:read_build, :read_pipeline]
+ end
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_disallowed(*reporter_public_build_permissions)
+ expect_disallowed(*team_member_reporter_permissions)
+ expect_disallowed(*developer_permissions)
+ expect_disallowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { guest_permissions }
+ end
+
+ context 'public builds enabled' do
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(:read_build, :read_pipeline)
+ end
+ end
+
+ context 'when public builds disabled' do
+ before do
+ project.update(public_builds: false)
+ end
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_disallowed(:read_build, :read_pipeline)
+ end
+ end
+
+ context 'when builds are disabled' do
+ before do
+ project.project_feature.update(builds_access_level: ProjectFeature::DISABLED)
+ end
+
+ it do
+ expect_disallowed(:read_build)
+ expect_allowed(:read_pipeline)
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as reporter' do
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+
+ subject { described_class.new(reporter, project) }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*reporter_permissions)
+ expect_allowed(*team_member_reporter_permissions)
+ expect_disallowed(*developer_permissions)
+ expect_disallowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { reporter_permissions }
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as developer' do
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+ subject { described_class.new(developer, project) }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*reporter_permissions)
+ expect_allowed(*team_member_reporter_permissions)
+ expect_allowed(*developer_permissions)
+ expect_disallowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { developer_permissions }
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as maintainer' do
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+
+ subject { described_class.new(maintainer, project) }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*reporter_permissions)
+ expect_allowed(*team_member_reporter_permissions)
+ expect_allowed(*developer_permissions)
+ expect_allowed(*maintainer_permissions)
+ expect_disallowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { maintainer_permissions }
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as owner' do
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+
+ subject { described_class.new(owner, project) }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*reporter_permissions)
+ expect_allowed(*team_member_reporter_permissions)
+ expect_allowed(*developer_permissions)
+ expect_allowed(*maintainer_permissions)
+ expect_allowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { owner_permissions }
+ end
+ end
+end
+
+RSpec.shared_examples 'project policies as admin' do
+ context 'abilities for non-public projects' do
+ let(:project) { create(:project, namespace: owner.namespace) }
+
+ subject { described_class.new(admin, project) }
+
+ it do
+ expect_allowed(*guest_permissions)
+ expect_allowed(*reporter_permissions)
+ expect_disallowed(*team_member_reporter_permissions)
+ expect_allowed(*developer_permissions)
+ expect_allowed(*maintainer_permissions)
+ expect_allowed(*owner_permissions)
+ end
+
+ it_behaves_like 'archived project policies' do
+ let(:regular_abilities) { owner_permissions }
+ end
+ end
+end