Commit f539b03a authored by Diego Louzán's avatar Diego Louzán Committed by Bob Van Landuyt

Use policies framework for determining admin access to groups

parent 3c0902c7
......@@ -505,7 +505,7 @@ class Group < Namespace
# @param only_concrete_membership [Bool] whether require admin concrete membership status
def max_member_access_for_user(user, only_concrete_membership: false)
return GroupMember::NO_ACCESS unless user
return GroupMember::OWNER if user.admin? && !only_concrete_membership
return GroupMember::OWNER if user.can_admin_all_resources? && !only_concrete_membership
max_member_access = members_with_parents.where(user_id: user)
.reorder(access_level: :desc)
......
......@@ -1704,6 +1704,10 @@ class User < ApplicationRecord
can?(:read_all_resources)
end
def can_admin_all_resources?
can?(:admin_all_resources)
end
def update_two_factor_requirement
periods = expanded_groups_requiring_two_factor_authentication.pluck(:two_factor_grace_period)
......
......@@ -55,14 +55,17 @@ class BasePolicy < DeclarativePolicy::Base
prevent :read_cross_project
end
# Policy extended in EE to also enable auditors
rule { admin }.enable :read_all_resources
rule { admin }.policy do
# Only for actual administrator accounts, behaviour affected by admin mode application setting
enable :admin_all_resources
# Policy extended in EE to also enable auditors
enable :read_all_resources
enable :change_repository_storage
end
rule { default }.enable :read_cross_project
condition(:is_gitlab_com) { ::Gitlab.dev_env_or_com? }
rule { admin }.enable :change_repository_storage
end
BasePolicy.prepend_if_ee('EE::BasePolicy')
---
title: Use policies for group access rights as admin
merge_request: 55349
author: Diego Louzán
type: changed
......@@ -41,7 +41,12 @@ RSpec.describe Groups::ClustersController do
allow(controller).to receive(:prometheus_adapter).and_return(prometheus_adapter)
end
it { expect { go }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { go }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { go }.to be_denied_for(:admin) }
end
it { expect { go }.to be_allowed_for(:owner).of(clusterable) }
it { expect { go }.to be_allowed_for(:maintainer).of(clusterable) }
it { expect { go }.to be_denied_for(:developer).of(clusterable) }
......@@ -78,7 +83,12 @@ RSpec.describe Groups::ClustersController do
end
describe 'security' do
it { expect { get_cluster_environments }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { get_cluster_environments }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { get_cluster_environments }.to be_denied_for(:admin) }
end
it { expect { get_cluster_environments }.to be_allowed_for(:owner).of(group) }
it { expect { get_cluster_environments }.to be_allowed_for(:maintainer).of(group) }
it { expect { get_cluster_environments }.to be_denied_for(:developer).of(group) }
......
......@@ -20,7 +20,12 @@ RSpec.describe '[EE] Private Group access' do
subject { group_insights_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
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(:maintainer).of(group) }
......
......@@ -75,9 +75,7 @@ RSpec.describe Event do
end
context 'when admin mode disabled' do
# Skipped because `Group#max_member_access_for_user` needs to be migrated to use admin mode
# See https://gitlab.com/gitlab-org/gitlab/-/issues/207950
xit 'is not visible to admin', :aggregate_failures do
it 'is not visible to admin', :aggregate_failures do
expect(event).not_to be_visible_to(admin)
end
end
......
......@@ -265,6 +265,14 @@ RSpec.describe User do
end
end
describe '#can_admin_all_resources?' do
it 'returns false for auditor user' do
user = build(:user, :auditor)
expect(user.can_admin_all_resources?).to be_falsy
end
end
describe '#forget_me!' do
subject { create(:user, remember_created_at: Time.current) }
......
......@@ -26,4 +26,10 @@ RSpec.describe BasePolicy do
is_expected.to be_allowed(:read_all_resources)
end
end
describe 'admin all resources' do
it 'forbids auditors' do
is_expected.to be_disallowed(:admin_all_resources)
end
end
end
This diff is collapsed.
......@@ -4,9 +4,14 @@ require 'spec_helper'
RSpec.describe Epics::TransferService do
describe '#execute' do
let_it_be(:user) { create(:admin) }
let_it_be(:user) { create(:user) }
let_it_be(:new_group, refind: true) { create(:group) }
let_it_be(:old_group, refind: true) { create(:group) }
before do
old_group.add_maintainer(user) if old_group
end
subject(:service) { described_class.new(user, old_group, project) }
context 'when old_group is present' do
......
......@@ -114,7 +114,7 @@ RSpec.describe TodoService do
context 'for mentioned users' do
let(:todo_params) { { action: Todo::MENTIONED } }
let(:todos_for) { [member, author, guest, admin] }
let(:todos_for) { [member, author, guest] }
let(:todos_not_for) { [non_member, john_doe, skipped] }
include_examples 'todos creation'
......@@ -126,7 +126,7 @@ RSpec.describe TodoService do
end
let(:todo_params) { { action: Todo::DIRECTLY_ADDRESSED } }
let(:todos_for) { [member, author, guest, admin] }
let(:todos_for) { [member, author, guest] }
let(:todos_not_for) { [non_member, john_doe, skipped] }
include_examples 'todos creation'
......
......@@ -10,6 +10,7 @@ RSpec.describe 'groups/compliance_frameworks/edit.html.haml' do
assign(:group, group)
allow(view).to receive(:current_user).and_return(user)
allow(user).to receive(:can_admin_all_resources?).and_return(false)
allow(user).to receive(:can?).with(:admin_compliance_pipeline_configuration, group).and_return(true)
allow(view).to receive(:params).and_return(id: 1)
end
......
......@@ -10,6 +10,7 @@ RSpec.describe 'groups/compliance_frameworks/new.html.haml' do
assign(:group, group)
allow(view).to receive(:current_user).and_return(user)
allow(user).to receive(:can_admin_all_resources?).and_return(false)
allow(user).to receive(:can?).with(:admin_compliance_pipeline_configuration, group).and_return(true)
end
......
......@@ -6,7 +6,7 @@ module DeclarativePolicy
# Policy class (context_class here). See Base.rule
#
# Note that the #policy method just performs an #instance_eval,
# which is useful for multiple #enable or #prevent callse.
# which is useful for multiple #enable or #prevent calls.
#
# Also provides a #method_missing proxy to the context
# class's class methods, so that helper methods can be
......
......@@ -10,7 +10,8 @@ RSpec.describe Groups::Clusters::ApplicationsController do
end
shared_examples 'a secure endpoint' do
it { expect { subject }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { subject }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { subject }.to be_denied_for(:admin) }
it { expect { subject }.to be_allowed_for(:owner).of(group) }
it { expect { subject }.to be_allowed_for(:maintainer).of(group) }
it { expect { subject }.to be_denied_for(:developer).of(group) }
......
......@@ -99,7 +99,8 @@ RSpec.describe Groups::ClustersController do
describe 'security' do
let(:cluster) { create(:cluster, :provided_by_gcp, cluster_type: :group_type, groups: [group]) }
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -183,7 +184,8 @@ RSpec.describe Groups::ClustersController do
include_examples 'GET new cluster shared examples'
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -316,7 +318,8 @@ RSpec.describe Groups::ClustersController do
allow(WaitForClusterCreationWorker).to receive(:perform_in).and_return(nil)
end
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -418,7 +421,8 @@ RSpec.describe Groups::ClustersController do
end
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -486,7 +490,8 @@ RSpec.describe Groups::ClustersController do
allow(WaitForClusterCreationWorker).to receive(:perform_in)
end
it { expect { post_create_aws }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { post_create_aws }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { post_create_aws }.to be_denied_for(:admin) }
it { expect { post_create_aws }.to be_allowed_for(:owner).of(group) }
it { expect { post_create_aws }.to be_allowed_for(:maintainer).of(group) }
it { expect { post_create_aws }.to be_denied_for(:developer).of(group) }
......@@ -544,7 +549,8 @@ RSpec.describe Groups::ClustersController do
end
end
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -580,7 +586,8 @@ RSpec.describe Groups::ClustersController do
end
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -619,7 +626,8 @@ RSpec.describe Groups::ClustersController do
end
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -651,7 +659,8 @@ RSpec.describe Groups::ClustersController do
end
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -759,7 +768,8 @@ RSpec.describe Groups::ClustersController do
describe 'security' do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, cluster_type: :group_type, groups: [group]) }
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......@@ -827,7 +837,8 @@ RSpec.describe Groups::ClustersController do
describe 'security' do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group]) }
it { expect { go }.to be_allowed_for(:admin) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { expect { go }.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(group) }
it { expect { go }.to be_allowed_for(:maintainer).of(group) }
it { expect { go }.to be_denied_for(:developer).of(group) }
......
......@@ -4,17 +4,23 @@ require 'spec_helper'
RSpec.describe GroupsController, factory_default: :keep do
include ExternalAuthorizationServiceHelpers
include AdminModeHelper
let_it_be_with_refind(:group) { create_default(:group, :public) }
let_it_be_with_refind(:project) { create(:project, namespace: group) }
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create(:admin) }
let_it_be(:admin_with_admin_mode) { create(:admin) }
let_it_be(:admin_without_admin_mode) { create(:admin) }
let_it_be(:group_member) { create(:group_member, group: group, user: user) }
let_it_be(:owner) { group.add_owner(create(:user)).user }
let_it_be(:maintainer) { group.add_maintainer(create(:user)).user }
let_it_be(:developer) { group.add_developer(create(:user)).user }
let_it_be(:guest) { group.add_guest(create(:user)).user }
before do
enable_admin_mode!(admin_with_admin_mode)
end
shared_examples 'member with ability to create subgroups' do
it 'renders the new page' do
sign_in(member)
......@@ -105,10 +111,10 @@ RSpec.describe GroupsController, factory_default: :keep do
[true, false].each do |can_create_group_status|
context "and can_create_group is #{can_create_group_status}" do
before do
User.where(id: [admin, owner, maintainer, developer, guest]).update_all(can_create_group: can_create_group_status)
User.where(id: [admin_with_admin_mode, admin_without_admin_mode, owner, maintainer, developer, guest]).update_all(can_create_group: can_create_group_status)
end
[:admin, :owner, :maintainer].each do |member_type|
[:admin_with_admin_mode, :owner, :maintainer].each do |member_type|
context "and logged in as #{member_type.capitalize}" do
it_behaves_like 'member with ability to create subgroups' do
let(:member) { send(member_type) }
......@@ -116,7 +122,7 @@ RSpec.describe GroupsController, factory_default: :keep do
end
end
[:guest, :developer].each do |member_type|
[:guest, :developer, :admin_without_admin_mode].each do |member_type|
context "and logged in as #{member_type.capitalize}" do
it_behaves_like 'member without ability to create subgroups' do
let(:member) { send(member_type) }
......@@ -856,6 +862,12 @@ RSpec.describe GroupsController, factory_default: :keep do
end
describe 'POST #export' do
let(:admin) { create(:admin) }
before do
enable_admin_mode!(admin)
end
context 'when the group export feature flag is not enabled' do
before do
sign_in(admin)
......@@ -918,6 +930,12 @@ RSpec.describe GroupsController, factory_default: :keep do
end
describe 'GET #download_export' do
let(:admin) { create(:admin) }
before do
enable_admin_mode!(admin)
end
context 'when there is a file available to download' do
let(:export_file) { fixture_file_upload('spec/fixtures/group_export.tar.gz') }
......@@ -934,8 +952,6 @@ RSpec.describe GroupsController, factory_default: :keep do
end
context 'when there is no file available to download' do
let(:admin) { create(:admin) }
before do
sign_in(admin)
end
......
......@@ -143,7 +143,7 @@ RSpec.describe 'Group' do
end
end
describe 'create a nested group', :js do
describe 'create a nested group' do
let_it_be(:group) { create(:group, path: 'foo') }
context 'as admin' do
......@@ -153,13 +153,21 @@ RSpec.describe 'Group' do
visit new_group_path(group, parent_id: group.id)
end
it 'creates a nested group' do
fill_in 'Group name', with: 'bar'
fill_in 'Group URL', with: 'bar'
click_button 'Create group'
context 'when admin mode is enabled', :enable_admin_mode do
it 'creates a nested group' do
fill_in 'Group name', with: 'bar'
fill_in 'Group URL', with: 'bar'
click_button 'Create group'
expect(current_path).to eq(group_path('foo/bar'))
expect(page).to have_content("Group 'bar' was successfully created.")
expect(current_path).to eq(group_path('foo/bar'))
expect(page).to have_content("Group 'bar' was successfully created.")
end
end
context 'when admin mode is disabled' do
it 'is not allowed' do
expect(page).to have_gitlab_http_status(:not_found)
end
end
end
......
......@@ -95,33 +95,55 @@ RSpec.describe 'New project', :js do
end
context 'when group visibility is private but default is internal' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
visit new_project_path(namespace_id: group.id)
find('[data-qa-selector="blank_project_link"]').click
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id)
find('[data-qa-selector="blank_project_link"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id)
expect(page).to have_content('Not Found')
end
end
end
context 'when group visibility is public but user requests private' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
find('[data-qa-selector="blank_project_link"]').click
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
find('[data-qa-selector="blank_project_link"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
expect(page).to have_content('Not Found')
end
end
end
......
......@@ -24,7 +24,12 @@ RSpec.describe 'Internal Group access' do
describe 'GET /groups/:path' do
subject { group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -39,7 +44,12 @@ RSpec.describe 'Internal Group access' do
describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -56,7 +66,12 @@ RSpec.describe 'Internal Group access' do
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -71,7 +86,12 @@ RSpec.describe 'Internal Group access' do
describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -86,7 +106,12 @@ RSpec.describe 'Internal Group access' do
describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_denied_for(:maintainer).of(group) }
it { is_expected.to be_denied_for(:developer).of(group) }
......
......@@ -24,7 +24,12 @@ RSpec.describe 'Private Group access' do
describe 'GET /groups/:path' do
subject { group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -39,7 +44,12 @@ RSpec.describe 'Private Group access' do
describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -56,7 +66,12 @@ RSpec.describe 'Private Group access' do
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -71,7 +86,12 @@ RSpec.describe 'Private Group access' do
describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -86,7 +106,12 @@ RSpec.describe 'Private Group access' do
describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_denied_for(:maintainer).of(group) }
it { is_expected.to be_denied_for(:developer).of(group) }
......@@ -107,7 +132,12 @@ RSpec.describe 'Private Group access' do
subject { group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......
......@@ -24,7 +24,12 @@ RSpec.describe 'Public Group access' do
describe 'GET /groups/:path' do
subject { group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -39,7 +44,12 @@ RSpec.describe 'Public Group access' do
describe 'GET /groups/:path/-/issues' do
subject { issues_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -56,7 +66,12 @@ RSpec.describe 'Public Group access' do
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -71,7 +86,12 @@ RSpec.describe 'Public Group access' do
describe 'GET /groups/:path/-/group_members' do
subject { group_group_members_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_allowed_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_allowed_for(:maintainer).of(group) }
it { is_expected.to be_allowed_for(:developer).of(group) }
......@@ -86,7 +106,12 @@ RSpec.describe 'Public Group access' do
describe 'GET /groups/:path/-/edit' do
subject { edit_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_denied_for(:admin) }
end
it { is_expected.to be_allowed_for(:owner).of(group) }
it { is_expected.to be_denied_for(:maintainer).of(group) }
it { is_expected.to be_denied_for(:developer).of(group) }
......
......@@ -46,13 +46,26 @@ RSpec.describe NamespacesHelper do
end
describe '#namespaces_options' do
it 'returns groups without being a member for admin' do
allow(helper).to receive(:current_user).and_return(admin)
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns groups without being a member for admin' do
allow(helper).to receive(:current_user).and_return(admin)
options = helper.namespaces_options(user_group.id, display_path: true, extra_group: user_group.id)
options = helper.namespaces_options(user_group.id, display_path: true, extra_group: user_group.id)
expect(options).to include(admin_group.name)
expect(options).to include(user_group.name)
expect(options).to include(admin_group.name)
expect(options).to include(user_group.name)
end
end
context 'when admin mode is disabled' do
it 'returns only allowed namespaces for admin' do
allow(helper).to receive(:current_user).and_return(admin)
options = helper.namespaces_options(user_group.id, display_path: true, extra_group: user_group.id)
expect(options).to include(admin_group.name)
expect(options).not_to include(user_group.name)
end
end
it 'returns only allowed namespaces for user' do
......@@ -74,13 +87,16 @@ RSpec.describe NamespacesHelper do
expect(options).to include(admin_group.name)
end
it 'selects existing group' do
allow(helper).to receive(:current_user).and_return(admin)
context 'when admin mode is disabled' do
it 'selects existing group' do
allow(helper).to receive(:current_user).and_return(admin)
user_group.add_owner(admin)
options = helper.namespaces_options(:extra_group, display_path: true, extra_group: user_group)
options = helper.namespaces_options(:extra_group, display_path: true, extra_group: user_group)
expect(options).to include("selected=\"selected\" value=\"#{user_group.id}\"")
expect(options).to include(admin_group.name)
expect(options).to include("selected=\"selected\" value=\"#{user_group.id}\"")
expect(options).to include(admin_group.name)
end
end
it 'selects the new group by default' do
......
......@@ -349,14 +349,22 @@ RSpec.describe Gitlab::ImportExport::Project::TreeSaver do
project_tree_saver.save
end
it 'exports group members as admin' do
expect(member_emails).to include('group@member.com')
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'exports group members as admin' do
expect(member_emails).to include('group@member.com')
end
it 'exports group members as project members' do
member_types = subject.map { |pm| pm['source_type'] }
it 'exports group members as project members' do
member_types = subject.map { |pm| pm['source_type'] }
expect(member_types).to all(eq('Project'))
end
end
expect(member_types).to all(eq('Project'))
context 'when admin mode is disabled' do
it 'does not export group members' do
expect(member_emails).not_to include('group@member.com')
end
end
end
end
......
......@@ -781,8 +781,16 @@ RSpec.describe Group do
context 'evaluating admin access level' do
let_it_be(:admin) { create(:admin) }
it 'returns OWNER by default' do
expect(group.max_member_access_for_user(admin)).to eq(Gitlab::Access::OWNER)
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns OWNER by default' do
expect(group.max_member_access_for_user(admin)).to eq(Gitlab::Access::OWNER)
end
end
context 'when admin mode is disabled' do
it 'returns NO_ACCESS' do
expect(group.max_member_access_for_user(admin)).to eq(Gitlab::Access::NO_ACCESS)
end
end
it 'returns NO_ACCESS when only concrete membership should be considered' do
......
......@@ -425,12 +425,10 @@ RSpec.describe Member do
end
context 'when admin mode is disabled' do
# Skipped because `Group#max_member_access_for_user` needs to be migrated to use admin mode
# https://gitlab.com/gitlab-org/gitlab/-/issues/207950
xit 'rejects setting members.created_by to the given admin current_user' do
it 'rejects setting members.created_by to the given admin current_user' do
member = described_class.add_user(source, user, :maintainer, current_user: admin)
expect(member.created_by).not_to be_persisted
expect(member.created_by).to be_nil
end
end
......
......@@ -3961,6 +3961,37 @@ RSpec.describe User do
end
end
describe '#can_admin_all_resources?', :request_store do
it 'returns false for regular user' do
user = build_stubbed(:user)
expect(user.can_admin_all_resources?).to be_falsy
end
context 'for admin user' do
include_context 'custom session'
let(:user) { build_stubbed(:user, :admin) }
context 'when admin mode is disabled' do
it 'returns false' do
expect(user.can_admin_all_resources?).to be_falsy
end
end
context 'when admin mode is enabled' do
before do
Gitlab::Auth::CurrentUserMode.new(user).request_admin_mode!
Gitlab::Auth::CurrentUserMode.new(user).enable_admin_mode!(password: user.password)
end
it 'returns true' do
expect(user.can_admin_all_resources?).to be_truthy
end
end
end
end
describe '.ghost' do
it "creates a ghost user if one isn't already present" do
ghost = described_class.ghost
......
......@@ -73,10 +73,14 @@ RSpec.describe BasePolicy do
end
end
describe 'full private access' do
describe 'full private access: read_all_resources' do
it_behaves_like 'admin only access', :read_all_resources
end
describe 'full private access: admin_all_resources' do
it_behaves_like 'admin only access', :admin_all_resources
end
describe 'change_repository_storage' do
it_behaves_like 'admin only access', :change_repository_storage
end
......
......@@ -193,16 +193,24 @@ RSpec.describe GroupPolicy do
let(:current_user) { admin }
specify do
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
expect_allowed(*maintainer_permissions)
expect_allowed(*owner_permissions)
expect_disallowed(*read_group_permissions)
expect_disallowed(*guest_permissions)
expect_disallowed(*reporter_permissions)
expect_disallowed(*developer_permissions)
expect_disallowed(*maintainer_permissions)
expect_disallowed(*owner_permissions)
end
context 'with admin mode', :enable_admin_mode do
specify { expect_allowed(*admin_permissions) }
specify do
expect_allowed(*read_group_permissions)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
expect_allowed(*maintainer_permissions)
expect_allowed(*owner_permissions)
expect_allowed(*admin_permissions)
end
end
it_behaves_like 'deploy token does not get confused with user' do
......@@ -773,7 +781,13 @@ RSpec.describe GroupPolicy do
context 'admin' do
let(:current_user) { admin }
it { is_expected.to be_allowed(:create_jira_connect_subscription) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:create_jira_connect_subscription) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_disallowed(:create_jira_connect_subscription) }
end
end
context 'with owner' do
......@@ -817,7 +831,13 @@ RSpec.describe GroupPolicy do
context 'admin' do
let(:current_user) { admin }
it { is_expected.to be_allowed(:read_package) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:read_package) }
end
context 'when admin mode is disabled' do
it { is_expected.to be_disallowed(:read_package) }
end
end
context 'with owner' do
......
......@@ -86,14 +86,22 @@ RSpec.describe Projects::ImportExport::ProjectExportPresenter do
context 'as admin' do
let(:user) { create(:admin) }
it 'exports group members as admin' do
expect(member_emails).to include('group@member.com')
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'exports group members as admin' do
expect(member_emails).to include('group@member.com')
end
it 'exports group members as project members' do
member_types = subject.project_members.map { |pm| pm.source_type }
it 'exports group members as project members' do
member_types = subject.project_members.map { |pm| pm.source_type }
expect(member_types).to all(eq('Project'))
end
end
expect(member_types).to all(eq('Project'))
context 'when admin mode is disabled' do
it 'does not export group members' do
expect(member_emails).not_to include('group@member.com')
end
end
end
end
......
......@@ -54,7 +54,7 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'with group_import_ndjson feature flag disabled' do
let(:user) { create(:admin) }
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:import_logger) { instance_double(Gitlab::Import::Logger) }
......@@ -63,6 +63,8 @@ RSpec.describe Groups::ImportExport::ImportService do
before do
stub_feature_flags(group_import_ndjson: false)
group.add_owner(user)
ImportExportUpload.create!(group: group, import_file: import_file)
allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
......@@ -95,7 +97,7 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when importing a ndjson export' do
let(:user) { create(:admin) }
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:service) { described_class.new(group: group, user: user) }
let(:import_file) { fixture_file_upload('spec/fixtures/group_export.tar.gz') }
......@@ -115,6 +117,10 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when user has correct permissions' do
before do
group.add_owner(user)
end
it 'imports group structure successfully' do
expect(subject).to be_truthy
end
......@@ -147,8 +153,6 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when user does not have correct permissions' do
let(:user) { create(:user) }
it 'logs the error and raises an exception' do
expect(import_logger).to receive(:error).with(
group_id: group.id,
......@@ -188,6 +192,10 @@ RSpec.describe Groups::ImportExport::ImportService do
context 'when there are errors with the sub-relations' do
let(:import_file) { fixture_file_upload('spec/fixtures/group_export_invalid_subrelations.tar.gz') }
before do
group.add_owner(user)
end
it 'successfully imports the group' do
expect(subject).to be_truthy
end
......@@ -207,7 +215,7 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when importing a json export' do
let(:user) { create(:admin) }
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:service) { described_class.new(group: group, user: user) }
let(:import_file) { fixture_file_upload('spec/fixtures/legacy_group_export.tar.gz') }
......@@ -227,6 +235,10 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when user has correct permissions' do
before do
group.add_owner(user)
end
it 'imports group structure successfully' do
expect(subject).to be_truthy
end
......@@ -259,8 +271,6 @@ RSpec.describe Groups::ImportExport::ImportService do
end
context 'when user does not have correct permissions' do
let(:user) { create(:user) }
it 'logs the error and raises an exception' do
expect(import_logger).to receive(:error).with(
group_id: group.id,
......@@ -300,6 +310,10 @@ RSpec.describe Groups::ImportExport::ImportService do
context 'when there are errors with the sub-relations' do
let(:import_file) { fixture_file_upload('spec/fixtures/legacy_group_export_invalid_subrelations.tar.gz') }
before do
group.add_owner(user)
end
it 'successfully imports the group' do
expect(subject).to be_truthy
end
......
......@@ -26,19 +26,25 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
end
context 'an admin user' do
include_examples 'an idempotent worker' do
let(:job_args) { [user.id, group_id] }
context 'when admin mode is enabled', :enable_admin_mode do
include_examples 'an idempotent worker' do
let(:job_args) { [user.id, group_id] }
it 'deletes the blobs and returns ok', :aggregate_failures do
expect(group.dependency_proxy_blobs.size).to eq(1)
expect(group.dependency_proxy_manifests.size).to eq(1)
it 'deletes the blobs and returns ok', :aggregate_failures do
expect(group.dependency_proxy_blobs.size).to eq(1)
expect(group.dependency_proxy_manifests.size).to eq(1)
subject
subject
expect(group.dependency_proxy_blobs.size).to eq(0)
expect(group.dependency_proxy_manifests.size).to eq(0)
expect(group.dependency_proxy_blobs.size).to eq(0)
expect(group.dependency_proxy_manifests.size).to eq(0)
end
end
end
context 'when admin mode is disabled' do
it_behaves_like 'returns nil'
end
end
context 'a non-admin user' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment