diff options
Diffstat (limited to 'spec/lib/gitlab/git_access_spec.rb')
-rw-r--r-- | spec/lib/gitlab/git_access_spec.rb | 117 |
1 files changed, 108 insertions, 9 deletions
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 21607edbc32..780f4329bcc 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -10,8 +10,7 @@ RSpec.describe Gitlab::GitAccess do let(:actor) { user } let(:project) { create(:project, :repository) } - let(:project_path) { project&.path } - let(:namespace_path) { project&.namespace&.path } + let(:repository_path) { "#{project.full_path}.git" } let(:protocol) { 'ssh' } let(:authentication_abilities) { %i[read_project download_code push_code] } let(:redirected_path) { nil } @@ -210,10 +209,9 @@ RSpec.describe Gitlab::GitAccess do end end - context 'when the project is nil' do + context 'when the project does not exist' do let(:project) { nil } - let(:project_path) { "new-project" } - let(:namespace_path) { user.namespace.path } + let(:repository_path) { "#{user.namespace.path}/new-project.git" } it 'blocks push and pull with "not found"' do aggregate_failures do @@ -389,6 +387,108 @@ RSpec.describe Gitlab::GitAccess do end end + describe '#check_otp_session!' do + let_it_be(:user) { create(:user, :two_factor_via_otp)} + let_it_be(:key) { create(:key, user: user) } + let_it_be(:actor) { key } + + before do + project.add_developer(user) + stub_feature_flags(two_factor_for_cli: true) + end + + context 'with an OTP session', :clean_gitlab_redis_shared_state do + before do + Gitlab::Redis::SharedState.with do |redis| + redis.set("#{Gitlab::Auth::Otp::SessionEnforcer::OTP_SESSIONS_NAMESPACE}:#{key.id}", true) + end + end + + 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 + end + end + end + + context 'without OTP session' do + it 'does not allow push or pull access' do + user = 'jane.doe' + host = 'fridge.ssh' + port = 42 + + stub_config( + gitlab_shell: { + ssh_user: user, + ssh_host: host, + ssh_port: port + } + ) + + error_message = "OTP verification is required to access the repository.\n\n"\ + " Use: ssh #{user}@#{host} -p #{port} 2fa_verify" + + aggregate_failures do + expect { push_access_check }.to raise_forbidden(error_message) + expect { pull_access_check }.to raise_forbidden(error_message) + end + end + + context 'when protocol is HTTP' do + let(:protocol) { 'http' } + + 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 + end + end + end + + context 'when actor is not an SSH key' do + let(:deploy_key) { create(:deploy_key, user: user) } + let(:actor) { deploy_key } + + before do + deploy_key.deploy_keys_projects.create(project: project, can_push: true) + end + + 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 + end + end + end + + context 'when 2FA is not enabled for the user' do + let(:user) { create(:user)} + let(:actor) { create(:key, user: user) } + + 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 + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(two_factor_for_cli: false) + end + + 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 + end + end + end + end + end + describe '#check_db_accessibility!' do context 'when in a read-only GitLab instance' do before do @@ -452,9 +552,8 @@ RSpec.describe Gitlab::GitAccess do context 'when project is public' do let(:public_project) { create(:project, :public, :repository) } - let(:project_path) { public_project.path } - let(:namespace_path) { public_project.namespace.path } - let(:access) { access_class.new(nil, public_project, 'web', authentication_abilities: [:download_code], repository_path: project_path, namespace_path: namespace_path) } + let(:repository_path) { "#{public_project.full_path}.git" } + let(:access) { access_class.new(nil, public_project, 'web', authentication_abilities: [:download_code], repository_path: repository_path) } context 'when repository is enabled' do it 'give access to download code' do @@ -1169,7 +1268,7 @@ RSpec.describe Gitlab::GitAccess do def access access_class.new(actor, project, protocol, authentication_abilities: authentication_abilities, - namespace_path: namespace_path, repository_path: project_path, + repository_path: repository_path, redirected_path: redirected_path, auth_result_type: auth_result_type) end |