Commit 60e42dd9 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'rs-git-access-spec-speed-ee' into 'master'

[EE] Greatly reduce test duration for git_access_spec

See merge request !2719
parents 692597a8 b3a3257f
...@@ -6,6 +6,7 @@ module Gitlab ...@@ -6,6 +6,7 @@ module Gitlab
include PathLocksHelper include PathLocksHelper
UnauthorizedError = Class.new(StandardError) UnauthorizedError = Class.new(StandardError)
NotFoundError = Class.new(StandardError) NotFoundError = Class.new(StandardError)
ProjectMovedError = Class.new(NotFoundError)
ERROR_MESSAGES = { ERROR_MESSAGES = {
upload: 'You are not allowed to upload code for this project.', upload: 'You are not allowed to upload code for this project.',
...@@ -95,7 +96,8 @@ module Gitlab ...@@ -95,7 +96,8 @@ module Gitlab
end end
def check_project_moved! def check_project_moved!
if redirected_path return unless redirected_path
url = protocol == 'ssh' ? project.ssh_url_to_repo : project.http_url_to_repo url = protocol == 'ssh' ? project.ssh_url_to_repo : project.http_url_to_repo
message = <<-MESSAGE.strip_heredoc message = <<-MESSAGE.strip_heredoc
Project '#{redirected_path}' was moved to '#{project.full_path}'. Project '#{redirected_path}' was moved to '#{project.full_path}'.
...@@ -105,8 +107,7 @@ module Gitlab ...@@ -105,8 +107,7 @@ module Gitlab
git remote set-url origin #{url} git remote set-url origin #{url}
MESSAGE MESSAGE
raise NotFoundError, message raise ProjectMovedError, message
end
end end
def check_command_disabled!(cmd) def check_command_disabled!(cmd)
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::GitAccess do describe Gitlab::GitAccess do
let(:pull_access_check) { access.check('git-upload-pack', '_any') } set(:user) { create(:user) }
let(:push_access_check) { access.check('git-receive-pack', '_any') }
let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:actor) { user } let(:actor) { user }
let(:project) { create(:project, :repository) }
let(:protocol) { 'ssh' } let(:protocol) { 'ssh' }
let(:authentication_abilities) { %i[read_project download_code push_code] }
let(:redirected_path) { nil } let(:redirected_path) { nil }
let(:authentication_abilities) do
[ let(:access) { described_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
:read_project, let(:push_access_check) { access.check('git-receive-pack', '_any') }
:download_code, let(:pull_access_check) { access.check('git-upload-pack', '_any') }
:push_code
]
end
describe '#check with single protocols allowed' do describe '#check with single protocols allowed' do
def disable_protocol(protocol) def disable_protocol(protocol)
...@@ -27,14 +23,13 @@ describe Gitlab::GitAccess do ...@@ -27,14 +23,13 @@ describe Gitlab::GitAccess do
disable_protocol('ssh') disable_protocol('ssh')
end end
it 'blocks ssh git push' do it 'blocks ssh git push and pull' do
aggregate_failures do
expect { push_access_check }.to raise_unauthorized('Git access over SSH is not allowed') expect { push_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
end
it 'blocks ssh git pull' do
expect { pull_access_check }.to raise_unauthorized('Git access over SSH is not allowed') expect { pull_access_check }.to raise_unauthorized('Git access over SSH is not allowed')
end end
end end
end
context 'http disabled' do context 'http disabled' do
let(:protocol) { 'http' } let(:protocol) { 'http' }
...@@ -43,15 +38,14 @@ describe Gitlab::GitAccess do ...@@ -43,15 +38,14 @@ describe Gitlab::GitAccess do
disable_protocol('http') disable_protocol('http')
end end
it 'blocks http push' do it 'blocks http push and pull' do
aggregate_failures do
expect { push_access_check }.to raise_unauthorized('Git access over HTTP is not allowed') expect { push_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
end
it 'blocks http git pull' do
expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed') expect { pull_access_check }.to raise_unauthorized('Git access over HTTP is not allowed')
end end
end end
end end
end
describe '#check_project_accessibility!' do describe '#check_project_accessibility!' do
context 'when the project exists' do context 'when the project exists' do
...@@ -65,22 +59,20 @@ describe Gitlab::GitAccess do ...@@ -65,22 +59,20 @@ describe Gitlab::GitAccess do
deploy_key.projects << project deploy_key.projects << project
end end
it 'allows pull access' do it 'allows push and pull access' do
aggregate_failures do
expect { push_access_check }.not_to raise_error
expect { pull_access_check }.not_to raise_error expect { pull_access_check }.not_to raise_error
end end
it 'allows push access' do
expect { push_access_check }.not_to raise_error
end end
end end
context 'when the Deploykey does not have access to the project' do context 'when the Deploykey does not have access to the project' do
it 'blocks pulls with "not found"' do it 'blocks push and pull with "not found"' do
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') aggregate_failures do
expect { push_access_check }.to raise_not_found
expect { pull_access_check }.to raise_not_found
end end
it 'blocks pushes with "not found"' do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
end end
end end
end end
...@@ -88,25 +80,23 @@ describe Gitlab::GitAccess do ...@@ -88,25 +80,23 @@ describe Gitlab::GitAccess do
context 'when actor is a User' do context 'when actor is a User' do
context 'when the User can read the project' do context 'when the User can read the project' do
before do before do
project.team << [user, :master] project.add_master(user)
end end
it 'allows pull access' do it 'allows push and pull access' do
aggregate_failures do
expect { pull_access_check }.not_to raise_error expect { pull_access_check }.not_to raise_error
end
it 'allows push access' do
expect { push_access_check }.not_to raise_error expect { push_access_check }.not_to raise_error
end end
end end
end
context 'when the User cannot read the project' do context 'when the User cannot read the project' do
it 'blocks pulls with "not found"' do it 'blocks push and pull with "not found"' do
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') aggregate_failures do
expect { push_access_check }.to raise_not_found
expect { pull_access_check }.to raise_not_found
end end
it 'blocks pushes with "not found"' do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.')
end end
end end
end end
...@@ -121,7 +111,7 @@ describe Gitlab::GitAccess do ...@@ -121,7 +111,7 @@ describe Gitlab::GitAccess do
end end
it 'does not block pushes with "not found"' do it 'does not block pushes with "not found"' do
expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload])
end end
end end
end end
...@@ -137,17 +127,17 @@ describe Gitlab::GitAccess do ...@@ -137,17 +127,17 @@ describe Gitlab::GitAccess do
end end
it 'does not block pushes with "not found"' do it 'does not block pushes with "not found"' do
expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload])
end end
end end
context 'when guests cannot read the project' do context 'when guests cannot read the project' do
it 'blocks pulls with "not found"' do it 'blocks pulls with "not found"' do
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') expect { pull_access_check }.to raise_not_found
end end
it 'blocks pushes with "not found"' do it 'blocks pushes with "not found"' do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') expect { push_access_check }.to raise_not_found
end end
end end
end end
...@@ -156,48 +146,50 @@ describe Gitlab::GitAccess do ...@@ -156,48 +146,50 @@ describe Gitlab::GitAccess do
context 'when the project is nil' do context 'when the project is nil' do
let(:project) { nil } let(:project) { nil }
it 'blocks any command with "not found"' do it 'blocks push and pull with "not found"' do
expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') aggregate_failures do
expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') expect { pull_access_check }.to raise_not_found
expect { push_access_check }.to raise_not_found
end
end end
end end
end end
describe '#check_project_moved!' do describe '#check_project_moved!' do
before do before do
project.team << [user, :master] project.add_master(user)
end end
context 'when a redirect was not followed to find the project' do context 'when a redirect was not followed to find the project' do
context 'pull code' do it 'allows push and pull access' do
it { expect { pull_access_check }.not_to raise_error } aggregate_failures do
expect { push_access_check }.not_to raise_error
expect { pull_access_check }.not_to raise_error
end end
context 'push code' do
it { expect { push_access_check }.not_to raise_error }
end end
end end
context 'when a redirect was followed to find the project' do context 'when a redirect was followed to find the project' do
let(:redirected_path) { 'some/other-path' } let(:redirected_path) { 'some/other-path' }
context 'pull code' do it 'blocks push and pull access' do
it { expect { pull_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) } aggregate_failures do
it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) } expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /Project '#{redirected_path}' was moved to '#{project.full_path}'/)
expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.ssh_url_to_repo}/)
context 'http protocol' do expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /Project '#{redirected_path}' was moved to '#{project.full_path}'/)
let(:protocol) { 'http' } expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.ssh_url_to_repo}/)
it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
end end
end end
context 'push code' do
it { expect { push_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
context 'http protocol' do context 'http protocol' do
let(:protocol) { 'http' } let(:protocol) { 'http' }
it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
it 'includes the path to the project using HTTP' do
aggregate_failures do
expect { push_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.http_url_to_repo}/)
expect { pull_access_check }.to raise_error(described_class::ProjectMovedError, /git remote set-url origin #{project.http_url_to_repo}/)
end
end end
end end
end end
...@@ -242,40 +234,28 @@ describe Gitlab::GitAccess do ...@@ -242,40 +234,28 @@ describe Gitlab::GitAccess do
end end
describe '#check_download_access!' do describe '#check_download_access!' do
describe 'master permissions' do it 'allows masters to pull' do
before do project.add_master(user)
project.team << [user, :master]
end
context 'pull code' do expect { pull_access_check }.not_to raise_error
it { expect { pull_access_check }.not_to raise_error }
end
end end
describe 'guest permissions' do it 'disallows guests to pull' do
before do project.add_guest(user)
project.team << [user, :guest]
end
context 'pull code' do expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download])
it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') }
end
end end
describe 'blocked user' do it 'disallows blocked users to pull' do
before do project.add_master(user)
project.team << [user, :master]
user.block user.block
end
context 'pull code' do expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.')
it { expect { pull_access_check }.to raise_unauthorized('Your account has been blocked.') }
end
end end
describe 'without access to project' do describe 'without access to project' do
context 'pull code' do context 'pull code' do
it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { pull_access_check }.to raise_not_found }
end end
context 'when project is public' do context 'when project is public' do
...@@ -292,7 +272,7 @@ describe Gitlab::GitAccess do ...@@ -292,7 +272,7 @@ describe Gitlab::GitAccess do
it 'does not give access to download code' do it 'does not give access to download code' do
public_project.project_feature.update_attribute(:repository_access_level, ProjectFeature::DISABLED) public_project.project_feature.update_attribute(:repository_access_level, ProjectFeature::DISABLED)
expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download])
end end
end end
end end
...@@ -321,13 +301,13 @@ describe Gitlab::GitAccess do ...@@ -321,13 +301,13 @@ describe Gitlab::GitAccess do
context 'from internal project' do context 'from internal project' do
let(:project) { create(:project, :internal, :repository) } let(:project) { create(:project, :internal, :repository) }
it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { pull_access_check }.to raise_not_found }
end end
context 'from private project' do context 'from private project' do
let(:project) { create(:project, :private, :repository) } let(:project) { create(:project, :private, :repository) }
it { expect { pull_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { pull_access_check }.to raise_not_found }
end end
end end
end end
...@@ -380,7 +360,7 @@ describe Gitlab::GitAccess do ...@@ -380,7 +360,7 @@ describe Gitlab::GitAccess do
context 'when is not member of the project' do context 'when is not member of the project' do
context 'pull code' do context 'pull code' do
it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') } it { expect { pull_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:download]) }
end end
end end
end end
...@@ -440,28 +420,30 @@ describe Gitlab::GitAccess do ...@@ -440,28 +420,30 @@ describe Gitlab::GitAccess do
end end
end end
# Run permission checks for a user
def self.run_permission_checks(permissions_matrix) def self.run_permission_checks(permissions_matrix)
permissions_matrix.keys.each do |role| permissions_matrix.each_pair do |role, matrix|
describe "#{role} access" do # Run through the entire matrix for this role in one test to avoid
before do # repeated setup.
#
# Expectations are given a custom failure message proc so that it's
# easier to identify which check(s) failed.
it "has the correct permissions for #{role}s" do
if role == :admin if role == :admin
user.update_attribute(:admin, true) user.update_attribute(:admin, true)
else else
project.team << [user, role] project.team << [user, role]
end end
end
permissions_matrix[role].each do |action, allowed| aggregate_failures do
context action.to_s do matrix.each do |action, allowed|
subject { access.send(:check_push_access!, changes[action]) } check = -> { access.send(:check_push_access!, changes[action]) }
it do
if allowed if allowed
expect { subject }.not_to raise_error expect(&check).not_to raise_error,
-> { "expected #{action} to be allowed" }
else else
expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError) expect(&check).to raise_error(Gitlab::GitAccess::UnauthorizedError),
end -> { "expected #{action} to be disallowed" }
end end
end end
end end
...@@ -471,24 +453,22 @@ describe Gitlab::GitAccess do ...@@ -471,24 +453,22 @@ describe Gitlab::GitAccess do
# Run permission checks for a group # Run permission checks for a group
def self.run_group_permission_checks(permissions_matrix) def self.run_group_permission_checks(permissions_matrix)
permissions_matrix.keys.each do |role| permissions_matrix.each_pair do |role, matrix|
describe "#{role} access" do it "has the correct permissions for group #{role}s" do
before do project
project.project_group_links.create( .project_group_links
group: group, group_access: Gitlab::Access.sym_options[role] .create(group: group, group_access: Gitlab::Access.sym_options[role])
)
end
permissions_matrix[role].each do |action, allowed| aggregate_failures do
context action.to_s do matrix.each do |action, allowed|
subject { access.send(:check_push_access!, changes[action]) } check = -> { access.send(:check_push_access!, changes[action]) }
it do
if allowed if allowed
expect { subject }.not_to raise_error expect(&check).not_to raise_error,
-> { "expected #{action} to be allowed" }
else else
expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError) expect(&check).to raise_error(Gitlab::GitAccess::UnauthorizedError),
end -> { "expected #{action} to be disallowed" }
end end
end end
end end
...@@ -719,10 +699,11 @@ describe Gitlab::GitAccess do ...@@ -719,10 +699,11 @@ describe Gitlab::GitAccess do
allow(License).to receive(:block_changes?).and_return(true) allow(License).to receive(:block_changes?).and_return(true)
end end
# All permissions are `false` # Only check admin; if an admin can't do it, other roles can't either
permissions_matrix = Hash.new(Hash.new(false)) matrix = permissions_matrix[:admin].dup
matrix.each { |key, _| matrix[key] = false }
run_permission_checks(permissions_matrix) run_permission_checks(admin: matrix)
end end
context "when in a secondary gitlab geo node" do context "when in a secondary gitlab geo node" do
...@@ -732,38 +713,39 @@ describe Gitlab::GitAccess do ...@@ -732,38 +713,39 @@ describe Gitlab::GitAccess do
allow(Gitlab::Geo).to receive(:secondary?) { true } allow(Gitlab::Geo).to receive(:secondary?) { true }
end end
# All permissions are `false` # Only check admin; if an admin can't do it, other roles can't either
permissions_matrix = Hash.new(Hash.new(false)) matrix = permissions_matrix[:admin].dup
matrix.each { |key, _| matrix[key] = false }
run_permission_checks(permissions_matrix) run_permission_checks(admin: matrix)
end end
describe "push_rule_check" do describe "push_rule_check" do
let(:start_sha) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
let(:end_sha) { '570e7b2abdd848b95f2f578043fc23bd6f6fd24d' }
before do before do
project.team << [user, :developer] project.add_developer(user)
allow(project.repository).to receive(:new_commits).and_return( allow(project.repository).to receive(:new_commits)
project.repository.commits_between('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d') .and_return(project.repository.commits_between(start_sha, end_sha))
)
end end
describe "author email check" do describe "author email check" do
it 'returns true' do it 'returns true' do
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
it 'returns false' do it 'returns false' do
project.create_push_rule project.create_push_rule(commit_message_regex: "@only.com")
project.push_rule.update(commit_message_regex: "@only.com")
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
it 'returns true for tags' do it 'returns true for tags' do
project.create_push_rule project.create_push_rule(commit_message_regex: "@only.com")
project.push_rule.update(commit_message_regex: "@only.com")
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/tags/v1') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/tags/v1") }.not_to raise_error
end end
it 'allows githook for new branch with an old bad commit' do it 'allows githook for new branch with an old bad commit' do
...@@ -772,11 +754,10 @@ describe Gitlab::GitAccess do ...@@ -772,11 +754,10 @@ describe Gitlab::GitAccess do
allow(bad_commit).to receive(:refs).and_return([ref_object]) allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit]) allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit])
project.create_push_rule project.create_push_rule(commit_message_regex: "Change some files")
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref # push to new branch, so use a blank old rev and new ref
expect { access.send(:check_push_access!, "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new-branch") }.not_to raise_error expect { access.send(:check_push_access!, "#{Gitlab::Git::BLANK_SHA} #{end_sha} refs/heads/new-branch") }.not_to raise_error
end end
it 'allows githook for any change with an old bad commit' do it 'allows githook for any change with an old bad commit' do
...@@ -785,11 +766,10 @@ describe Gitlab::GitAccess do ...@@ -785,11 +766,10 @@ describe Gitlab::GitAccess do
allow(bad_commit).to receive(:refs).and_return([ref_object]) allow(bad_commit).to receive(:refs).and_return([ref_object])
allow(project.repository).to receive(:commits_between).and_return([bad_commit]) allow(project.repository).to receive(:commits_between).and_return([bad_commit])
project.create_push_rule project.create_push_rule(commit_message_regex: "Change some files")
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref # push to new branch, so use a blank old rev and new ref
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
it 'does not allow any change from Web UI with bad commit' do it 'does not allow any change from Web UI with bad commit' do
...@@ -800,78 +780,76 @@ describe Gitlab::GitAccess do ...@@ -800,78 +780,76 @@ describe Gitlab::GitAccess do
allow(project.repository).to receive(:commits_between).and_return([bad_commit]) allow(project.repository).to receive(:commits_between).and_return([bad_commit])
allow(project.repository).to receive(:new_commits).and_return([bad_commit]) allow(project.repository).to receive(:new_commits).and_return([bad_commit])
project.create_push_rule project.create_push_rule(commit_message_regex: "Change some files")
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref # push to new branch, so use a blank old rev and new ref
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
end end
describe "member_check" do describe "member_check" do
before do before do
project.create_push_rule project.create_push_rule(member_check: true)
project.push_rule.update(member_check: true)
end end
it 'returns false for non-member user' do it 'returns false for non-member user' do
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
it 'returns true if committer is a gitlab member' do it 'returns true if committer is a gitlab member' do
create(:user, email: 'dmitriy.zaporozhets@gmail.com') create(:user, email: 'dmitriy.zaporozhets@gmail.com')
expect { access.send(:check_push_access!, '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
end end
describe "file names check" do describe "file names check" do
let(:start_sha) { '913c66a37b4a45b9769037c55c2d238bd0942d2e' }
let(:end_sha) { '33f3729a45c02fc67d00adb1b8bca394b0e761d9' }
before do before do
allow(project.repository).to receive(:new_commits).and_return( allow(project.repository).to receive(:new_commits)
project.repository.commits_between('913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9') .and_return(project.repository.commits_between(start_sha, end_sha))
)
end end
it 'returns false when filename is prohibited' do it 'returns false when filename is prohibited' do
project.create_push_rule project.create_push_rule(file_name_regex: "jpg$")
project.push_rule.update(file_name_regex: "jpg$")
expect { access.send(:check_push_access!, '913c66a37b4a45b9769037c55c2d238bd0942d2e 33f3729a45c02fc67d00adb1b8bca394b0e761d9 refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
it 'returns true if file name is allowed' do it 'returns true if file name is allowed' do
project.create_push_rule project.create_push_rule(file_name_regex: "exe$")
project.push_rule.update(file_name_regex: "exe$")
expect { access.send(:check_push_access!, '913c66a37b4a45b9769037c55c2d238bd0942d2e 33f3729a45c02fc67d00adb1b8bca394b0e761d9 refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
end end
describe "max file size check" do describe "max file size check" do
let(:start_sha) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
let(:end_sha) { '913c66a37b4a45b9769037c55c2d238bd0942d2e' }
before do before do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(1.5.megabytes.to_i) allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(1.5.megabytes.to_i)
end end
it "returns false when size is too large" do it "returns false when size is too large" do
project.create_push_rule project.create_push_rule(max_file_size: 1)
project.push_rule.update(max_file_size: 1)
expect { access.send(:check_push_access!, 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660 913c66a37b4a45b9769037c55c2d238bd0942d2e refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
it "returns true when size is allowed" do it "returns true when size is allowed" do
project.create_push_rule project.create_push_rule(max_file_size: 2)
project.push_rule.update(max_file_size: 2)
expect { access.send(:check_push_access!, 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660 913c66a37b4a45b9769037c55c2d238bd0942d2e refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
it "returns true when size is nil" do it "returns true when size is nil" do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(nil) allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(nil)
project.create_push_rule project.create_push_rule(max_file_size: 2)
project.push_rule.update(max_file_size: 2)
expect { access.send(:check_push_access!, 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660 913c66a37b4a45b9769037c55c2d238bd0942d2e refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
end end
...@@ -883,13 +861,13 @@ describe Gitlab::GitAccess do ...@@ -883,13 +861,13 @@ describe Gitlab::GitAccess do
it 'returns false when blob is too big' do it 'returns false when blob is too big' do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(100.megabytes.to_i) allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(100.megabytes.to_i)
expect { access.send(:check_push_access!, 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660 913c66a37b4a45b9769037c55c2d238bd0942d2e refs/heads/master') }.to raise_error(described_class::UnauthorizedError) expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.to raise_error(described_class::UnauthorizedError)
end end
it 'returns true when blob is just right' do it 'returns true when blob is just right' do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(2.megabytes.to_i) allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(2.megabytes.to_i)
expect { access.send(:check_push_access!, 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660 913c66a37b4a45b9769037c55c2d238bd0942d2e refs/heads/master') }.not_to raise_error expect { access.send(:check_push_access!, "#{start_sha} #{end_sha} refs/heads/master") }.not_to raise_error
end end
end end
end end
...@@ -903,26 +881,26 @@ describe Gitlab::GitAccess do ...@@ -903,26 +881,26 @@ describe Gitlab::GitAccess do
project.team << [user, :reporter] project.team << [user, :reporter]
end end
it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end end
context 'when unauthorized' do context 'when unauthorized' do
context 'to public project' do context 'to public project' do
let(:project) { create(:project, :public, :repository) } let(:project) { create(:project, :public, :repository) }
it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end end
context 'to internal project' do context 'to internal project' do
let(:project) { create(:project, :internal, :repository) } let(:project) { create(:project, :internal, :repository) }
it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) }
end end
context 'to private project' do context 'to private project' do
let(:project) { create(:project, :private, :repository) } let(:project) { create(:project, :private, :repository) }
it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { push_access_check }.to raise_not_found }
end end
end end
end end
...@@ -931,7 +909,7 @@ describe Gitlab::GitAccess do ...@@ -931,7 +909,7 @@ describe Gitlab::GitAccess do
let(:project) { create(:project, :repository, :read_only_repository) } let(:project) { create(:project, :repository, :read_only_repository) }
it 'denies push access' do it 'denies push access' do
project.team << [user, :master] project.add_master(user)
expect { push_access_check }.to raise_unauthorized('The repository is temporarily read-only. Please try again later.') expect { push_access_check }.to raise_unauthorized('The repository is temporarily read-only. Please try again later.')
end end
...@@ -956,19 +934,19 @@ describe Gitlab::GitAccess do ...@@ -956,19 +934,19 @@ describe Gitlab::GitAccess do
context 'to public project' do context 'to public project' do
let(:project) { create(:project, :public, :repository) } let(:project) { create(:project, :public, :repository) }
it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end end
context 'to internal project' do context 'to internal project' do
let(:project) { create(:project, :internal, :repository) } let(:project) { create(:project, :internal, :repository) }
it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { push_access_check }.to raise_not_found }
end end
context 'to private project' do context 'to private project' do
let(:project) { create(:project, :private, :repository) } let(:project) { create(:project, :private, :repository) }
it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { push_access_check }.to raise_not_found }
end end
end end
end end
...@@ -981,26 +959,26 @@ describe Gitlab::GitAccess do ...@@ -981,26 +959,26 @@ describe Gitlab::GitAccess do
key.projects << project key.projects << project
end end
it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end end
context 'when unauthorized' do context 'when unauthorized' do
context 'to public project' do context 'to public project' do
let(:project) { create(:project, :public, :repository) } let(:project) { create(:project, :public, :repository) }
it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') } it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:deploy_key_upload]) }
end end
context 'to internal project' do context 'to internal project' do
let(:project) { create(:project, :internal, :repository) } let(:project) { create(:project, :internal, :repository) }
it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { push_access_check }.to raise_not_found }
end end
context 'to private project' do context 'to private project' do
let(:project) { create(:project, :private, :repository) } let(:project) { create(:project, :private, :repository) }
it { expect { push_access_check }.to raise_not_found('The project you were looking for could not be found.') } it { expect { push_access_check }.to raise_not_found }
end end
end end
end end
...@@ -1012,8 +990,9 @@ describe Gitlab::GitAccess do ...@@ -1012,8 +990,9 @@ describe Gitlab::GitAccess do
raise_error(Gitlab::GitAccess::UnauthorizedError, message) raise_error(Gitlab::GitAccess::UnauthorizedError, message)
end end
def raise_not_found(message) def raise_not_found
raise_error(Gitlab::GitAccess::NotFoundError, message) raise_error(Gitlab::GitAccess::NotFoundError,
Gitlab::GitAccess::ERROR_MESSAGES[:project_not_found])
end end
def build_authentication_abilities def build_authentication_abilities
......
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