Commit edf0b602 authored by Imre Farkas's avatar Imre Farkas

Merge branch 'chore/disable-admin-mode-in-services' into 'master'

[RUN AS-IF-FOSS] Migrate services specs to consider admin mode

See merge request gitlab-org/gitlab!45988
parents fe6dfe89 afacfadf
......@@ -602,7 +602,7 @@ class Project < ApplicationRecord
# Returns a collection of projects that is either public or visible to the
# logged in user.
def self.public_or_visible_to_user(user = nil, min_access_level = nil)
min_access_level = nil if user&.admin?
min_access_level = nil if user&.can_read_all_resources?
return public_to_user unless user
......@@ -628,7 +628,7 @@ class Project < ApplicationRecord
def self.with_feature_available_for_user(feature, user)
visible = [ProjectFeature::ENABLED, ProjectFeature::PUBLIC]
if user&.admin?
if user&.can_read_all_resources?
with_feature_enabled(feature)
elsif user
min_access_level = ProjectFeature.required_minimum_access_level(feature)
......
......@@ -72,6 +72,10 @@ module PolicyActor
def try_obtain_ldap_lease
nil
end
def can_read_all_resources?
false
end
end
PolicyActor.prepend_if_ee('EE::PolicyActor')
---
title: Migrate services specs to consider admin mode
merge_request: 45988
author: Diego Louzán
type: other
......@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CompareSecurityReportsService do
let_it_be(:project) { create(:project, :repository) }
let(:current_user) { build(:user, :admin) }
let(:current_user) { project.owner }
def collect_ids(collection)
collection.map { |t| t['identifiers'].first['external_id'] }
......
......@@ -6,7 +6,7 @@ RSpec.describe Ci::CreatePipelineService do
subject(:execute) { service.execute(:push) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
let_it_be(:user) { project.owner }
let(:service) do
described_class.new(project, user, { ref: 'refs/heads/master' })
......@@ -64,6 +64,10 @@ RSpec.describe Ci::CreatePipelineService do
end
shared_examples 'mixed artifacts definitions' do
before do
other_project.add_developer(user)
end
let(:other_project) { create(:project, :repository) }
let(:other_pipeline) do
......
......@@ -7,7 +7,7 @@ RSpec.describe Ci::CreatePipelineService do
let_it_be(:downstream_project) { create(:project, name: 'project', namespace: create(:namespace, name: 'some')) }
let(:project) { create(:project, :repository) }
let(:user) { create(:admin) }
let(:user) { project.owner }
let(:service) { described_class.new(project, user, { ref: 'refs/heads/master' }) }
let(:config) do
......@@ -25,6 +25,7 @@ RSpec.describe Ci::CreatePipelineService do
end
before do
downstream_project.add_developer(user)
stub_ci_pipeline_yaml_file(config)
end
......
......@@ -12,49 +12,57 @@ RSpec.describe Users::DestroyService do
subject(:operation) { service.execute(user) }
it 'returns result' do
allow(user).to receive(:destroy).and_return(user)
expect(operation).to eq(user)
context 'when admin mode is disabled' do
it 'raises access denied' do
expect { operation }.to raise_error(::Gitlab::Access::AccessDeniedError)
end
end
context 'when project is a mirror' do
let(:project) { create(:project, :mirror, mirror_user_id: user.id) }
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns result' do
allow(user).to receive(:destroy).and_return(user)
it 'disables mirror and does not assign a new mirror_user' do
expect(::Gitlab::ErrorTracking).to receive(:track_exception)
expect(operation).to eq(user)
end
allow_next_instance_of(::NotificationService) do |notification|
expect(notification).to receive(:mirror_was_disabled)
.with(project, user.name)
.and_call_original
end
context 'when project is a mirror' do
let(:project) { create(:project, :mirror, mirror_user_id: user.id) }
expect { operation }.to change { project.reload.mirror_user }.from(user).to(nil)
.and change { project.reload.mirror }.from(true).to(false)
end
end
it 'disables mirror and does not assign a new mirror_user' do
expect(::Gitlab::ErrorTracking).to receive(:track_exception)
allow_next_instance_of(::NotificationService) do |notification|
expect(notification).to receive(:mirror_was_disabled)
.with(project, user.name)
.and_call_original
end
describe 'audit events' do
include_examples 'audit event logging' do
let(:fail_condition!) do
expect_any_instance_of(User)
.to receive(:destroy).and_return(false)
expect { operation }.to change { project.reload.mirror_user }.from(user).to(nil)
.and change { project.reload.mirror }.from(true).to(false)
end
end
describe 'audit events' do
include_examples 'audit event logging' do
let(:fail_condition!) do
expect_any_instance_of(User)
.to receive(:destroy).and_return(false)
end
let(:attributes) do
{
author_id: current_user.id,
entity_id: @resource.id,
entity_type: 'User',
details: {
remove: 'user',
author_name: current_user.name,
target_id: @resource.id,
target_type: 'User',
target_details: @resource.full_path
let(:attributes) do
{
author_id: current_user.id,
entity_id: @resource.id,
entity_type: 'User',
details: {
remove: 'user',
author_name: current_user.name,
target_id: @resource.id,
target_type: 'User',
target_details: @resource.full_path
}
}
}
end
end
end
end
......
......@@ -10,13 +10,22 @@ RSpec.describe Users::UpdateService do
shared_examples_for 'a user can update the name' do
it 'updates the name' do
result = described_class.new(current_user, { user: user, name: 'New Name' }).execute!
result = update_user_as(current_user, user, { user: user, name: 'New Name' })
expect(result).to be_truthy
expect(user.name).to eq('New Name')
end
end
shared_examples_for 'a user cannot update the name' do
it 'does not update the name' do
result = update_user_as(current_user, user, { name: 'New Name' })
expect(result).to be_truthy
expect(user.name).not_to eq('New Name')
end
end
context 'when `disable_name_update_for_users` feature is available' do
before do
stub_licensed_features(disable_name_update_for_users: true)
......@@ -31,8 +40,10 @@ RSpec.describe Users::UpdateService do
let(:current_user) { user }
end
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
end
end
end
......@@ -42,16 +53,21 @@ RSpec.describe Users::UpdateService do
end
context 'as a regular user' do
it 'does not update the name' do
result = update_user(user, name: 'New Name')
it_behaves_like 'a user cannot update the name' do
let(:current_user) { user }
end
end
expect(result).to be_truthy
expect(user.name).not_to eq('New Name')
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
end
end
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
context 'when admin mode is disabled' do
it_behaves_like 'a user cannot update the name' do
let(:current_user) { admin }
end
end
end
end
......@@ -65,8 +81,16 @@ RSpec.describe Users::UpdateService do
let(:current_user) { user }
end
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'a user can update the name' do
let(:current_user) { admin }
end
end
context 'when admin mode is disabled' do
it_behaves_like 'a user cannot update the name' do
let(:current_user) { admin }
end
end
end
end
......@@ -84,7 +108,7 @@ RSpec.describe Users::UpdateService do
expected_message = "Changed username from #{previous_username} to #{new_username}"
expect do
update_user(user, username: new_username)
update_user_as_self(user, username: new_username)
end.to change { AuditEvent.count }.by(1)
expect(AuditEvent.last.present.action).to eq(expected_message)
......@@ -97,7 +121,7 @@ RSpec.describe Users::UpdateService do
allow(user).to receive(:group_managed_account?).and_return(true)
expect do
update_user(user, { email: 'foreign@email' })
update_user_as_self(user, { email: 'foreign@email' })
end.not_to change { user.reload.email }
end
......@@ -105,7 +129,7 @@ RSpec.describe Users::UpdateService do
allow(user).to receive(:group_managed_account?).and_return(true)
expect do
update_user(user, { commit_email: 'foreign@email' })
update_user_as_self(user, { commit_email: 'foreign@email' })
end.not_to change { user.reload.commit_email }
end
......@@ -113,7 +137,7 @@ RSpec.describe Users::UpdateService do
allow(user).to receive(:group_managed_account?).and_return(true)
expect do
update_user(user, { public_email: 'foreign@email' })
update_user_as_self(user, { public_email: 'foreign@email' })
end.not_to change { user.reload.public_email }
end
......@@ -121,7 +145,7 @@ RSpec.describe Users::UpdateService do
allow(user).to receive(:group_managed_account?).and_return(true)
expect do
update_user(user, { notification_email: 'foreign@email' })
update_user_as_self(user, { notification_email: 'foreign@email' })
end.not_to change { user.reload.notification_email }
end
......@@ -142,7 +166,7 @@ RSpec.describe Users::UpdateService do
end
it 'adds identity to user' do
result = update_user(user, params)
result = update_user_as_self(user, params)
expect(result).to be true
expect(user.identities.last.saml_provider_id).to eq(provider.id)
......@@ -152,8 +176,8 @@ RSpec.describe Users::UpdateService do
it 'adds two different identities to user' do
second_provider = create(:saml_provider)
result_one = update_user(user, { extern_uid: 'uid', provider: 'group_saml', saml_provider_id: provider.id })
result_two = update_user(user, { extern_uid: 'uid2', provider: 'group_saml', group_id_for_saml: second_provider.group.id } )
result_one = update_user_as_self(user, { extern_uid: 'uid', provider: 'group_saml', saml_provider_id: provider.id })
result_two = update_user_as_self(user, { extern_uid: 'uid2', provider: 'group_saml', group_id_for_saml: second_provider.group.id } )
expect(result_one).to be true
expect(result_two).to be true
......@@ -165,8 +189,12 @@ RSpec.describe Users::UpdateService do
end
end
def update_user(user, opts)
described_class.new(user, opts.merge(user: user)).execute!
def update_user_as(current_user, user, opts)
described_class.new(current_user, opts.merge(user: user)).execute!
end
def update_user_as_self(user, opts)
update_user_as(user, user, opts)
end
end
end
......@@ -10,10 +10,18 @@ RSpec.describe Licenses::DestroyService do
described_class.new(license, user).execute
end
it 'destroys a license' do
destroy_with(user)
context 'when admin mode is enabled', :enable_admin_mode do
it 'destroys a license' do
destroy_with(user)
expect(License.where(id: license.id)).not_to exist
expect(License.where(id: license.id)).not_to exist
end
end
context 'when admin mode is disabled' do
it 'raises not allowed error' do
expect { destroy_with(user) }.to raise_error(::Gitlab::Access::AccessDeniedError)
end
end
it 'raises an error if license is nil' do
......
......@@ -29,12 +29,13 @@ RSpec.describe Search::GlobalService do
let!(:merge_request) { create :merge_request, target_project: project, source_project: project }
let!(:note) { create :note, project: project, noteable: merge_request }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_reporter_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
ensure_elasticsearch_index!
......@@ -53,12 +54,13 @@ RSpec.describe Search::GlobalService do
let!(:project) { create(:project, project_level, :repository, namespace: group ) }
let!(:note) { create :note_on_commit, project: project }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access_and_non_private_project_only
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
ElasticCommitIndexerWorker.new.perform(project.id)
ensure_elasticsearch_index!
......@@ -85,12 +87,13 @@ RSpec.describe Search::GlobalService do
let!(:issue) { create :issue, project: project }
let!(:note) { create :note, project: project, noteable: issue }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
ensure_elasticsearch_index!
......@@ -143,12 +146,13 @@ RSpec.describe Search::GlobalService do
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
......@@ -164,12 +168,13 @@ RSpec.describe Search::GlobalService do
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
......@@ -261,8 +266,16 @@ RSpec.describe Search::GlobalService do
context 'when the user is an admin' do
let(:user) { admin }
it 'returns :any' do
expect(elastic_projects).to eq(:any)
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns :any' do
expect(elastic_projects).to eq(:any)
end
end
context 'when admin mode is disabled' do
it 'returns empty array' do
expect(elastic_projects).to eq([])
end
end
end
......
......@@ -81,12 +81,13 @@ RSpec.describe Search::GroupService, :elastic do
let!(:note) { create :note, project: project, noteable: merge_request }
let!(:note2) { create :note, project: project2, noteable: merge_request2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_reporter_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
......@@ -107,12 +108,13 @@ RSpec.describe Search::GroupService, :elastic do
let!(:project) { create(:project, project_level, :repository, namespace: group ) }
let!(:note) { create :note_on_commit, project: project }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access_and_non_private_project_only
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
ElasticCommitIndexerWorker.new.perform(project.id)
......@@ -141,12 +143,13 @@ RSpec.describe Search::GroupService, :elastic do
let!(:note) { create :note, project: project, noteable: issue }
let!(:note2) { create :note, project: project2, noteable: issue2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
......@@ -166,12 +169,13 @@ RSpec.describe Search::GroupService, :elastic do
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
......@@ -187,12 +191,13 @@ RSpec.describe Search::GroupService, :elastic do
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
......
......@@ -48,12 +48,13 @@ RSpec.describe Search::ProjectService do
let!(:note) { create :note, project: project, noteable: merge_request }
let!(:note2) { create :note, project: project2, noteable: merge_request2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_reporter_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
......@@ -76,12 +77,13 @@ RSpec.describe Search::ProjectService do
let!(:note) { create :note_on_commit, project: project }
let!(:note2) { create :note_on_commit, project: project2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access_and_non_private_project_only
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
ElasticCommitIndexerWorker.new.perform(project.id)
......@@ -109,12 +111,13 @@ RSpec.describe Search::ProjectService do
let!(:note) { create :note, project: project, noteable: issue }
let!(:note2) { create :note, project: project2, noteable: issue2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
......@@ -134,12 +137,13 @@ RSpec.describe Search::ProjectService do
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
......@@ -155,12 +159,13 @@ RSpec.describe Search::ProjectService do
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
......
......@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Search::SnippetService do
include SearchResultHelpers
include ProjectHelpers
include AdminModeHelper
using RSpec::Parameterized::TableSyntax
it_behaves_like 'EE search service shared examples', ::Gitlab::SnippetSearchResults, ::Gitlab::Elastic::SnippetSearchResults do
......@@ -32,11 +33,20 @@ RSpec.describe Search::SnippetService do
context 'project snippet' do
let(:pendings) do
# TODO: Ignore some spec cases, non-members regular users or non-member admins without admin mode should see snippets if:
# - feature access level is enabled, and
# - project access level is public or internal, and
# - snippet access level is equal or more open than the project access level
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45988#note_436009204
[
{ snippet_level: :public, project_level: :public, feature_access_level: :enabled, membership: :non_member, expected_count: 1 },
{ snippet_level: :public, project_level: :internal, feature_access_level: :enabled, membership: :non_member, expected_count: 1 },
{ snippet_level: :internal, project_level: :public, feature_access_level: :enabled, membership: :non_member, expected_count: 1 },
{ snippet_level: :internal, project_level: :internal, feature_access_level: :enabled, membership: :non_member, expected_count: 1 }
{ snippet_level: :public, project_level: :public, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1 },
{ snippet_level: :public, project_level: :internal, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1 },
{ snippet_level: :internal, project_level: :public, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1 },
{ snippet_level: :internal, project_level: :internal, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1 },
{ snippet_level: :public, project_level: :public, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1 },
{ snippet_level: :public, project_level: :internal, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1 },
{ snippet_level: :internal, project_level: :public, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1 },
{ snippet_level: :internal, project_level: :internal, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1 }
]
end
......@@ -47,6 +57,7 @@ RSpec.describe Search::SnippetService do
project_level: project_level,
feature_access_level: feature_access_level,
membership: membership,
admin_mode: admin_mode,
expected_count: expected_count
}
)
......@@ -62,7 +73,7 @@ RSpec.describe Search::SnippetService do
let_it_be(:snippet) { create(:project_snippet, :public, project: project, author: snippet_author, title: 'foobar') }
where(:snippet_level, :project_level, :feature_access_level, :membership, :expected_count) do
where(:snippet_level, :project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_project_snippet_access
end
......@@ -75,6 +86,7 @@ RSpec.describe Search::SnippetService do
expected_objects = expected_count == 0 ? [] : [snippet]
search_user = user_from_membership(membership)
enable_admin_mode!(search_user) if admin_mode
expect_search_results(search_user, 'snippet_titles', expected_objects: expected_objects, pending: pending?) do |user|
described_class.new(user, search: snippet.title).execute
......@@ -98,7 +110,7 @@ RSpec.describe Search::SnippetService do
let(:snippet) { snippets[snippet_level] }
where(:snippet_level, :membership, :expected_count) do
where(:snippet_level, :membership, :admin_mode, :expected_count) do
permission_table_for_personal_snippet_access
end
......@@ -111,6 +123,7 @@ RSpec.describe Search::SnippetService do
expected_objects = expected_count == 0 ? [] : [snippet]
search_user = user_from_membership(membership)
enable_admin_mode!(search_user) if admin_mode
expect_search_results(search_user, 'snippet_titles', expected_objects: expected_objects) do |user|
described_class.new(user, search: snippet.title).execute
......
......@@ -51,7 +51,12 @@ RSpec.describe Vulnerabilities::ConfirmService do
end
describe 'permissions' do
it { expect { confirm_vulnerability }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { confirm_vulnerability }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { confirm_vulnerability }.to be_denied_for(:admin) }
end
it { expect { confirm_vulnerability }.to be_allowed_for(:owner).of(project) }
it { expect { confirm_vulnerability }.to be_allowed_for(:maintainer).of(project) }
it { expect { confirm_vulnerability }.to be_allowed_for(:developer).of(project) }
......
......@@ -103,7 +103,12 @@ RSpec.describe Vulnerabilities::DismissService do
end
describe 'permissions' do
it { expect { dismiss_vulnerability }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { dismiss_vulnerability }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { dismiss_vulnerability }.to be_denied_for(:admin) }
end
it { expect { dismiss_vulnerability }.to be_allowed_for(:owner).of(project) }
it { expect { dismiss_vulnerability }.to be_allowed_for(:maintainer).of(project) }
it { expect { dismiss_vulnerability }.to be_allowed_for(:developer).of(project) }
......
......@@ -51,7 +51,12 @@ RSpec.describe Vulnerabilities::ResolveService do
end
describe 'permissions' do
it { expect { resolve_vulnerability }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { resolve_vulnerability }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { resolve_vulnerability }.to be_denied_for(:admin) }
end
it { expect { resolve_vulnerability }.to be_allowed_for(:owner).of(project) }
it { expect { resolve_vulnerability }.to be_allowed_for(:maintainer).of(project) }
it { expect { resolve_vulnerability }.to be_allowed_for(:developer).of(project) }
......
......@@ -71,7 +71,12 @@ RSpec.describe Vulnerabilities::RevertToDetectedService do
end
describe 'permissions' do
it { expect { revert_vulnerability_to_detected }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { revert_vulnerability_to_detected }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { revert_vulnerability_to_detected }.to be_denied_for(:admin) }
end
it { expect { revert_vulnerability_to_detected }.to be_allowed_for(:owner).of(project) }
it { expect { revert_vulnerability_to_detected }.to be_allowed_for(:maintainer).of(project) }
it { expect { revert_vulnerability_to_detected }.to be_allowed_for(:developer).of(project) }
......
......@@ -117,7 +117,12 @@ RSpec.describe VulnerabilityIssueLinks::CreateService do
end
describe 'permissions' do
it { expect { create_issue_link }.to be_allowed_for(:admin) }
context 'when admin mode enabled', :enable_admin_mode do
it { expect { create_issue_link }.to be_allowed_for(:admin) }
end
context 'when admin mode disabled' do
it { expect { create_issue_link }.to be_denied_for(:admin) }
end
it { expect { create_issue_link }.to be_allowed_for(:owner).of(project) }
it { expect { create_issue_link }.to be_allowed_for(:maintainer).of(project) }
it { expect { create_issue_link }.to be_allowed_for(:developer).of(project) }
......
......@@ -46,7 +46,12 @@ RSpec.describe VulnerabilityIssueLinks::DeleteService do
end
describe 'permissions' do
it { expect { delete_issue_link }.to be_allowed_for(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect { delete_issue_link }.to be_allowed_for(:admin) }
end
context 'when admin mode is disabled' do
it { expect { delete_issue_link }.to be_denied_for(:admin) }
end
it { expect { delete_issue_link }.to be_allowed_for(:owner).of(project) }
it { expect { delete_issue_link }.to be_allowed_for(:maintainer).of(project) }
it { expect { delete_issue_link }.to be_allowed_for(:developer).of(project) }
......
......@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::GitAccessSnippet do
include ProjectHelpers
include TermsHelper
include AdminModeHelper
include_context 'ProjectPolicyTable context'
using RSpec::Parameterized::TableSyntax
......@@ -207,12 +208,13 @@ RSpec.describe Gitlab::GitAccessSnippet do
let(:snippet) { create(:personal_snippet, snippet_level, :repository) }
let(:user) { membership == :author ? snippet.author : create_user_from_membership(nil, membership) }
where(:snippet_level, :membership, :_expected_count) do
where(:snippet_level, :membership, :admin_mode, :_expected_count) do
permission_table_for_personal_snippet_access
end
with_them do
it "respects accessibility" do
enable_admin_mode!(user) if admin_mode
error_class = described_class::ForbiddenError
if Ability.allowed?(user, :update_snippet, snippet)
......
......@@ -3996,8 +3996,16 @@ RSpec.describe Project, factory_default: :keep do
context 'when feature is private' do
let(:project) { create(:project, :public, :merge_requests_private) }
it 'returns projects with the project feature private' do
is_expected.to include(project)
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns projects with the project feature private' do
is_expected.to include(project)
end
end
context 'when admin mode is disabled' do
it 'does not return projects with the project feature private' do
is_expected.not_to include(project)
end
end
end
end
......@@ -4020,7 +4028,7 @@ RSpec.describe Project, factory_default: :keep do
end
end
describe '.filter_by_feature_visibility', :enable_admin_mode do
describe '.filter_by_feature_visibility' do
include_context 'ProjectPolicyTable context'
include ProjectHelpers
using RSpec::Parameterized::TableSyntax
......@@ -4032,12 +4040,13 @@ RSpec.describe Project, factory_default: :keep do
context 'reporter level access' do
let(:feature) { MergeRequest }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_reporter_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
expected_objects = expected_count == 1 ? [project] : []
......@@ -4052,12 +4061,13 @@ RSpec.describe Project, factory_default: :keep do
context 'issues' do
let(:feature) { Issue }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
expected_objects = expected_count == 1 ? [project] : []
......@@ -4072,12 +4082,13 @@ RSpec.describe Project, factory_default: :keep do
context 'wiki' do
let(:feature) { :wiki }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
expected_objects = expected_count == 1 ? [project] : []
......@@ -4092,12 +4103,13 @@ RSpec.describe Project, factory_default: :keep do
context 'code' do
let(:feature) { :repository }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access_and_non_private_project_only
end
with_them do
it "respects visibility" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
expected_objects = expected_count == 1 ? [project] : []
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe BlobPolicy, :enable_admin_mode do
RSpec.describe BlobPolicy do
include_context 'ProjectPolicyTable context'
include ProjectHelpers
using RSpec::Parameterized::TableSyntax
......@@ -13,12 +13,13 @@ RSpec.describe BlobPolicy, :enable_admin_mode do
subject(:policy) { described_class.new(user, blob) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access_and_non_private_project_only
end
with_them do
it "grants permission" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
if expected_count == 1
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe WikiPagePolicy, :enable_admin_mode do
RSpec.describe WikiPagePolicy do
include_context 'ProjectPolicyTable context'
include ProjectHelpers
using RSpec::Parameterized::TableSyntax
......@@ -13,12 +13,13 @@ RSpec.describe WikiPagePolicy, :enable_admin_mode do
subject(:policy) { described_class.new(user, wiki_page) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "grants permission" do
enable_admin_mode!(user) if admin_mode
update_feature_access_level(project, feature_access_level)
if expected_count == 1
......
......@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Auth::ContainerRegistryAuthenticationService do
include AdminModeHelper
let(:current_project) { nil }
let(:current_user) { nil }
let(:current_params) { {} }
......@@ -696,6 +698,10 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
context 'user has access to all projects' do
let_it_be(:current_user) { create(:user, :admin) }
before do
enable_admin_mode!(current_user)
end
it_behaves_like 'a browsable' do
let(:access) do
[
......
......@@ -4,13 +4,13 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'cache' do
let(:user) { create(:admin) }
let(:project) { create(:project, :custom_repo, files: files) }
let(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
let(:pipeline) { service.execute(source) }
let(:job) { pipeline.builds.find_by(name: 'job') }
let(:project) { create(:project, :custom_repo, files: files) }
before do
stub_ci_pipeline_yaml_file(config)
......
......@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe 'creation errors and warnings' do
let_it_be(:user) { create(:admin) }
let_it_be(:project) { create(:project, :repository, creator: user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
......
......@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
let_it_be(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
let_it_be(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
......
......@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
context 'needs' do
let_it_be(:user) { create(:admin) }
let_it_be(:project) { create(:project, :repository, creator: user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
......@@ -14,6 +14,7 @@ RSpec.describe Ci::CreatePipelineService do
before do
stub_ci_pipeline_yaml_file(config)
project.add_developer(user)
end
context 'with a valid config' do
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
let_it_be(:user) { project.owner }
let(:service) { described_class.new(project, user, { ref: 'refs/heads/master' }) }
let(:content) do
<<~EOY
......
......@@ -3,8 +3,8 @@ require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe '.pre/.post stages' do
let_it_be(:user) { create(:admin) }
let_it_be(:project) { create(:project, :repository, creator: user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
......
......@@ -2,10 +2,10 @@
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let(:user) { create(:admin) }
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:project) { create(:project, :repository) }
let(:service) { described_class.new(project, user, { ref: ref }) }
let(:pipeline) { service.execute(source) }
let(:build_names) { pipeline.builds.pluck(:name) }
......
......@@ -6,7 +6,7 @@ RSpec.describe Ci::CreatePipelineService do
include ProjectForksHelper
let_it_be(:project, reload: true) { create(:project, :repository) }
let(:user) { create(:admin) }
let_it_be(:user, reload: true) { project.owner }
let(:ref_name) { 'refs/heads/master' }
before do
......@@ -155,6 +155,11 @@ RSpec.describe Ci::CreatePipelineService do
context 'when merge request target project is different from source project' do
let!(:project) { fork_project(target_project, nil, repository: true) }
let!(:target_project) { create(:project, :repository) }
let!(:user) { create(:user) }
before do
project.add_developer(user)
end
it 'updates head pipeline for merge request', :sidekiq_might_not_need_inline do
merge_request = create(:merge_request, source_branch: 'feature',
......@@ -1442,6 +1447,11 @@ RSpec.describe Ci::CreatePipelineService do
let(:ref_name) { 'refs/heads/feature' }
let!(:project) { fork_project(target_project, nil, repository: true) }
let!(:target_project) { create(:project, :repository) }
let!(:user) { create(:user) }
before do
project.add_developer(user)
end
it 'creates a legacy detached merge request pipeline in the forked project', :sidekiq_might_not_need_inline do
expect(pipeline).to be_persisted
......
......@@ -321,21 +321,40 @@ RSpec.describe Issues::MoveService do
before do
authorized_project.add_developer(user)
authorized_project.add_developer(admin)
authorized_project2.add_developer(user)
authorized_project2.add_developer(admin)
end
context 'multiple related issues' do
it 'moves all related issues and retains permissions' do
new_issue = move_service.execute(old_issue, new_project)
context 'when admin mode is enabled', :enable_admin_mode do
it 'moves all related issues and retains permissions' do
new_issue = move_service.execute(old_issue, new_project)
expect(new_issue.related_issues(admin))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d, unauthorized_issue])
expect(new_issue.related_issues(user))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d])
expect(authorized_issue_d.related_issues(user))
.to match_array([new_issue])
end
end
expect(new_issue.related_issues(admin))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d, unauthorized_issue])
context 'when admin mode is disabled' do
it 'moves all related issues and retains permissions' do
new_issue = move_service.execute(old_issue, new_project)
expect(new_issue.related_issues(user))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d])
expect(new_issue.related_issues(admin))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d])
expect(authorized_issue_d.related_issues(user))
.to match_array([new_issue])
expect(new_issue.related_issues(user))
.to match_array([authorized_issue_b, authorized_issue_c, authorized_issue_d])
expect(authorized_issue_d.related_issues(user))
.to match_array([new_issue])
end
end
end
end
......
......@@ -74,8 +74,16 @@ RSpec.describe Issues::RelatedBranchesService do
context 'the user has access to otherwise unreadable pipelines' do
let(:user) { create(:admin) }
it 'returns info a developer could not see' do
expect(branch_info.pluck(:pipeline_status)).to include(an_instance_of(Gitlab::Ci::Status::Running))
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns info a developer could not see' do
expect(branch_info.pluck(:pipeline_status)).to include(an_instance_of(Gitlab::Ci::Status::Running))
end
end
context 'when admin mode is disabled' do
it 'does not return info a developer could not see' do
expect(branch_info.pluck(:pipeline_status)).not_to include(an_instance_of(Gitlab::Ci::Status::Running))
end
end
end
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Labels::TransferService do
describe '#execute' do
let_it_be(:user) { create(:admin) }
let_it_be(:user) { create(:user) }
let_it_be(:old_group_ancestor) { create(:group) }
let_it_be(:old_group) { create(:group, parent: old_group_ancestor) }
......@@ -15,6 +15,11 @@ RSpec.describe Labels::TransferService do
subject(:service) { described_class.new(user, old_group, project) }
before do
old_group_ancestor.add_developer(user)
new_group.add_developer(user)
end
it 'recreates missing group labels at project level and assigns them to the issuables' do
old_group_label_1 = create(:group_label, group: old_group)
old_group_label_2 = create(:group_label, group: old_group)
......
......@@ -12,10 +12,20 @@ RSpec.describe MergeRequests::AddContextService do
subject(:service) { described_class.new(project, admin, merge_request: merge_request, commits: commits) }
describe "#execute" do
it "adds context commit" do
service.execute
context "when admin mode is enabled", :enable_admin_mode do
it "adds context commit" do
service.execute
expect(merge_request.merge_request_context_commit_diff_files.length).to eq(2)
expect(merge_request.merge_request_context_commit_diff_files.length).to eq(2)
end
end
context "when admin mode is disabled" do
it "doesn't add context commit" do
subject.execute
expect(merge_request.merge_request_context_commit_diff_files.length).to eq(0)
end
end
context "when user doesn't have permission to update merge request" do
......
......@@ -3099,12 +3099,26 @@ RSpec.describe NotificationService, :mailer do
subject.new_issue(issue, member)
end
it 'still delivers email to admins' do
member.update!(admin: true)
context 'with admin user' do
before do
member.update!(admin: true)
end
expect(Notify).to receive(:new_issue_email).at_least(:once).with(member.id, issue.id, nil).and_call_original
context 'when admin mode is enabled', :enable_admin_mode do
it 'still delivers email to admins' do
expect(Notify).to receive(:new_issue_email).at_least(:once).with(member.id, issue.id, nil).and_call_original
subject.new_issue(issue, member)
subject.new_issue(issue, member)
end
end
context 'when admin mode is disabled' do
it 'does not send an email' do
expect(Notify).not_to receive(:new_issue_email)
subject.new_issue(issue, member)
end
end
end
end
end
......
......@@ -38,7 +38,13 @@ RSpec.describe PersonalAccessTokens::CreateService do
context 'when current_user is an administrator' do
let(:current_user) { create(:admin) }
it_behaves_like 'a successfully created token'
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'a successfully created token'
end
context 'when admin mode is disabled' do
it_behaves_like 'an unsuccessfully created token'
end
end
context 'when current_user is not an administrator' do
......
......@@ -24,10 +24,19 @@ RSpec.describe PersonalAccessTokens::RevokeService do
let(:service) { described_class.new(current_user, token: token) }
context 'when current_user is an administrator' do
let_it_be(:current_user) { create(:admin) }
let_it_be(:token) { create(:personal_access_token) }
context 'when admin mode is enabled', :enable_admin_mode do
let_it_be(:current_user) { create(:admin) }
let_it_be(:token) { create(:personal_access_token) }
it_behaves_like 'a successfully revoked token'
end
it_behaves_like 'a successfully revoked token'
context 'when admin mode is disabled' do
let_it_be(:current_user) { create(:admin) }
let_it_be(:token) { create(:personal_access_token) }
it_behaves_like 'an unsuccessfully revoked token'
end
end
context 'when current_user is not an administrator' do
......
......@@ -79,14 +79,28 @@ RSpec.describe Projects::AutocompleteService do
expect(issues.count).to eq 3
end
it 'lists all project issues for admin' do
autocomplete = described_class.new(project, admin)
issues = autocomplete.issues.map(&:iid)
context 'when admin mode is enabled', :enable_admin_mode do
it 'lists all project issues for admin', :enable_admin_mode do
autocomplete = described_class.new(project, admin)
issues = autocomplete.issues.map(&:iid)
expect(issues).to include issue.iid
expect(issues).to include security_issue_1.iid
expect(issues).to include security_issue_2.iid
expect(issues.count).to eq 3
end
end
expect(issues).to include issue.iid
expect(issues).to include security_issue_1.iid
expect(issues).to include security_issue_2.iid
expect(issues.count).to eq 3
context 'when admin mode is disabled' do
it 'does not list project confidential issues for admin' do
autocomplete = described_class.new(project, admin)
issues = autocomplete.issues.map(&:iid)
expect(issues).to include issue.iid
expect(issues).not_to include security_issue_1.iid
expect(issues).not_to include security_issue_2.iid
expect(issues.count).to eq 1
end
end
end
end
......
......@@ -72,14 +72,25 @@ RSpec.describe Projects::CreateService, '#execute' do
end
context "admin creates project with other user's namespace_id" do
it 'sets the correct permissions' do
admin = create(:admin)
project = create_project(admin, opts)
context 'when admin mode is enabled', :enable_admin_mode do
it 'sets the correct permissions' do
admin = create(:admin)
project = create_project(admin, opts)
expect(project).to be_persisted
expect(project.owner).to eq(user)
expect(project.team.maintainers).to contain_exactly(user)
expect(project.namespace).to eq(user.namespace)
expect(project).to be_persisted
expect(project.owner).to eq(user)
expect(project.team.maintainers).to contain_exactly(user)
expect(project.namespace).to eq(user.namespace)
end
end
context 'when admin mode is disabled' do
it 'is not allowed' do
admin = create(:admin)
project = create_project(admin, opts)
expect(project).not_to be_persisted
end
end
end
......@@ -336,7 +347,15 @@ RSpec.describe Projects::CreateService, '#execute' do
)
end
it 'allows a restricted visibility level for admins' do
it 'does not allow a restricted visibility level for admins when admin mode is disabled' do
admin = create(:admin)
project = create_project(admin, opts)
expect(project.errors.any?).to be(true)
expect(project.saved?).to be_falsey
end
it 'allows a restricted visibility level for admins when admin mode is enabled', :enable_admin_mode do
admin = create(:admin)
project = create_project(admin, opts)
......
......@@ -127,11 +127,22 @@ RSpec.describe Projects::UpdateService do
end
context 'when updated by an admin' do
it 'updates the project to public' do
result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
context 'when admin mode is enabled', :enable_admin_mode do
it 'updates the project to public' do
result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
expect(result).to eq({ status: :success })
expect(project).to be_public
expect(result).to eq({ status: :success })
expect(project).to be_public
end
end
context 'when admin mode is disabled' do
it 'does not update the project to public' do
result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
expect(result).to eq({ status: :error, message: 'New visibility level not allowed!' })
expect(project).to be_private
end
end
end
end
......@@ -144,7 +155,7 @@ RSpec.describe Projects::UpdateService do
project.update!(namespace: group, visibility_level: group.visibility_level)
end
it 'does not update project visibility level' do
it 'does not update project visibility level even if admin', :enable_admin_mode do
result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
expect(result).to eq({ status: :error, message: 'Visibility level public is not allowed in a internal group.' })
......@@ -181,6 +192,7 @@ RSpec.describe Projects::UpdateService do
describe 'when updating project that has forks' do
let(:project) { create(:project, :internal) }
let(:user) { project.owner }
let(:forked_project) { fork_project(project) }
context 'and unlink forks feature flag is off' do
......@@ -194,7 +206,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
expect(update_project(project, admin, opts)).to eq({ status: :success })
expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_private
expect(forked_project.reload).to be_private
......@@ -206,7 +218,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
expect(update_project(project, admin, opts)).to eq({ status: :success })
expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_public
expect(forked_project.reload).to be_internal
......@@ -220,7 +232,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
expect(update_project(project, admin, opts)).to eq({ status: :success })
expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_private
expect(forked_project.reload).to be_internal
......@@ -576,15 +588,21 @@ RSpec.describe Projects::UpdateService do
context 'authenticated as admin' do
let(:user) { create(:admin) }
it 'schedules the transfer of the repository to the new storage and locks the project' do
update_project(project, admin, opts)
context 'when admin mode is enabled', :enable_admin_mode do
it 'schedules the transfer of the repository to the new storage and locks the project' do
update_project(project, admin, opts)
expect(project).to be_repository_read_only
expect(project.repository_storage_moves.last).to have_attributes(
state: ::ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value,
source_storage_name: 'default',
destination_storage_name: 'test_second_storage'
)
expect(project).to be_repository_read_only
expect(project.repository_storage_moves.last).to have_attributes(
state: ::ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value,
source_storage_name: 'default',
destination_storage_name: 'test_second_storage'
)
end
end
context 'when admin mode is disabled' do
it_behaves_like 'the transfer was not scheduled'
end
context 'the repository is read-only' do
......
......@@ -46,8 +46,18 @@ RSpec.describe ResourceAccessTokens::CreateService do
end
context 'when created by an admin' do
it_behaves_like 'creates a user that has their email confirmed' do
let(:user) { create(:admin) }
let(:user) { create(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'creates a user that has their email confirmed'
end
context 'when admin mode is disabled' do
it 'returns error' do
response = subject
expect(response.error?).to be true
end
end
end
......
......@@ -49,12 +49,24 @@ RSpec.describe Search::SnippetService do
expect(results.objects('snippet_titles')).to match_array [public_snippet, internal_snippet, private_snippet, project_public_snippet, project_internal_snippet]
end
it 'returns all snippets when user is admin' do
admin = create(:admin)
search = described_class.new(admin, search: 'bar')
results = search.execute
context 'when admin mode is enabled', :enable_admin_mode do
it 'returns all snippets when user is admin' do
admin = create(:admin)
search = described_class.new(admin, search: 'bar')
results = search.execute
expect(results.objects('snippet_titles')).to match_array [public_snippet, internal_snippet, private_snippet, project_public_snippet, project_internal_snippet, project_private_snippet]
end
end
context 'when admin mode is disabled' do
it 'returns only public & internal snippets when user is admin' do
admin = create(:admin)
search = described_class.new(admin, search: 'bar')
results = search.execute
expect(results.objects('snippet_titles')).to match_array [public_snippet, internal_snippet, private_snippet, project_public_snippet, project_internal_snippet, project_private_snippet]
expect(results.objects('snippet_titles')).to match_array [public_snippet, internal_snippet, project_public_snippet, project_internal_snippet]
end
end
end
end
......
......@@ -150,7 +150,7 @@ RSpec.describe TodoService do
service.new_issue(issue, author)
should_create_todo(user: member, target: issue, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
should_create_todo(user: guest, target: issue, action: Todo::MENTIONED)
end
......@@ -160,7 +160,7 @@ RSpec.describe TodoService do
should_create_todo(user: assignee, target: confidential_issue, author: john_doe, action: Todo::ASSIGNED)
should_create_todo(user: author, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
end
......@@ -171,7 +171,7 @@ RSpec.describe TodoService do
should_create_todo(user: assignee, target: addressed_confident_issue, author: john_doe, action: Todo::ASSIGNED)
should_create_todo(user: author, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: member, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: admin, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_not_create_todo(user: admin, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_not_create_todo(user: guest, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: john_doe, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
end
......@@ -228,7 +228,7 @@ RSpec.describe TodoService do
should_create_todo(user: member, target: issue, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: guest, target: issue, action: Todo::MENTIONED)
should_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: skipped, target: issue)
end
......@@ -273,7 +273,7 @@ RSpec.describe TodoService do
should_create_todo(user: author, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: assignee, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
end
......@@ -284,7 +284,7 @@ RSpec.describe TodoService do
should_create_todo(user: author, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: assignee, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: member, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: admin, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_not_create_todo(user: admin, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_not_create_todo(user: guest, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: john_doe, target: addressed_confident_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED)
end
......@@ -432,7 +432,7 @@ RSpec.describe TodoService do
service.new_note(note, john_doe)
should_create_todo(user: member, target: issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: note)
should_create_todo(user: admin, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_not_create_todo(user: admin, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_create_todo(user: guest, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
end
......@@ -452,7 +452,7 @@ RSpec.describe TodoService do
should_create_todo(user: author, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_create_todo(user: assignee, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_not_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
end
......@@ -463,7 +463,7 @@ RSpec.describe TodoService do
should_create_todo(user: author, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_create_todo(user: assignee, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_not_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::DIRECTLY_ADDRESSED, note: addressed_note_on_confidential_issue)
end
......@@ -699,7 +699,7 @@ RSpec.describe TodoService do
service.new_merge_request(mr_assigned, author)
should_create_todo(user: member, target: mr_assigned, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
end
it 'creates a directly addressed todo for each valid addressed user' do
......@@ -731,7 +731,7 @@ RSpec.describe TodoService do
service.update_merge_request(mr_assigned, author, skip_users)
should_create_todo(user: member, target: mr_assigned, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: skipped, target: mr_assigned)
end
......@@ -997,7 +997,7 @@ RSpec.describe TodoService do
should_create_todo(user: member, target: noteable, action: Todo::DIRECTLY_ADDRESSED)
should_create_todo(user: guest, target: noteable, action: Todo::MENTIONED)
should_create_todo(user: admin, target: noteable, action: Todo::MENTIONED)
should_not_create_todo(user: admin, target: noteable, action: Todo::MENTIONED)
should_not_create_todo(user: skipped, target: noteable)
end
......
......@@ -85,7 +85,7 @@ RSpec.describe TwoFactor::DestroyService do
it_behaves_like 'disables two-factor authentication'
end
context 'admin disables the two-factor authentication of another user' do
context 'admin disables the two-factor authentication of another user', :enable_admin_mode do
let(:current_user) { create(:admin) }
let(:user) { create(:user, :two_factor) }
......
......@@ -19,85 +19,96 @@ RSpec.describe Users::ApproveService do
end
end
context 'when user is not in pending approval state' do
let(:user) { create(:user, state: 'active') }
context 'when the executor user is an admin not in admin mode' do
it 'returns error result' do
expect(subject[:status]).to eq(:error)
expect(subject[:message])
.to match(/The user you are trying to approve is not pending an approval/)
expect(subject[:message]).to match(/You are not allowed to approve a user/)
end
end
context 'when user cannot be activated' do
let(:user) do
build(:user, state: 'blocked_pending_approval', email: 'invalid email')
end
context 'when the executor user is an admin in admin mode', :enable_admin_mode do
context 'when user is not in pending approval state' do
let(:user) { create(:user, state: 'active') }
it 'returns error result' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to match(/Email is invalid/)
it 'returns error result' do
expect(subject[:status]).to eq(:error)
expect(subject[:message])
.to match(/The user you are trying to approve is not pending an approval/)
end
end
it 'does not change the state of the user' do
expect { subject }.not_to change { user.state }
context 'when user cannot be activated' do
let(:user) do
build(:user, state: 'blocked_pending_approval', email: 'invalid email')
end
it 'returns error result' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to match(/Email is invalid/)
end
it 'does not change the state of the user' do
expect { subject }.not_to change { user.state }
end
end
end
end
context 'success' do
it 'activates the user' do
expect(subject[:status]).to eq(:success)
expect(user.reload).to be_active
end
context 'when the executor user is an admin in admin mode', :enable_admin_mode do
it 'activates the user' do
expect(subject[:status]).to eq(:success)
expect(user.reload).to be_active
end
context 'email confirmation status' do
context 'user is unconfirmed' do
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
context 'email confirmation status' do
context 'user is unconfirmed' do
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
it 'sends confirmation instructions' do
expect { subject }
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
it 'sends confirmation instructions' do
expect { subject }
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
end
end
context 'user is confirmed' do
it 'does not send a confirmation email' do
expect { subject }
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
context 'user is confirmed' do
it 'does not send a confirmation email' do
expect { subject }
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
end
end
end
context 'pending invitiations' do
let!(:project_member_invite) { create(:project_member, :invited, invite_email: user.email) }
let!(:group_member_invite) { create(:group_member, :invited, invite_email: user.email) }
context 'pending invitations' do
let!(:project_member_invite) { create(:project_member, :invited, invite_email: user.email) }
let!(:group_member_invite) { create(:group_member, :invited, invite_email: user.email) }
context 'user is unconfirmed' do
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
context 'user is unconfirmed' do
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
it 'does not accept pending invites of the user' do
expect(subject[:status]).to eq(:success)
it 'does not accept pending invites of the user' do
expect(subject[:status]).to eq(:success)
group_member_invite.reload
project_member_invite.reload
group_member_invite.reload
project_member_invite.reload
expect(group_member_invite).to be_invite
expect(project_member_invite).to be_invite
expect(group_member_invite).to be_invite
expect(project_member_invite).to be_invite
end
end
end
context 'user is confirmed' do
it 'accepts pending invites of the user' do
expect(subject[:status]).to eq(:success)
context 'user is confirmed' do
it 'accepts pending invites of the user' do
expect(subject[:status]).to eq(:success)
group_member_invite.reload
project_member_invite.reload
group_member_invite.reload
project_member_invite.reload
expect(group_member_invite).not_to be_invite
expect(project_member_invite).not_to be_invite
expect(group_member_invite.user).to eq(user)
expect(project_member_invite.user).to eq(user)
expect(group_member_invite).not_to be_invite
expect(project_member_invite).not_to be_invite
expect(group_member_invite.user).to eq(user)
expect(project_member_invite.user).to eq(user)
end
end
end
end
......
......@@ -3,14 +3,14 @@
require 'spec_helper'
RSpec.describe Users::DestroyService do
describe "Deletes a user and all their personal projects" do
let!(:user) { create(:user) }
let!(:admin) { create(:admin) }
let!(:namespace) { user.namespace }
let!(:project) { create(:project, namespace: namespace) }
let(:service) { described_class.new(admin) }
let(:gitlab_shell) { Gitlab::Shell.new }
let!(:user) { create(:user) }
let!(:admin) { create(:admin) }
let!(:namespace) { user.namespace }
let!(:project) { create(:project, namespace: namespace) }
let(:service) { described_class.new(admin) }
let(:gitlab_shell) { Gitlab::Shell.new }
describe "Deletes a user and all their personal projects", :enable_admin_mode do
context 'no options are given' do
it 'deletes the user' do
user_data = service.execute(user)
......@@ -215,35 +215,6 @@ RSpec.describe Users::DestroyService do
end
end
context "deletion permission checks" do
it 'does not delete the user when user is not an admin' do
other_user = create(:user)
expect { described_class.new(other_user).execute(user) }.to raise_error(Gitlab::Access::AccessDeniedError)
expect(User.exists?(user.id)).to be(true)
end
it 'allows admins to delete anyone' do
described_class.new(admin).execute(user)
expect(User.exists?(user.id)).to be(false)
end
it 'allows users to delete their own account' do
described_class.new(user).execute(user)
expect(User.exists?(user.id)).to be(false)
end
it 'allows user to be deleted if skip_authorization: true' do
other_user = create(:user)
described_class.new(user).execute(other_user, skip_authorization: true)
expect(User.exists?(other_user.id)).to be(false)
end
end
context "migrating associated records" do
let!(:issue) { create(:issue, author: user) }
......@@ -320,4 +291,43 @@ RSpec.describe Users::DestroyService do
end
end
end
describe "Deletion permission checks" do
it 'does not delete the user when user is not an admin' do
other_user = create(:user)
expect { described_class.new(other_user).execute(user) }.to raise_error(Gitlab::Access::AccessDeniedError)
expect(User.exists?(user.id)).to be(true)
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'allows admins to delete anyone' do
described_class.new(admin).execute(user)
expect(User.exists?(user.id)).to be(false)
end
end
context 'when admin mode is disabled' do
it 'disallows admins to delete anyone' do
expect { described_class.new(admin).execute(user) }.to raise_error(Gitlab::Access::AccessDeniedError)
expect(User.exists?(user.id)).to be(true)
end
end
it 'allows users to delete their own account' do
described_class.new(user).execute(user)
expect(User.exists?(user.id)).to be(false)
end
it 'allows user to be deleted if skip_authorization: true' do
other_user = create(:user)
described_class.new(user).execute(other_user, skip_authorization: true)
expect(User.exists?(other_user.id)).to be(false)
end
end
end
......@@ -52,7 +52,7 @@ RSpec.describe Users::SetStatusService do
{ emoji: 'taurus', message: 'a random status', user: target_user }
end
context 'the current user is admin' do
context 'the current user is admin', :enable_admin_mode do
let(:current_user) { create(:admin) }
it 'changes the status when the current user is allowed to do that' do
......
......@@ -283,12 +283,10 @@ RSpec.configure do |config|
./ee/spec/lib
./ee/spec/requests/admin
./ee/spec/serializers
./ee/spec/services
./ee/spec/support/protected_tags
./ee/spec/support/shared_examples/features
./ee/spec/support/shared_examples/finders/geo
./ee/spec/support/shared_examples/graphql/geo
./ee/spec/support/shared_examples/services
./spec/features
./spec/finders
./spec/frontend
......@@ -296,7 +294,6 @@ RSpec.configure do |config|
./spec/lib
./spec/requests
./spec/serializers
./spec/services
./spec/support/protected_tags
./spec/support/shared_examples/features
./spec/support/shared_examples/requests
......
......@@ -13,6 +13,8 @@ module AdminModeHelper
def enable_admin_mode!(user)
fake_user_mode = instance_double(Gitlab::Auth::CurrentUserMode)
allow(Gitlab::Auth::CurrentUserMode).to receive(:new).and_call_original
allow(Gitlab::Auth::CurrentUserMode).to receive(:new).with(user).and_return(fake_user_mode)
allow(fake_user_mode).to receive(:admin_mode?).and_return(user&.admin?)
end
......
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