diff --git a/.flayignore b/.flayignore index 0689ddc1eb8b9309b960e44439f0759c740894b5..80682c5b237ea2b20e9dd89334b9705cc813a87e 100644 --- a/.flayignore +++ b/.flayignore @@ -3,3 +3,4 @@ lib/gitlab/sanitizers/svg/whitelist.rb lib/gitlab/diff/position_tracer.rb app/controllers/projects/approver_groups_controller.rb app/controllers/projects/approvers_controller.rb +app/policies/project_policy.rb \ No newline at end of file diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index c788e6ea59a2841c75e4c5eb07edb0a93a523d8f..6acdc5d59dc05e3c34cfd063291aa8967252ffe7 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -175,7 +175,7 @@ def user_params def user_params_ce [ - :admin, + :access_level, :avatar, :bio, :can_create_group, diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb index aa8f4c1d0e4da52daea174402259d1a7d40ff474..3b9a421b11871ff7b174918cf812778a5f184524 100644 --- a/app/finders/group_projects_finder.rb +++ b/app/finders/group_projects_finder.rb @@ -18,7 +18,7 @@ def group_projects(current_user) projects = [] if current_user - if @group.users.include?(current_user) || current_user.admin? + if @group.users.include?(current_user) projects << @group.projects unless only_shared projects << @group.shared_projects unless only_owned else diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index 707eddd4d2991138ee6fb9d2f279e25e8ba48416..752c7bf59dd3367dc5592938e225e8e9d0f55033 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -33,7 +33,7 @@ def iid_pattern def self.not_restricted_by_confidentiality(user) return Issue.where('issues.confidential IS NULL OR issues.confidential IS FALSE') if user.blank? - return Issue.all if user.admin? + return Issue.all if user.admin_or_auditor? Issue.where(' issues.confidential IS NULL diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb index da6e6e87a6ff336cae9660a6415543220c449f1f..a292d5b537d501a7ed1b5bedf53febad1948120d 100644 --- a/app/finders/snippets_finder.rb +++ b/app/finders/snippets_finder.rb @@ -44,7 +44,7 @@ def by_project(current_user, project, scope) snippets = project.snippets.fresh if current_user - include_private = project.team.member?(current_user) || current_user.admin? + include_private = project.team.member?(current_user) || current_user.admin_or_auditor? by_scope(snippets, scope, include_private) else snippets.are_public diff --git a/app/helpers/auditor_user_helper.rb b/app/helpers/auditor_user_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..88094373b0a0052bf86b173b01352b4aa2343588 --- /dev/null +++ b/app/helpers/auditor_user_helper.rb @@ -0,0 +1,5 @@ +module AuditorUserHelper + def license_allows_auditor_user? + @license_allows_auditor_user ||= (::License.current && ::License.current.add_on?('GitLab_Auditor_User')) + end +end diff --git a/app/models/ee/user.rb b/app/models/ee/user.rb new file mode 100644 index 0000000000000000000000000000000000000000..40b3f3178c5b45ecd678114156d22dd1c8347927 --- /dev/null +++ b/app/models/ee/user.rb @@ -0,0 +1,40 @@ +module EE + # User EE mixin + # + # This module is intended to encapsulate EE-specific model logic + # and be prepended in the `User` model + module User + extend ActiveSupport::Concern + include AuditorUserHelper + + included do + # We aren't using the `auditor?` method for the `if` condition here + # because `auditor?` returns `false` when the `auditor` column is `true` + # and the auditor add-on absent. We want to run this validation + # regardless of the add-on's presence, so we need to check the `auditor` + # column directly. + validate :auditor_requires_license_add_on, if: :auditor + validate :cannot_be_admin_and_auditor + end + + def cannot_be_admin_and_auditor + if admin? && auditor? + errors.add(:admin, "user cannot also be an Auditor.") + end + end + + def auditor_requires_license_add_on + unless license_allows_auditor_user? + errors.add(:auditor, 'user cannot be created without the "GitLab_Auditor_User" addon') + end + end + + def auditor? + license_allows_auditor_user? && self.auditor + end + + def admin_or_auditor? + admin? || auditor? + end + end +end diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index 03194fc2141356fd731c71c89a036af7cd575ccd..e0673098e37e8515fe2d7472d452e5eccd2e5603 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -83,7 +83,7 @@ def get_permission(user, level) when DISABLED false when PRIVATE - user && (project.team.member?(user) || user.admin?) + user && (project.team.member?(user) || user.admin_or_auditor?) when ENABLED true else diff --git a/app/models/user.rb b/app/models/user.rb index 1209cdddc8598456e57b636214b463d9502ca7ca..8e2463e7aaaff55b03c550bf5d584142f4a1a011 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,6 +10,7 @@ class User < ActiveRecord::Base include CaseSensitivity include TokenAuthenticatable prepend EE::GeoAwareAvatar + prepend EE::User DEFAULT_NOTIFICATION_LEVEL = :participating @@ -933,6 +934,24 @@ def record_activity Gitlab::UserActivities::ActivitySet.record(self) end + def access_level + if admin? + :admin + elsif auditor? + :auditor + else + :regular + end + end + + def access_level=(new_level) + new_level = new_level.to_s + return unless %w(admin auditor regular).include?(new_level) + + self.admin = (new_level == 'admin') + self.auditor = (new_level == 'auditor') + end + private def ci_projects_union diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 669b5e780e9f35604d3e2a94d8560ac141503a8f..a6be4ac2bd82d6ef545d1509ed89fb1d83c860d9 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -12,6 +12,7 @@ def rules can_read ||= globally_viewable can_read ||= member can_read ||= @user.admin? + can_read ||= @user.auditor? can_read ||= GroupProjectsFinder.new(@subject).execute(@user).any? can! :read_group if can_read @@ -40,6 +41,7 @@ def rules def can_read_group? return true if @subject.public? return true if @user.admin? + return true if @user.auditor? return true if @subject.internal? && !@user.external? return true if @subject.users.include?(@user) diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index e5ff006847c65298c0a023a266da829a07fef0b6..bb03de3fbd0fa259d49deba01a823b9a32d37eb1 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -8,6 +8,7 @@ def rules (project.group && project.group.has_owner?(user)) owner_access! if user.admin? || owner + auditor_access! if user.auditor? team_member_owner_access! if owner if project.public? || (project.internal? && !user.external?) @@ -182,6 +183,16 @@ def archived_access! cannot! :admin_merge_request end + # An auditor user has read-only access to all projects + def auditor_access! + base_readonly_access! + + can! :read_build + can! :read_environment + can! :read_deployment + can! :read_pages + end + def disabled_features! repository_enabled = project.feature_available?(:repository, user) @@ -228,25 +239,7 @@ def disabled_features! def anonymous_rules return unless project.public? - can! :read_project - can! :read_board - can! :read_list - can! :read_wiki - can! :read_label - can! :read_milestone - can! :read_project_snippet - can! :read_project_member - can! :read_merge_request - can! :read_note - can! :read_pipeline - can! :read_commit_status - can! :read_container_image - can! :download_code - can! :download_wiki_code - can! :read_cycle_analytics - - # NOTE: may be overridden by IssuePolicy - can! :read_issue + base_readonly_access! # Allow to read builds by anonymous user if guests are allowed can! :read_build if project.public_builds? @@ -279,4 +272,31 @@ def named_abilities(name) :"admin_#{name}" ] end + + private + + # A base set of abilities for read-only users, which + # is then augmented as necessary for anonymous and other + # read-only users. + def base_readonly_access! + can! :read_project + can! :read_board + can! :read_list + can! :read_wiki + can! :read_label + can! :read_milestone + can! :read_project_snippet + can! :read_project_member + can! :read_merge_request + can! :read_note + can! :read_pipeline + can! :read_commit_status + can! :read_container_image + can! :download_code + can! :download_wiki_code + can! :read_cycle_analytics + + # NOTE: may be overridden by IssuePolicy + can! :read_issue + end end diff --git a/app/policies/project_snippet_policy.rb b/app/policies/project_snippet_policy.rb index 57acccfafd95c67b661fa923bb676e34d8124361..dd45309adb0d58129589ca8cab9fb89fc1996b83 100644 --- a/app/policies/project_snippet_policy.rb +++ b/app/policies/project_snippet_policy.rb @@ -3,12 +3,16 @@ def rules can! :read_project_snippet if @subject.public? return unless @user - if @user && @subject.author == @user || @user.admin? + if @user && (@subject.author == @user || @user.admin?) can! :read_project_snippet can! :update_project_snippet can! :admin_project_snippet end + if @user.auditor? + can! :read_project_snippet + end + if @subject.internal? && !@user.external? can! :read_project_snippet end diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..b3e76ddaf4dcd54ff42f5721e4d0ec959eb83445 --- /dev/null +++ b/app/views/admin/users/_access_levels.html.haml @@ -0,0 +1,44 @@ +%fieldset + %legend Access + .form-group + = f.label :projects_limit, class: 'control-label' + .col-sm-10= f.number_field :projects_limit, min: 0, class: 'form-control' + + .form-group + = f.label :can_create_group, class: 'control-label' + .col-sm-10= f.check_box :can_create_group + + .form-group + = f.label :access_level, class: 'control-label' + .col-sm-10 + - editing_current_user = (current_user == @user) + + = f.radio_button :access_level, :regular, disabled: editing_current_user + = label_tag :regular do + Regular + %p.light + Regular users have access to their groups and projects + + - if license_allows_auditor_user? + = f.radio_button :access_level, :auditor, disabled: editing_current_user + = label_tag :auditor do + Auditor + %p.light + Auditors have read-only access to all groups, projects and users + + = f.radio_button :access_level, :admin, disabled: editing_current_user + = label_tag :admin do + Admin + %p.light + Administrators have access to all groups, projects and users and can manage all features in this installation + - if editing_current_user + %p.light + You cannot remove your own admin rights. + + .form-group + = f.label :external, class: 'control-label' + .col-sm-10 + = f.check_box :external do + External + %p.light + External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects or groups. diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 6ed2ff07bbacde39cfe81849700a6653a2265f47..bbe8f7d911435f5d4f20f8c0baed6a05d62a69f8 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -40,28 +40,7 @@ = f.label :password_confirmation, class: 'control-label' .col-sm-10= f.password_field :password_confirmation, disabled: f.object.force_random_password, class: 'form-control' - %fieldset - %legend Access - .form-group - = f.label :projects_limit, class: 'control-label' - .col-sm-10= f.number_field :projects_limit, min: 0, class: 'form-control' - - .form-group - = f.label :can_create_group, class: 'control-label' - .col-sm-10= f.check_box :can_create_group - - .form-group - = f.label :admin, class: 'control-label' - - if current_user == @user - .col-sm-10= f.check_box :admin, disabled: true - .col-sm-10 You cannot remove your own admin rights. - - else - .col-sm-10= f.check_box :admin - - .form-group - = f.label :external, class: 'control-label' - .col-sm-10= f.check_box :external - .col-sm-10 External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects or groups. + = render partial: 'access_levels', locals: { f: f } %fieldset %legend Profile diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml index 9984e733956afeaf1a0a62983db62be2fd22422f..ea71cf0968f9b49b70c9c8c06d151283fac29ed1 100644 --- a/app/views/admin/users/_head.html.haml +++ b/app/views/admin/users/_head.html.haml @@ -4,6 +4,8 @@ %span.cred (Blocked) - if @user.admin %span.cred (Admin) + - if @user.auditor + %span.cred (Auditor) .pull-right - unless @user == current_user || @user.blocked? diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml index fbd2bff5bbb27a7bff6f1daf572b697535b51295..08c73d94a0997172e79a48a15820ba4892223d51 100644 --- a/app/views/projects/notes/_notes_with_form.html.haml +++ b/app/views/projects/notes/_notes_with_form.html.haml @@ -13,7 +13,7 @@ = image_tag avatar_icon(current_user), alt: current_user.to_reference, class: 'avatar s40' .timeline-content.timeline-content-form = render "projects/notes/form", view: diff_view - - else + - elsif !current_user .disabled-comment.text-center .disabled-comment-text.inline Please diff --git a/changelogs/unreleased-ee/1439-read-only-user.yml b/changelogs/unreleased-ee/1439-read-only-user.yml new file mode 100644 index 0000000000000000000000000000000000000000..b80db5272f0bd486e313202ae166dd695571354c --- /dev/null +++ b/changelogs/unreleased-ee/1439-read-only-user.yml @@ -0,0 +1,4 @@ +--- +title: Read-only "auditor" user role +merge_request: 998 +author: diff --git a/db/migrate/20170120123345_add_column_auditor_to_users.rb b/db/migrate/20170120123345_add_column_auditor_to_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..11e2b6160f241ccf757aafb119bd2fd6c3c4e5b0 --- /dev/null +++ b/db/migrate/20170120123345_add_column_auditor_to_users.rb @@ -0,0 +1,18 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddColumnAuditorToUsers < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_column_with_default :users, :auditor, :boolean, default: false, allow_null: false + end + + def down + remove_column :users, :auditor + end +end diff --git a/db/schema.rb b/db/schema.rb index c3728be053b4604550afe27bc32703cb1fa1d5b8..e22210f6fc0175c33ea26b4418f698b3429f56ae 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1452,6 +1452,7 @@ t.string "incoming_email_token" t.string "organization" t.boolean "authorized_projects_populated" + t.boolean "auditor", default: false, null: false end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree diff --git a/doc/README.md b/doc/README.md index 6991c4ca3f5120e90e5f56915276f501bc662de1..e26ddb13cc1c9f6333e69157035f815ce1d7a221 100644 --- a/doc/README.md +++ b/doc/README.md @@ -77,6 +77,7 @@ - [High Availability](administration/high_availability/README.md) Configure multiple servers for scaling or high availability. - [Container Registry](administration/container_registry.md) Configure Docker Registry with GitLab. - [Repository restrictions](user/admin_area/settings/account_and_limit_settings.md#repository-size-limit) Define size restrictions for your repositories to limit the space they occupy in your storage device. Includes LFS objects. +- [Auditor users](administration/auditor_users.md) Create auditor users, with read-only access to the entire system. ## Contributor documentation diff --git a/doc/administration/auditor_access_form.png b/doc/administration/auditor_access_form.png new file mode 100644 index 0000000000000000000000000000000000000000..390df04392da02d548e634333b92df611b66ae75 Binary files /dev/null and b/doc/administration/auditor_access_form.png differ diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md new file mode 100644 index 0000000000000000000000000000000000000000..fbcc18eb3cf52e871b98531f16cbd149190ba751 --- /dev/null +++ b/doc/administration/auditor_users.md @@ -0,0 +1,24 @@ +# Auditor Users + +>**Note:** [Introduced][998] in GitLab 8.17. + +With Gitlab Enterprise Edition Premium, you can create *auditor* users, who +are given read-only access to all projects, groups, and other resources on the +GitLab instance. + +First and foremost, an auditor user can perform all the actions that a regular user can. +In projects that the auditor user owns, or has been added to, they can be added to +groups, mentioned in comments, or have issues assigned to them. The one exception is +that auditor users cannot _create_ projects or groups. + +In addition, the auditor will be granted read-only access to all other projects/groups/etc. +on the GitLab instance. + +The `auditor` role is _not_ a read-only version of the `admin` role. The auditor will not be +able to access the project settings pages, or the Admin Area. + +A user's access level can be set to ‘Auditor’ in the Admin Area + +![Admin Area Form](auditor_access_form.png) + +[998]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/998 diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index c7953af29ddb3815d3fa76dd28ea84e62ae0c3d1..ba9140c16fac147c7a8f425ab0e4b91d1cb689fc 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -13,7 +13,19 @@ module VisibilityLevel scope :public_and_internal_only, -> { where(visibility_level: [PUBLIC, INTERNAL] ) } scope :non_public_only, -> { where.not(visibility_level: PUBLIC) } - scope :public_to_user, -> (user) { user && !user.external ? public_and_internal_only : public_only } + scope :public_to_user, -> (user) do + if user + if user.admin_or_auditor? + all + elsif !user.external? + public_and_internal_only + else + public_only + end + else + public_only + end + end end PRIVATE = 0 unless const_defined?(:PRIVATE) diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..29c545be43dd60d48afe85f720f3f30397441cfb --- /dev/null +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe Admin::DashboardController do + describe '#index' do + it "allows an admin user to access the page" do + sign_in(create(:user, :admin)) + get :index + + expect(response).to have_http_status(200) + end + + it "does not allow an auditor user to access the page" do + sign_in(create(:user, :auditor)) + get :index + + expect(response).to have_http_status(404) + end + + it "does not allow a regular user to access the page" do + sign_in(create(:user)) + get :index + + expect(response).to have_http_status(404) + end + end +end diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index cad82a34fb0e92d1e127dda7361b6fed9773f25f..418205e5db7c70944135b94f20b977318751b104 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -126,4 +126,48 @@ expect(assigns(:group).path).not_to eq('new_path') end end + + describe 'POST create' do + it 'allows creating a group' do + sign_in(user) + + expect do + post :create, group: { name: 'new_group', path: "new_group" } + end.to change { Group.count }.by(1) + + expect(response).to have_http_status(302) + end + + context 'authorization' do + it 'allows an admin to create a group' do + sign_in(create(:admin)) + + expect do + post :create, group: { name: 'new_group', path: "new_group" } + end.to change { Group.count }.by(1) + + expect(response).to have_http_status(302) + end + + it 'does not allow a user with "can_create_group" set to false to create a group' do + sign_in(create(:user, can_create_group: false)) + + expect do + post :create, group: { name: 'new_group', path: "new_group" } + end.not_to change { Group.count } + + expect(response).to have_http_status(404) + end + + it 'allows an auditor with "can_create_group" set to true to create a group' do + sign_in(create(:user, :auditor, can_create_group: true)) + + expect do + post :create, group: { name: 'new_group', path: "new_group" } + end.to change { Group.count }.by(1) + + expect(response).to have_http_status(302) + end + end + end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 4378ae4950b432fdc3dda997cec284e76bbc0b3c..2e1a0323a28d865568aa5a3226a0dcce5d207b2e 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -425,4 +425,26 @@ expect(parsed_body["Commits"]).to include("123456") end end + + describe 'GET edit' do + it 'does not allow an auditor user to access the page' do + sign_in(create(:user, :auditor)) + + get :edit, + namespace_id: project.namespace.path, + id: project.path + + expect(response).to have_http_status(404) + end + + it 'allows an admin user to access the page' do + sign_in(create(:user, :admin)) + + get :edit, + namespace_id: project.namespace.path, + id: project.path + + expect(response).to have_http_status(200) + end + end end diff --git a/spec/factories/licenses.rb b/spec/factories/licenses.rb index bfc483943778b5a609e6e8e557c0a9d4298abbfb..4faff875637fcf2dc09aeda574a2a9f7936b898b 100644 --- a/spec/factories/licenses.rb +++ b/spec/factories/licenses.rb @@ -6,7 +6,12 @@ { "Name" => FFaker::Name.name } end restrictions do - { add_ons: { 'GitLab_FileLocks' => 1 } } + { + add_ons: { + 'GitLab_FileLocks' => 1, + 'GitLab_Auditor_User' => 1 + } + } end notify_users_at { |l| l.expires_at } notify_admins_at { |l| l.expires_at } diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 67843ed8dd9f4166d9a5f099304a8c8a88b2a66f..ce9353e7342b0b0a88bac9eaf2d14a175de8a1fa 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -14,6 +14,10 @@ admin true end + trait :auditor do + auditor true + end + trait :external do external true end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index a586f8d31843a61aa88ce8f4bc5328e8b5fe9fa2..e9a684b2011de822eb1aba180464aa63c5d96dbc 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -211,7 +211,7 @@ def expect_two_factor_status(status) fill_in "user_email", with: "bigbang@mail.com" fill_in "user_password", with: "AValidPassword1" fill_in "user_password_confirmation", with: "AValidPassword1" - check "user_admin" + choose "user_access_level_admin" click_button "Save changes" end @@ -228,6 +228,21 @@ def expect_two_factor_status(status) end end + describe "Update user account type" do + before do + allow_any_instance_of(AuditorUserHelper).to receive(:license_allows_auditor_user?).and_return(true) + choose "user_access_level_auditor" + click_button "Save changes" + end + + it "changes account type to be auditor" do + user.reload + + expect(user).not_to be_admin + expect(user).to be_auditor + end + end + describe 'update username to non ascii char' do it do fill_in 'user_username', with: '\u3042\u3044' diff --git a/spec/features/security/admin_access_spec.rb b/spec/features/security/admin_access_spec.rb index e180ca53eb51e8f6c9e438a3a243456e0320573e..52a63a9ebecceae128ed3daf600c803830f7da75 100644 --- a/spec/features/security/admin_access_spec.rb +++ b/spec/features/security/admin_access_spec.rb @@ -9,6 +9,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_denied_for :auditor } end describe "GET /admin/users" do @@ -17,6 +18,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_denied_for :auditor } end describe "GET /admin/hooks" do @@ -25,5 +27,6 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_denied_for :auditor } end end diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb index 40f773956d198606e35e917ff0eae75295757225..8f5e2d7cb8a956dde7c28b1775402f522bf599c5 100644 --- a/spec/features/security/dashboard_access_spec.rb +++ b/spec/features/security/dashboard_access_spec.rb @@ -8,6 +8,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -16,6 +17,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -24,6 +26,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -32,6 +35,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -40,6 +44,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_allowed_for :visitor } end @@ -53,6 +58,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end end @@ -60,12 +66,14 @@ describe "GET /projects/new" do it { expect(new_project_path).to be_allowed_for :admin } it { expect(new_project_path).to be_allowed_for :user } + it { expect(new_project_path).to be_allowed_for :auditor } it { expect(new_project_path).to be_denied_for :visitor } end describe "GET /groups/new" do it { expect(new_group_path).to be_allowed_for :admin } it { expect(new_group_path).to be_allowed_for :user } + it { expect(new_group_path).to be_allowed_for :auditor } it { expect(new_group_path).to be_denied_for :visitor } end @@ -74,6 +82,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end end diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb index 87cce32d6c63f3acddb91ad07b050a673267ce1c..1036f65b37f216a7ec80272a8295e8ac13ec9fba 100644 --- a/spec/features/security/group/internal_access_spec.rb +++ b/spec/features/security/group/internal_access_spec.rb @@ -22,6 +22,7 @@ subject { group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -37,6 +38,7 @@ subject { issues_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -52,6 +54,7 @@ subject { merge_requests_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -67,6 +70,7 @@ subject { group_group_members_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -82,6 +86,7 @@ subject { edit_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_denied_for(:master).of(group) } it { is_expected.to be_denied_for(:developer).of(group) } diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb index 1d6b3e77c2213ddf0b5d6ec28548395fd0f3fe21..52a84278e8c50e9fc61dd53cee633fc316bde88d 100644 --- a/spec/features/security/group/private_access_spec.rb +++ b/spec/features/security/group/private_access_spec.rb @@ -22,6 +22,7 @@ subject { group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -37,6 +38,7 @@ subject { issues_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -52,6 +54,7 @@ subject { merge_requests_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -67,6 +70,7 @@ subject { group_group_members_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -82,6 +86,7 @@ subject { edit_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_denied_for(:master).of(group) } it { is_expected.to be_denied_for(:developer).of(group) } diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb index d7d761772692b5f95ef0d2a57db2a341eca3cf33..5532d9790d1ac243a8f614fcd8cf5fc107ebc4ba 100644 --- a/spec/features/security/group/public_access_spec.rb +++ b/spec/features/security/group/public_access_spec.rb @@ -22,6 +22,7 @@ subject { group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -37,6 +38,7 @@ subject { issues_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -52,6 +54,7 @@ subject { merge_requests_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -67,6 +70,7 @@ subject { group_group_members_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_allowed_for(:master).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) } @@ -82,6 +86,7 @@ subject { edit_group_path(group) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(group) } it { is_expected.to be_denied_for(:master).of(group) } it { is_expected.to be_denied_for(:developer).of(group) } diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb index c19678ab381334bad24144b2a1ace31a07613098..86fc58d930669ec08a5f780e62acd322ebed6a2c 100644 --- a/spec/features/security/profile_access_spec.rb +++ b/spec/features/security/profile_access_spec.rb @@ -8,6 +8,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -16,6 +17,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -24,6 +26,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -32,6 +35,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -40,6 +44,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end @@ -48,6 +53,7 @@ it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :auditor } it { is_expected.to be_denied_for :visitor } end end diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 5c3fe62379fa11b119990771e33cfdaf7d1864e3..b601aa03acb1eacd959e0b338f455e66faaadf8d 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -16,6 +16,7 @@ subject { namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -30,6 +31,7 @@ subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -44,6 +46,7 @@ subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -58,6 +61,7 @@ subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -72,6 +76,7 @@ subject { namespace_project_compare_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -86,6 +91,7 @@ subject { namespace_project_settings_members_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -101,6 +107,7 @@ subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -115,6 +122,7 @@ subject { edit_namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -129,6 +137,7 @@ subject { namespace_project_deploy_keys_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -143,6 +152,7 @@ subject { namespace_project_issues_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -158,6 +168,7 @@ subject { edit_namespace_project_issue_path(project.namespace, project, issue) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -172,6 +183,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -186,6 +198,7 @@ subject { new_namespace_project_snippet_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -200,6 +213,7 @@ subject { namespace_project_merge_requests_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -214,6 +228,7 @@ subject { new_namespace_project_merge_request_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -233,6 +248,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -252,6 +268,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -266,6 +283,7 @@ subject { namespace_project_settings_integrations_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -280,6 +298,7 @@ subject { namespace_project_pipelines_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -295,6 +314,7 @@ subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -312,6 +332,7 @@ before { project.update(public_builds: true) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -326,6 +347,7 @@ before { project.update(public_builds: false) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -346,6 +368,7 @@ before { project.update(public_builds: true) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -360,6 +383,7 @@ before { project.update(public_builds: false) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -375,6 +399,7 @@ subject { namespace_project_environments_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -390,6 +415,7 @@ subject { namespace_project_environment_path(project.namespace, project, environment) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -404,6 +430,7 @@ subject { new_namespace_project_environment_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -427,6 +454,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end @@ -438,6 +466,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end end @@ -451,6 +480,7 @@ subject { namespace_project_container_registry_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index 828d7bc496e6225523d5a70048e79286866f5289..e42ea69ebd22220b7aff39414834642a58bafe5d 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -16,6 +16,7 @@ subject { namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -30,6 +31,7 @@ subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -44,6 +46,7 @@ subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -58,6 +61,7 @@ subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -72,6 +76,7 @@ subject { namespace_project_compare_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -86,6 +91,7 @@ subject { namespace_project_settings_members_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -101,6 +107,7 @@ subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore'))} it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -115,6 +122,7 @@ subject { edit_namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -129,6 +137,7 @@ subject { namespace_project_deploy_keys_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -143,6 +152,7 @@ subject { namespace_project_issues_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -158,6 +168,7 @@ subject { edit_namespace_project_issue_path(project.namespace, project, issue) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -172,6 +183,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -186,6 +198,7 @@ subject { namespace_project_merge_requests_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -205,6 +218,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -224,6 +238,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -238,6 +253,7 @@ subject { namespace_project_settings_integrations_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -252,6 +268,7 @@ subject { namespace_project_pipelines_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -279,6 +296,7 @@ subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -305,6 +323,7 @@ subject { namespace_project_builds_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -333,6 +352,7 @@ subject { namespace_project_build_path(project.namespace, project, build.id) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -364,6 +384,7 @@ subject { namespace_project_environments_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -379,6 +400,7 @@ subject { namespace_project_environment_path(project.namespace, project, environment) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -393,6 +415,7 @@ subject { new_namespace_project_environment_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -416,6 +439,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end @@ -427,6 +451,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end end @@ -440,6 +465,7 @@ subject { namespace_project_container_registry_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index 0a5ed2aa36db18011561961a4864eff0bf49b4e7..f121ba36a43c542f914f6b7a3350801d27bf7201 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -16,6 +16,7 @@ subject { namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -30,6 +31,7 @@ subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -44,6 +46,7 @@ subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -58,6 +61,7 @@ subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -72,6 +76,7 @@ subject { namespace_project_compare_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -86,6 +91,7 @@ subject { namespace_project_settings_members_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -100,6 +106,7 @@ subject { namespace_project_pipelines_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -115,6 +122,7 @@ subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -132,6 +140,7 @@ before { project.update(public_builds: true) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -146,6 +155,7 @@ before { project.update(public_builds: false) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -166,6 +176,7 @@ before { project.update(public_builds: true) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -180,6 +191,7 @@ before { project.update(public_builds: false) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -195,6 +207,7 @@ subject { namespace_project_environments_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -210,6 +223,7 @@ subject { namespace_project_environment_path(project.namespace, project, environment) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -224,6 +238,7 @@ subject { new_namespace_project_environment_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -240,6 +255,7 @@ subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -253,6 +269,7 @@ subject { edit_namespace_project_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -267,6 +284,7 @@ subject { namespace_project_deploy_keys_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -281,6 +299,7 @@ subject { namespace_project_issues_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -296,6 +315,7 @@ subject { edit_namespace_project_issue_path(project.namespace, project, issue) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -310,6 +330,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -324,6 +345,7 @@ subject { new_namespace_project_snippet_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -338,6 +360,7 @@ subject { namespace_project_merge_requests_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -352,6 +375,7 @@ subject { new_namespace_project_merge_request_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -371,6 +395,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -390,6 +415,7 @@ end it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -404,6 +430,7 @@ subject { namespace_project_settings_integrations_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_denied_for(:developer).of(project) } @@ -427,6 +454,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end @@ -438,6 +466,7 @@ it { is_expected.to be_denied_for(:admin) } it { is_expected.to be_denied_for(:guest).of(project) } it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_denied_for(:visitor) } end end @@ -451,6 +480,7 @@ subject { namespace_project_container_registry_index_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb index 2659b3ee3ec3aee20c5ce0e5b5032dcd2fe83221..26dd7e0c0b47712de3937246e2770e67df5e1ed0 100644 --- a/spec/features/security/project/snippet/internal_access_spec.rb +++ b/spec/features/security/project/snippet/internal_access_spec.rb @@ -12,6 +12,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -26,6 +27,7 @@ subject { new_namespace_project_snippet_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -41,6 +43,7 @@ subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -55,6 +58,7 @@ subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -71,6 +75,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -85,6 +90,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb index 6eb9f163bd5b25d782c79a3c13f20c2f14ebfaab..bb7ffcccc2be2aeadc8bbd57e8fb58807e97cd79 100644 --- a/spec/features/security/project/snippet/private_access_spec.rb +++ b/spec/features/security/project/snippet/private_access_spec.rb @@ -11,6 +11,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -25,6 +26,7 @@ subject { new_namespace_project_snippet_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -39,6 +41,7 @@ subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -53,6 +56,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb index f3329d0bc9609bb83f0e6f4c8769a584a2ed5ca2..45b8ca8093df3aa5c2c669d0de92029fd767bbe7 100644 --- a/spec/features/security/project/snippet/public_access_spec.rb +++ b/spec/features/security/project/snippet/public_access_spec.rb @@ -13,6 +13,7 @@ subject { namespace_project_snippets_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -27,6 +28,7 @@ subject { new_namespace_project_snippet_path(project.namespace, project) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_denied_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -42,6 +44,7 @@ subject { namespace_project_snippet_path(project.namespace, project, public_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -56,6 +59,7 @@ subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -70,6 +74,7 @@ subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -86,6 +91,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, public_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -100,6 +106,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } @@ -114,6 +121,7 @@ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:auditor) } it { is_expected.to be_allowed_for(:owner).of(project) } it { is_expected.to be_allowed_for(:master).of(project) } it { is_expected.to be_allowed_for(:developer).of(project) } diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb index ef97b061ca7b5398078dcec79b1621905d0cf720..4290adff94fc92355f54056f13c6c640f038c781 100644 --- a/spec/finders/group_projects_finder_spec.rb +++ b/spec/finders/group_projects_finder_spec.rb @@ -76,6 +76,44 @@ end end + describe 'with an admin current user' do + let(:current_user) { create(:admin) } + + context "only shared" do + subject { described_class.new(group, only_shared: true).execute(current_user) } + it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1]) } + end + + context "only owned" do + subject { described_class.new(group, only_owned: true).execute(current_user) } + it { is_expected.to eq([private_project, public_project]) } + end + + context "all" do + subject { described_class.new(group).execute(current_user) } + it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1, private_project, public_project]) } + end + end + + describe 'with an auditor current user' do + let(:current_user) { create(:user, :auditor) } + + context "only shared" do + subject { described_class.new(group, only_shared: true).execute(current_user) } + it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1]) } + end + + context "only owned" do + subject { described_class.new(group, only_owned: true).execute(current_user) } + it { is_expected.to eq([private_project, public_project]) } + end + + context "all" do + subject { described_class.new(group).execute(current_user) } + it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1, private_project, public_project]) } + end + end + describe "no user" do context "only shared" do subject { described_class.new(group, only_shared: true).execute(current_user) } diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index b19def2a3077863e73b3cbe68c42c9968e7307c7..8e9c4c8077cfa1baa89585f3e3529d416a731344 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -258,6 +258,8 @@ describe '.not_restricted_by_confidentiality' do let(:authorized_user) { create(:user) } + let(:admin_user) { create(:admin) } + let(:auditor_user) { create(:user, :auditor) } let(:project) { create(:empty_project, namespace: authorized_user.namespace) } let!(:public_issue) { create(:issue, project: project) } let!(:confidential_issue) { create(:issue, project: project, confidential: true) } @@ -273,5 +275,13 @@ it 'returns all issues for user authorized for the issues projects' do expect(IssuesFinder.send(:not_restricted_by_confidentiality, authorized_user)).to include(public_issue, confidential_issue) end + + it 'returns all issues for an admin user' do + expect(IssuesFinder.send(:not_restricted_by_confidentiality, admin_user)).to include(public_issue, confidential_issue) + end + + it 'returns all issues for an auditor user' do + expect(IssuesFinder.send(:not_restricted_by_confidentiality, auditor_user)).to include(public_issue, confidential_issue) + end end end diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb index 975e99c58072713dec0ebd4a84a9cec9735dd831..94eba72f78ff560bb721f0a7398baf7668c4e21b 100644 --- a/spec/finders/snippets_finder_spec.rb +++ b/spec/finders/snippets_finder_spec.rb @@ -15,12 +15,14 @@ it "returns all private and internal snippets" do snippets = SnippetsFinder.new.execute(user, filter: :all) + expect(snippets).to include(snippet2, snippet3) expect(snippets).not_to include(snippet1) end it "returns all public snippets" do snippets = SnippetsFinder.new.execute(nil, filter: :all) + expect(snippets).to include(snippet3) expect(snippets).not_to include(snippet1, snippet2) end @@ -46,6 +48,7 @@ it "returns all public and internal snippets" do snippets = SnippetsFinder.new.execute(user1, filter: :by_user, user: user) + expect(snippets).to include(snippet2, snippet3) expect(snippets).not_to include(snippet1) end @@ -58,23 +61,27 @@ it "returns private snippets" do snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user, scope: "are_private") + expect(snippets).to include(snippet1) expect(snippets).not_to include(snippet2, snippet3) end it "returns public snippets" do snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user, scope: "are_public") + expect(snippets).to include(snippet3) expect(snippets).not_to include(snippet1, snippet2) end it "returns all snippets" do snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user) + expect(snippets).to include(snippet1, snippet2, snippet3) end it "returns only public snippets if unauthenticated user" do snippets = SnippetsFinder.new.execute(nil, filter: :by_user, user: user) + expect(snippets).to include(snippet3) expect(snippets).not_to include(snippet2, snippet1) end @@ -89,43 +96,68 @@ it "returns public snippets for unauthorized user" do snippets = SnippetsFinder.new.execute(nil, filter: :by_project, project: project1) + expect(snippets).to include(@snippet3) expect(snippets).not_to include(@snippet1, @snippet2) end it "returns public and internal snippets for non project members" do snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) + expect(snippets).to include(@snippet2, @snippet3) expect(snippets).not_to include(@snippet1) end it "returns public snippets for non project members" do snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_public") + expect(snippets).to include(@snippet3) expect(snippets).not_to include(@snippet1, @snippet2) end it "returns internal snippets for non project members" do snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_internal") + expect(snippets).to include(@snippet2) expect(snippets).not_to include(@snippet1, @snippet3) end it "does not return private snippets for non project members" do snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_private") + expect(snippets).not_to include(@snippet1, @snippet2, @snippet3) end it "returns all snippets for project members" do project1.team << [user, :developer] + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) + expect(snippets).to include(@snippet1, @snippet2, @snippet3) end it "returns private snippets for project members" do project1.team << [user, :developer] + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_private") + expect(snippets).to include(@snippet1) end + + it "returns all snippets for admin users" do + user = create(:user, :admin) + + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) + + expect(snippets).to include(@snippet1, @snippet2, @snippet3) + end + + it "returns all snippets for auditor users" do + user = create(:user, :auditor) + + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) + + expect(snippets).to include(@snippet1, @snippet2, @snippet3) + end end end diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb index 8589f1eb712de8a3aa61e89afa47851b5dbf883b..2a188a8e0e573631ad44d78d20b6398fef69172b 100644 --- a/spec/models/project_feature_spec.rb +++ b/spec/models/project_feature_spec.rb @@ -52,6 +52,15 @@ expect(project.feature_available?(:issues, user)).to eq(true) end end + + it "returns true if user is an auditor" do + user.update_attribute(:auditor, true) + + features.each do |feature| + project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE) + expect(project.feature_available?(:issues, user)).to eq(true) + end + end end context 'when feature is enabled for everyone' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 929200469e1509c42d64428cdef83580d8c8a9f7..014d70acfab4d41171be9d11237fe97aee7126ec 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -198,6 +198,12 @@ end end end + + it 'does not allow a user to be both an auditor and an admin' do + user = build(:user, :admin, :auditor) + + expect(user).to be_invalid + end end describe "non_ldap" do @@ -1415,7 +1421,7 @@ def add_user(access) it 'returns the projects when using an ActiveRecord relation' do projects = user. - projects_with_reporter_access_limited_to(Project.select(:id)) + projects_with_reporter_access_limited_to(Project.select(:id)) expect(projects).to eq([project1]) end @@ -1486,4 +1492,141 @@ def add_user(access) expect(user.project_authorizations.where(access_level: Gitlab::Access::REPORTER).exists?).to eq(true) end end + + describe '#access_level=' do + let(:user) { build(:user) } + + before do + # `auditor?` returns true only when the user is an auditor _and_ the auditor license + # add-on is present. We aren't testing this here, so we can assume that the add-on exists. + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { true } + end + + it 'does nothing for an invalid access level' do + user.access_level = :invalid_access_level + + expect(user.access_level).to eq(:regular) + expect(user.admin).to be false + expect(user.auditor).to be false + end + + it "assigns the 'admin' access level" do + user.access_level = :admin + + expect(user.access_level).to eq(:admin) + expect(user.admin).to be true + expect(user.auditor).to be false + end + + it "assigns the 'auditor' access level" do + user.access_level = :auditor + + expect(user.access_level).to eq(:auditor) + expect(user.admin).to be false + expect(user.auditor).to be true + end + + it "assigns the 'auditor' access level" do + user.access_level = :regular + + expect(user.access_level).to eq(:regular) + expect(user.admin).to be false + expect(user.auditor).to be false + end + + it "clears the 'admin' access level when a user is made an auditor" do + user.access_level = :admin + user.access_level = :auditor + + expect(user.access_level).to eq(:auditor) + expect(user.admin).to be false + expect(user.auditor).to be true + end + + it "clears the 'auditor' access level when a user is made an admin" do + user.access_level = :auditor + user.access_level = :admin + + expect(user.access_level).to eq(:admin) + expect(user.admin).to be true + expect(user.auditor).to be false + end + + it "doesn't clear existing access levels when an invalid access level is passed in" do + user.access_level = :admin + user.access_level = :invalid_access_level + + expect(user.access_level).to eq(:admin) + expect(user.admin).to be true + expect(user.auditor).to be false + end + + it "accepts string values in addition to symbols" do + user.access_level = 'admin' + + expect(user.access_level).to eq(:admin) + expect(user.admin).to be true + expect(user.auditor).to be false + end + end + + describe 'the GitLab_Auditor_User add-on' do + let(:license) { build(:license) } + + before do + allow(::License).to receive(:current).and_return(license) + end + + context 'creating an auditor user' do + it "does not allow creating an auditor user if the addon isn't enabled" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { false } + + expect(build(:user, :auditor)).to be_invalid + end + + it "does not allow creating an auditor user if no license is present" do + allow(License).to receive(:current).and_return nil + + expect(build(:user, :auditor)).to be_invalid + end + + it "allows creating an auditor user if the addon is enabled" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { true } + + expect(build(:user, :auditor)).to be_valid + end + + it "allows creating a regular user if the addon isn't enabled" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { false } + + expect(build(:user)).to be_valid + end + end + + context '#auditor?' do + it "returns true for an auditor user if the addon is enabled" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { true } + + expect(build(:user, :auditor)).to be_auditor + end + + it "returns false for an auditor user if the addon is not enabled" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { false } + + expect(build(:user, :auditor)).not_to be_auditor + end + + it "returns false for an auditor user if a license is not present" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { false } + + expect(build(:user, :auditor)).not_to be_auditor + end + + it "returns false for a non-auditor user even if the addon is present" do + allow_any_instance_of(License).to receive(:add_on?).with('GitLab_Auditor_User') { true } + + expect(build(:user)).not_to be_auditor + end + end + end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 5c34ff041529f6c254fa8018f05b1ab200bb4b81..4f28ec22a62ef2a31be0e65e000780d3b917fd27 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -6,6 +6,7 @@ let(:developer) { create(:user) } let(:master) { create(:user) } let(:owner) { create(:user) } + let(:auditor) { create(:user, :auditor) } let(:admin) { create(:admin) } let(:group) { create(:group) } @@ -170,5 +171,16 @@ is_expected.to include(*owner_permissions) end end + + context 'auditor' do + let(:current_user) { auditor } + + it do + is_expected.to include(:read_group) + is_expected.to all(start_with("read")) + is_expected.not_to include(*master_permissions) + is_expected.not_to include(*owner_permissions) + end + end end end diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b7a9f05a7d6a303246d3f7636f250d42227285af --- /dev/null +++ b/spec/policies/namespace_policy_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe NamespacePolicy, models: true do + let(:user) { create(:user) } + let(:owner) { create(:user) } + let(:auditor) { create(:user, :auditor) } + let(:admin) { create(:admin) } + let(:namespace) { create(:namespace, owner: owner) } + + let(:owner_permissions) { [:create_projects, :admin_namespace] } + + let(:admin_permissions) { owner_permissions } + + subject { described_class.abilities(current_user, namespace).to_set } + + context 'with no user' do + let(:current_user) { nil } + + it { is_expected.to be_empty } + end + + context 'regular user' do + let(:current_user) { user } + + it { is_expected.to be_empty } + end + + context 'owner' do + let(:current_user) { owner } + + it { is_expected.to include(*owner_permissions) } + end + + context 'auditor' do + let(:current_user) { auditor } + + context 'owner' do + let(:namespace) { create(:namespace, owner: auditor) } + + it { is_expected.to include(*owner_permissions) } + end + + context 'non-owner' do + it { is_expected.to be_empty } + end + end + + context 'admin' do + let(:current_user) { admin } + + it { is_expected.to include(*owner_permissions) } + end +end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index eeab9827d994530f639ca91fb4015655725723a0..0c82568dcdf2ac9098a4dd851ec07b36ae0efd9f 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -6,65 +6,74 @@ let(:dev) { create(:user) } let(:master) { create(:user) } let(:owner) { create(:user) } + let(:auditor) { create(:user, :auditor) } let(:admin) { create(:admin) } let(:project) { create(:empty_project, :public, namespace: owner.namespace) } let(:guest_permissions) do - [ - :read_project, :read_board, :read_list, :read_wiki, :read_issue, :read_label, - :read_milestone, :read_project_snippet, :read_project_member, - :read_note, :create_project, :create_issue, :create_note, - :upload_file + %i[ + read_project read_board read_list read_wiki read_issue read_label + read_milestone read_project_snippet read_project_member + read_note create_project create_issue create_note + upload_file ] end let(:reporter_permissions) do - [ - :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 + %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 ] end let(:team_member_reporter_permissions) do - [ - :build_download_code, :build_read_container_image - ] + %i[build_download_code build_read_container_image] end let(:developer_permissions) do - [ - :admin_merge_request, :update_merge_request, :create_commit_status, - :update_commit_status, :create_build, :update_build, :create_pipeline, - :update_pipeline, :create_merge_request, :create_wiki, :push_code, - :resolve_note, :create_container_image, :update_container_image, - :create_environment, :create_deployment + %i[ + admin_merge_request update_merge_request create_commit_status + update_commit_status create_build update_build create_pipeline + update_pipeline create_merge_request create_wiki push_code + resolve_note create_container_image update_container_image + create_environment create_deployment ] end let(:master_permissions) do - [ - :push_code_to_protected_branches, :update_project_snippet, :update_environment, - :update_deployment, :admin_milestone, :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 + %i[ + push_code_to_protected_branches update_project_snippet update_environment + update_deployment admin_milestone 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 ] end let(:public_permissions) do - [ - :download_code, :fork_project, :read_commit_status, :read_pipeline, - :read_container_image, :build_download_code, :build_read_container_image, - :download_wiki_code + %i[ + download_code fork_project read_commit_status read_pipeline + read_container_image build_download_code build_read_container_image + download_wiki_code ] end let(:owner_permissions) do - [ - :change_namespace, :change_visibility_level, :rename_project, :remove_project, - :archive_project, :remove_fork_project, :destroy_merge_request, :destroy_issue + %i[ + change_namespace change_visibility_level rename_project remove_project + archive_project remove_fork_project destroy_merge_request destroy_issue + ] + end + + let(:auditor_permissions) do + %i[ + download_code download_wiki_code read_project read_board read_list + read_wiki read_issue read_label read_milestone read_project_snippet + read_project_member read_note read_cycle_analytics read_pipeline + read_build read_commit_status read_container_image read_environment + read_deployment read_merge_request read_pages ] end @@ -207,5 +216,16 @@ is_expected.to include(*owner_permissions) end end + + context 'auditor' do + let(:current_user) { auditor } + + it do + is_expected.not_to include(*developer_permissions) + is_expected.not_to include(*master_permissions) + is_expected.not_to include(*owner_permissions) + is_expected.to include(*auditor_permissions) + end + end end end diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..7b7c622ac31be69c434cda0ef69ce0109bfb7c3c --- /dev/null +++ b/spec/policies/project_snippet_policy_spec.rb @@ -0,0 +1,119 @@ +require 'spec_helper' + +describe ProjectSnippetPolicy, models: true do + let(:current_user) { create(:user) } + + let(:author_permissions) do + [ + :update_project_snippet, + :admin_project_snippet + ] + end + + subject { described_class.abilities(current_user, project_snippet).to_set } + + context 'public snippet' do + let(:project_snippet) { create(:project_snippet, :public) } + + context 'no user' do + let(:current_user) { nil } + + it do + is_expected.to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'regular user' do + it do + is_expected.to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + end + + context 'internal snippet' do + let(:project_snippet) { create(:project_snippet, :internal) } + + context 'no user' do + let(:current_user) { nil } + + it do + is_expected.not_to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'regular user' do + it do + is_expected.to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'external user' do + let(:current_user) { create(:user, :external) } + + it do + is_expected.not_to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + end + + context 'private snippet' do + let(:project_snippet) { create(:project_snippet, :private) } + + context 'no user' do + let(:current_user) { nil } + + it do + is_expected.not_to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'regular user' do + it do + is_expected.not_to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'snippet author' do + let(:project_snippet) { create(:project_snippet, :private, author: current_user) } + + it do + is_expected.to include(:read_project_snippet) + is_expected.to include(*author_permissions) + end + end + + context 'project team member' do + before { project_snippet.project.team << [current_user, :developer] } + + it do + is_expected.to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'auditor user' do + let(:current_user) { create(:user, :auditor) } + + it do + is_expected.to include(:read_project_snippet) + is_expected.not_to include(*author_permissions) + end + end + + context 'admin user' do + let(:current_user) { create(:admin) } + + it do + is_expected.to include(:read_project_snippet) + is_expected.to include(*author_permissions) + end + end + end +end diff --git a/spec/requests/api/license_spec.rb b/spec/requests/api/license_spec.rb index d5fe60e0a6decf15e86ab7d0a39512c08d29078d..9063380ce2e94601978d76d6af11b27030750b1f 100644 --- a/spec/requests/api/license_spec.rb +++ b/spec/requests/api/license_spec.rb @@ -17,7 +17,7 @@ expect(Date.parse(json_response['expires_at'])).to eq Date.today + 11.months expect(json_response['active_users']).to eq 1 expect(json_response['licensee']).not_to be_empty - expect(json_response['add_ons']).to eq({ 'GitLab_FileLocks' => 1 }) + expect(json_response['add_ons']).to eq({ 'GitLab_FileLocks' => 1, 'GitLab_Auditor_User' => 1 }) end it 'denies access if not admin' do diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb index 4a045b78187b3f402b961c4f3d70adc0f3582127..1459c745828ab9e4053763984d9da82cb5869c5a 100644 --- a/spec/services/groups/update_service_spec.rb +++ b/spec/services/groups/update_service_spec.rb @@ -76,7 +76,7 @@ end context 'rename group' do - let!(:service) { described_class.new(internal_group, user, path: 'new_path') } + let!(:service) { described_class.new(internal_group, user, path: SecureRandom.hex) } before do internal_group.add_user(user, Gitlab::Access::MASTER) diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb index 26e8bf5c02743e9d22a0cbc4b15636a130d22a66..6b0028a6089b1a4e683582fae4a7a063c9ea2de9 100644 --- a/spec/support/db_cleaner.rb +++ b/spec/support/db_cleaner.rb @@ -12,7 +12,7 @@ end config.before(:each, truncate: true) do - DatabaseCleaner.strategy = :truncation + DatabaseCleaner.strategy = :truncation, { except: ['licenses'] } end config.before(:each) do diff --git a/spec/support/matchers/access_matchers.rb b/spec/support/matchers/access_matchers.rb index ceddb6565961a0d5aa67c5bd65c552828f6016ce..63cdfc73310cea69b598f4824d9953858a599910 100644 --- a/spec/support/matchers/access_matchers.rb +++ b/spec/support/matchers/access_matchers.rb @@ -15,6 +15,8 @@ def emulate_user(user, membership = nil) logout when :admin login_as(create(:admin)) + when :auditor + login_as(create(:user, :auditor)) when :external login_as(create(:user, external: true)) when User