diff options
Diffstat (limited to 'spec/lib/gitlab/git_access_snippet_spec.rb')
-rw-r--r-- | spec/lib/gitlab/git_access_snippet_spec.rb | 153 |
1 files changed, 128 insertions, 25 deletions
diff --git a/spec/lib/gitlab/git_access_snippet_spec.rb b/spec/lib/gitlab/git_access_snippet_spec.rb index bbc3808df12..48b425a8ec5 100644 --- a/spec/lib/gitlab/git_access_snippet_spec.rb +++ b/spec/lib/gitlab/git_access_snippet_spec.rb @@ -11,8 +11,9 @@ describe Gitlab::GitAccessSnippet do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :public) } let_it_be(:snippet) { create(:project_snippet, :public, :repository, project: project) } - let(:repository) { snippet.repository } + let_it_be(:migration_bot) { User.migration_bot } + let(:repository) { snippet.repository } let(:actor) { user } let(:protocol) { 'ssh' } let(:changes) { Gitlab::GitAccess::ANY } @@ -27,20 +28,19 @@ describe Gitlab::GitAccessSnippet do let(:actor) { build(:deploy_key) } it 'does not allow push and pull access' do + expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:authentication_mechanism]) expect { pull_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:authentication_mechanism]) end end - describe 'when feature flag :version_snippets is disabled' do - let(:user) { snippet.author } - - before do - stub_feature_flags(version_snippets: false) - end + shared_examples 'actor is migration bot' do + context 'when user is the migration bot' do + let(:user) { migration_bot } - it 'allows push and pull access' do - expect { pull_access_check }.not_to raise_error - expect { push_access_check }.not_to raise_error + it 'can perform git operations' do + expect { push_access_check }.not_to raise_error + expect { pull_access_check }.not_to raise_error + end end end @@ -90,6 +90,12 @@ describe Gitlab::GitAccessSnippet do expect { push_access_check }.not_to raise_error expect { pull_access_check }.not_to raise_error end + + it_behaves_like 'actor is migration bot' do + before do + expect(migration_bot.required_terms_not_accepted?).to be_truthy + end + end end context 'project snippet accessibility', :aggregate_failures do @@ -120,6 +126,7 @@ describe Gitlab::GitAccessSnippet do context 'when project is public' do it_behaves_like 'checks accessibility' + it_behaves_like 'actor is migration bot' end context 'when project is public but snippet feature is private' do @@ -130,6 +137,7 @@ describe Gitlab::GitAccessSnippet do end it_behaves_like 'checks accessibility' + it_behaves_like 'actor is migration bot' end context 'when project is not accessible' do @@ -140,11 +148,58 @@ describe Gitlab::GitAccessSnippet do let(:membership) { membership } it 'respects accessibility' do - expect { push_access_check }.to raise_error(described_class::NotFoundError) - expect { pull_access_check }.to raise_error(described_class::NotFoundError) + expect { push_access_check }.to raise_snippet_not_found + expect { pull_access_check }.to raise_snippet_not_found + end + end + end + + it_behaves_like 'actor is migration bot' + end + + context 'when project is archived' do + let(:project) { create(:project, :public, :archived) } + + [:anonymous, :non_member].each do |membership| + context membership.to_s do + let(:membership) { membership } + + it 'cannot perform git operations' do + expect { push_access_check }.to raise_error(described_class::ForbiddenError) + expect { pull_access_check }.to raise_error(described_class::ForbiddenError) + end + end + end + + [:guest, :reporter, :maintainer, :author, :admin].each do |membership| + context membership.to_s do + let(:membership) { membership } + + it 'cannot perform git pushes' do + expect { push_access_check }.to raise_error(described_class::ForbiddenError) + expect { pull_access_check }.not_to raise_error + end + end + end + + it_behaves_like 'actor is migration bot' + end + + context 'when snippet feature is disabled' do + let(:project) { create(:project, :public, :snippets_disabled) } + + [:anonymous, :non_member, :author, :admin].each do |membership| + context membership.to_s do + let(:membership) { membership } + + it 'cannot perform git operations' do + expect { push_access_check }.to raise_error(described_class::ForbiddenError) + expect { pull_access_check }.to raise_error(described_class::ForbiddenError) end end end + + it_behaves_like 'actor is migration bot' end end @@ -172,6 +227,8 @@ describe Gitlab::GitAccessSnippet do expect { pull_access_check }.to raise_error(error_class) end end + + it_behaves_like 'actor is migration bot' end end @@ -179,36 +236,66 @@ describe Gitlab::GitAccessSnippet do let(:user) { snippet.author } let!(:primary_node) { FactoryBot.create(:geo_node, :primary) } - # Without override, push access would return Gitlab::GitAccessResult::CustomAction - it 'skips geo for snippet' do + before do allow(::Gitlab::Database).to receive(:read_only?).and_return(true) allow(::Gitlab::Geo).to receive(:secondary_with_primary?).and_return(true) + end + # Without override, push access would return Gitlab::GitAccessResult::CustomAction + it 'skips geo for snippet' do expect { push_access_check }.to raise_forbidden(/You can't push code to a read-only GitLab instance/) end + + context 'when user is migration bot' do + let(:user) { migration_bot } + + it 'skips geo for snippet' do + expect { push_access_check }.to raise_forbidden(/You can't push code to a read-only GitLab instance/) + end + end end context 'when changes are specific' do let(:changes) { "2d1db523e11e777e49377cfb22d368deec3f0793 ddd0f15ae83993f5cb66a927a28673882e99100b master" } let(:user) { snippet.author } - it 'does not raise error if SnippetCheck does not raise error' do - expect_next_instance_of(Gitlab::Checks::SnippetCheck) do |check| - expect(check).to receive(:validate!).and_call_original + shared_examples 'snippet checks' do + it 'does not raise error if SnippetCheck does not raise error' do + expect_next_instance_of(Gitlab::Checks::SnippetCheck) do |check| + expect(check).to receive(:validate!).and_call_original + end + expect_next_instance_of(Gitlab::Checks::PushFileCountCheck) do |check| + expect(check).to receive(:validate!) + end + + expect { push_access_check }.not_to raise_error end - expect_next_instance_of(Gitlab::Checks::PushFileCountCheck) do |check| - expect(check).to receive(:validate!) + + it 'raises error if SnippetCheck raises error' do + expect_next_instance_of(Gitlab::Checks::SnippetCheck) do |check| + allow(check).to receive(:validate!).and_raise(Gitlab::GitAccess::ForbiddenError, 'foo') + end + + expect { push_access_check }.to raise_forbidden('foo') end - expect { push_access_check }.not_to raise_error - end + it 'sets the file count limit from Snippet class' do + service = double - it 'raises error if SnippetCheck raises error' do - expect_next_instance_of(Gitlab::Checks::SnippetCheck) do |check| - allow(check).to receive(:validate!).and_raise(Gitlab::GitAccess::ForbiddenError, 'foo') + expect(service).to receive(:validate!).and_return(nil) + expect(Snippet).to receive(:max_file_limit).with(user).and_return(5) + expect(Gitlab::Checks::PushFileCountCheck).to receive(:new).with(anything, hash_including(limit: 5)).and_return(service) + + push_access_check end + end + + it_behaves_like 'snippet checks' - expect { push_access_check }.to raise_forbidden('foo') + context 'when user is migration bot' do + let(:user) { migration_bot } + + it_behaves_like 'snippet checks' end end @@ -221,6 +308,16 @@ describe Gitlab::GitAccessSnippet do let(:ref) { "refs/heads/snippet/edit-file" } let(:changes) { "#{oldrev} #{newrev} #{ref}" } + shared_examples 'migration bot does not err' do + let(:actor) { migration_bot } + + it 'does not err' do + expect(snippet.repository_size_checker).not_to receive(:above_size_limit?) + + expect { push_access_check }.not_to raise_error + end + end + shared_examples_for 'a push to repository already over the limit' do it 'errs' do expect(snippet.repository_size_checker).to receive(:above_size_limit?).and_return(true) @@ -229,6 +326,8 @@ describe Gitlab::GitAccessSnippet do push_access_check end.to raise_error(described_class::ForbiddenError, /Your push has been rejected/) end + + it_behaves_like 'migration bot does not err' end shared_examples_for 'a push to repository below the limit' do @@ -241,6 +340,8 @@ describe Gitlab::GitAccessSnippet do expect { push_access_check }.not_to raise_error end + + it_behaves_like 'migration bot does not err' end shared_examples_for 'a push to repository to make it over the limit' do @@ -255,6 +356,8 @@ describe Gitlab::GitAccessSnippet do push_access_check end.to raise_error(described_class::ForbiddenError, /Your push to this repository would cause it to exceed the size limit/) end + + it_behaves_like 'migration bot does not err' end context 'when GIT_OBJECT_DIRECTORY_RELATIVE env var is set' do |