summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2018-04-07 09:17:59 +0000
committerKamil Trzciński <ayufan@ayufan.eu>2018-04-07 09:17:59 +0000
commitdd552d06f6e39d5e6138a33bd7c1bffb2d3dbb1d (patch)
treee2cf4b8714c7dbb2bfc08c34e21b14cd5f9fa4e5 /spec/lib
parent671e93dc38365f3b05cb3cfe719e64713196be31 (diff)
parentb38439a3ae3c7ea1675b7037e4882213bdc58fdf (diff)
downloadgitlab-ce-dd552d06f6e39d5e6138a33bd7c1bffb2d3dbb1d.tar.gz
Merge branch '31591-project-deploy-tokens-to-allow-permanent-access' into 'master'
Create Project Deploy Tokens to allow permanent access to repo and registry Closes #31591 See merge request gitlab-org/gitlab-ce!17894
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/forever_spec.rb21
-rw-r--r--spec/lib/gitlab/auth_spec.rb122
-rw-r--r--spec/lib/gitlab/git_access_spec.rb62
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml5
4 files changed, 207 insertions, 3 deletions
diff --git a/spec/lib/forever_spec.rb b/spec/lib/forever_spec.rb
new file mode 100644
index 00000000000..cf40c467c72
--- /dev/null
+++ b/spec/lib/forever_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Forever do
+ describe '.date' do
+ subject { described_class.date }
+
+ context 'when using PostgreSQL' do
+ it 'should return Postgresql future date' do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
+ expect(subject).to eq(described_class::POSTGRESQL_DATE)
+ end
+ end
+
+ context 'when using MySQL' do
+ it 'should return MySQL future date' do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
+ expect(subject).to eq(described_class::MYSQL_DATE)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 18cef8ec996..9ccd0b206cc 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::Auth do
describe 'constants' do
it 'API_SCOPES contains all scopes for API access' do
- expect(subject::API_SCOPES).to eq %i[api read_user sudo]
+ expect(subject::API_SCOPES).to eq %i[api read_user sudo read_repository]
end
it 'OPENID_SCOPES contains all scopes for OpenID Connect' do
@@ -19,7 +19,7 @@ describe Gitlab::Auth do
it 'optional_scopes contains all non-default scopes' do
stub_container_registry_config(enabled: true)
- expect(subject.optional_scopes).to eq %i[read_user sudo read_registry openid]
+ expect(subject.optional_scopes).to eq %i[read_user sudo read_repository read_registry openid]
end
context 'registry_scopes' do
@@ -231,7 +231,7 @@ describe Gitlab::Auth do
.to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
end
- it 'falls through oauth authentication when the username is oauth2' do
+ it 'fails through oauth authentication when the username is oauth2' do
user = create(
:user,
username: 'oauth2',
@@ -255,6 +255,122 @@ describe Gitlab::Auth do
expect { gl_auth.find_for_git_client('foo', 'bar', project: nil, ip: 'ip') }.to raise_error(Gitlab::Auth::MissingPersonalAccessTokenError)
end
+
+ context 'while using deploy tokens' do
+ let(:project) { create(:project) }
+ let(:auth_failure) { Gitlab::Auth::Result.new(nil, nil) }
+
+ context 'when the deploy token has read_repository as scope' do
+ let(:deploy_token) { create(:deploy_token, read_registry: false, projects: [project]) }
+ let(:login) { deploy_token.username }
+
+ it 'succeeds when login and token are valid' do
+ auth_success = Gitlab::Auth::Result.new(deploy_token, project, :deploy_token, [:download_code])
+
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: login)
+ expect(gl_auth.find_for_git_client(login, deploy_token.token, project: project, ip: 'ip'))
+ .to eq(auth_success)
+ end
+
+ it 'fails when login is not valid' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'random_login')
+ expect(gl_auth.find_for_git_client('random_login', deploy_token.token, project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails when token is not valid' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, '123123', project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token is nil' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, nil, project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token is not related to project' do
+ another_deploy_token = create(:deploy_token)
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, another_deploy_token.token, project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token has been revoked' do
+ deploy_token.revoke!
+
+ expect(deploy_token.revoked?).to be_truthy
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'deploy-token')
+ expect(gl_auth.find_for_git_client('deploy-token', deploy_token.token, project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+ end
+
+ context 'when the deploy token has read_registry as a scope' do
+ let(:deploy_token) { create(:deploy_token, read_repository: false, projects: [project]) }
+ let(:login) { deploy_token.username }
+
+ context 'when registry enabled' do
+ before do
+ stub_container_registry_config(enabled: true)
+ end
+
+ it 'succeeds when login and token are valid' do
+ auth_success = Gitlab::Auth::Result.new(deploy_token, project, :deploy_token, [:read_container_image])
+
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: login)
+ expect(gl_auth.find_for_git_client(login, deploy_token.token, project: nil, ip: 'ip'))
+ .to eq(auth_success)
+ end
+
+ it 'fails when login is not valid' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'random_login')
+ expect(gl_auth.find_for_git_client('random_login', deploy_token.token, project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails when token is not valid' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, '123123', project: project, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token is nil' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, nil, project: nil, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token is not related to project' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, 'abcdef', project: nil, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+
+ it 'fails if token has been revoked' do
+ deploy_token.revoke!
+
+ expect(deploy_token.revoked?).to be_truthy
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'deploy-token')
+ expect(gl_auth.find_for_git_client('deploy-token', deploy_token.token, project: nil, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+ end
+
+ context 'when registry disabled' do
+ before do
+ stub_container_registry_config(enabled: false)
+ end
+
+ it 'fails when login and token are valid' do
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
+ expect(gl_auth.find_for_git_client(login, deploy_token.token, project: nil, ip: 'ip'))
+ .to eq(auth_failure)
+ end
+ end
+ end
+ end
end
describe 'find_with_user_password' do
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index c870997e274..6c625596605 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -145,6 +145,33 @@ describe Gitlab::GitAccess do
expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:auth_upload])
end
end
+
+ context 'when actor is DeployToken' do
+ let(:actor) { create(:deploy_token, projects: [project]) }
+
+ context 'when DeployToken is active and belongs to project' do
+ it 'allows pull access' do
+ expect { pull_access_check }.not_to raise_error
+ end
+
+ it 'blocks the push' do
+ expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload])
+ end
+ end
+
+ context 'when DeployToken does not belong to project' do
+ let(:another_project) { create(:project) }
+ let(:actor) { create(:deploy_token, projects: [another_project]) }
+
+ it 'blocks pull access' do
+ expect { pull_access_check }.to raise_not_found
+ end
+
+ it 'blocks the push' do
+ expect { push_access_check }.to raise_not_found
+ end
+ end
+ end
end
context 'when actor is nil' do
@@ -594,6 +621,41 @@ describe Gitlab::GitAccess do
end
end
+ describe 'deploy token permissions' do
+ let(:deploy_token) { create(:deploy_token) }
+ let(:actor) { deploy_token }
+
+ context 'pull code' do
+ context 'when project is authorized' do
+ before do
+ deploy_token.projects << project
+ end
+
+ it { expect { pull_access_check }.not_to raise_error }
+ end
+
+ context 'when unauthorized' do
+ context 'from public project' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it { expect { pull_access_check }.not_to raise_error }
+ end
+
+ context 'from internal project' do
+ let(:project) { create(:project, :internal, :repository) }
+
+ it { expect { pull_access_check }.to raise_not_found }
+ end
+
+ context 'from private project' do
+ let(:project) { create(:project, :private, :repository) }
+
+ it { expect { pull_access_check }.to raise_not_found }
+ end
+ end
+ end
+ end
+
describe 'build authentication_abilities permissions' do
let(:authentication_abilities) { build_authentication_abilities }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index b675d5dc031..897a5984782 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -145,6 +145,9 @@ pipeline_schedule:
- pipelines
pipeline_schedule_variables:
- pipeline_schedule
+deploy_tokens:
+- project_deploy_tokens
+- projects
deploy_keys:
- user
- deploy_keys_projects
@@ -281,6 +284,8 @@ project:
- project_badges
- source_of_merge_requests
- internal_ids
+- project_deploy_tokens
+- deploy_tokens
award_emoji:
- awardable
- user