diff options
author | Horatiu Eugen Vlad <horatiu@vlad.eu> | 2019-04-15 13:05:55 +0000 |
---|---|---|
committer | James Lopez <james@gitlab.com> | 2019-04-15 13:05:55 +0000 |
commit | 0aa56d895dba21d3a01b78d35c445107e224ed0c (patch) | |
tree | f97e1d6d289af84b5838db149a9208ae0f70b267 /spec | |
parent | 922fae29ca100e7f7f30fcb62541305994430779 (diff) | |
download | gitlab-ce-0aa56d895dba21d3a01b78d35c445107e224ed0c.tar.gz |
Added write_repository scope for personal access token
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/auth_spec.rb | 75 | ||||
-rw-r--r-- | spec/requests/git_http_spec.rb | 51 | ||||
-rw-r--r-- | spec/requests/jwt_controller_spec.rb | 2 | ||||
-rw-r--r-- | spec/requests/openid_connect_spec.rb | 2 |
4 files changed, 107 insertions, 23 deletions
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index a4a6338961e..3b5ca7c950c 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -5,7 +5,15 @@ 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 read_repository] + expect(subject::API_SCOPES).to eq %i[api read_user] + end + + it 'ADMIN_SCOPES contains all scopes for ADMIN access' do + expect(subject::ADMIN_SCOPES).to eq %i[sudo] + end + + it 'REPOSITORY_SCOPES contains all scopes for REPOSITORY access' do + expect(subject::REPOSITORY_SCOPES).to eq %i[read_repository write_repository] end it 'OPENID_SCOPES contains all scopes for OpenID Connect' do @@ -19,7 +27,29 @@ 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_repository read_registry openid profile email] + expect(subject.optional_scopes).to eq %i[read_user read_repository write_repository read_registry sudo openid profile email] + end + end + + context 'available_scopes' do + it 'contains all non-default scopes' do + stub_container_registry_config(enabled: true) + + expect(subject.all_available_scopes).to eq %i[api read_user read_repository write_repository read_registry sudo] + end + + it 'contains for non-admin user all non-default scopes without ADMIN access' do + stub_container_registry_config(enabled: true) + user = create(:user, admin: false) + + expect(subject.available_scopes_for(user)).to eq %i[api read_user read_repository write_repository read_registry] + end + + it 'contains for admin user all non-default scopes with ADMIN access' do + stub_container_registry_config(enabled: true) + user = create(:user, admin: true) + + expect(subject.available_scopes_for(user)).to eq %i[api read_user read_repository write_repository read_registry sudo] end context 'registry_scopes' do @@ -122,7 +152,7 @@ describe Gitlab::Auth do token = Gitlab::LfsToken.new(key).token expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: "lfs+deploy-key-#{key.id}") - expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_authentication_abilities)) + expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_only_authentication_abilities)) end it 'does not try password auth before oauth' do @@ -150,7 +180,7 @@ describe Gitlab::Auth do token = Gitlab::LfsToken.new(key).token expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: "lfs+deploy-key-#{key.id}") - expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: project, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_authentication_abilities)) + expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: project, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_only_authentication_abilities)) end end @@ -182,8 +212,19 @@ describe Gitlab::Auth do it 'succeeds for personal access tokens with the `api` scope' do personal_access_token = create(:personal_access_token, scopes: ['api']) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') - expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_access_token, full_authentication_abilities)) + expect_results_with_abilities(personal_access_token, full_authentication_abilities) + end + + it 'succeeds for personal access tokens with the `read_repository` scope' do + personal_access_token = create(:personal_access_token, scopes: ['read_repository']) + + expect_results_with_abilities(personal_access_token, [:download_code]) + end + + it 'succeeds for personal access tokens with the `write_repository` scope' do + personal_access_token = create(:personal_access_token, scopes: ['write_repository']) + + expect_results_with_abilities(personal_access_token, [:download_code, :push_code]) end context 'when registry is enabled' do @@ -194,28 +235,24 @@ describe Gitlab::Auth do it 'succeeds for personal access tokens with the `read_registry` scope' do personal_access_token = create(:personal_access_token, scopes: ['read_registry']) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') - expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_access_token, [:read_container_image])) + expect_results_with_abilities(personal_access_token, [:read_container_image]) end end it 'succeeds if it is an impersonation token' do impersonation_token = create(:personal_access_token, :impersonation, scopes: ['api']) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') - expect(gl_auth.find_for_git_client('', impersonation_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(impersonation_token.user, nil, :personal_access_token, full_authentication_abilities)) + expect_results_with_abilities(impersonation_token, full_authentication_abilities) end it 'limits abilities based on scope' do personal_access_token = create(:personal_access_token, scopes: %w[read_user sudo]) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') - expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_access_token, [])) + expect_results_with_abilities(personal_access_token, []) end it 'fails if password is nil' do - expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: '') - expect(gl_auth.find_for_git_client('', nil, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil)) + expect_results_with_abilities(nil, nil, false) end end @@ -479,7 +516,7 @@ describe Gitlab::Auth do ] end - def read_authentication_abilities + def read_only_authentication_abilities [ :read_project, :download_code, @@ -488,7 +525,7 @@ describe Gitlab::Auth do end def read_write_authentication_abilities - read_authentication_abilities + [ + read_only_authentication_abilities + [ :push_code, :create_container_image ] @@ -499,4 +536,10 @@ describe Gitlab::Auth do :admin_container_image ] end + + def expect_results_with_abilities(personal_access_token, abilities, success = true) + expect(gl_auth).to receive(:rate_limit!).with('ip', success: success, login: '') + expect(gl_auth.find_for_git_client('', personal_access_token&.token, project: nil, ip: 'ip')) + .to eq(Gitlab::Auth::Result.new(personal_access_token&.user, nil, personal_access_token.nil? ? nil : :personal_access_token, abilities)) + end end diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index bfa178f5cae..5c9a5b73ee5 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -549,14 +549,14 @@ describe 'Git HTTP requests' do it 'rejects pulls with personal access token error message' do download(path, user: user.username, password: user.password) do |response| expect(response).to have_gitlab_http_status(:unauthorized) - expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP') + expect(response.body).to include('You must use a personal access token with \'read_repository\' or \'write_repository\' scope for Git over HTTP') end end it 'rejects the push attempt with personal access token error message' do upload(path, user: user.username, password: user.password) do |response| expect(response).to have_gitlab_http_status(:unauthorized) - expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP') + expect(response.body).to include('You must use a personal access token with \'read_repository\' or \'write_repository\' scope for Git over HTTP') end end end @@ -566,6 +566,47 @@ describe 'Git HTTP requests' do it_behaves_like 'pulls are allowed' it_behaves_like 'pushes are allowed' + + it 'rejects the push attempt for read_repository scope' do + read_access_token = create(:personal_access_token, user: user, scopes: [:read_repository]) + + upload(path, user: user.username, password: read_access_token.token) do |response| + expect(response).to have_gitlab_http_status(:forbidden) + expect(response.body).to include('You are not allowed to upload code') + end + end + + it 'accepts the push attempt for write_repository scope' do + write_access_token = create(:personal_access_token, user: user, scopes: [:write_repository]) + + upload(path, user: user.username, password: write_access_token.token) do |response| + expect(response).to have_gitlab_http_status(:ok) + end + end + + it 'accepts the pull attempt for read_repository scope' do + read_access_token = create(:personal_access_token, user: user, scopes: [:read_repository]) + + download(path, user: user.username, password: read_access_token.token) do |response| + expect(response).to have_gitlab_http_status(:ok) + end + end + + it 'accepts the pull attempt for api scope' do + read_access_token = create(:personal_access_token, user: user, scopes: [:api]) + + download(path, user: user.username, password: read_access_token.token) do |response| + expect(response).to have_gitlab_http_status(:ok) + end + end + + it 'accepts the push attempt for api scope' do + write_access_token = create(:personal_access_token, user: user, scopes: [:api]) + + upload(path, user: user.username, password: write_access_token.token) do |response| + expect(response).to have_gitlab_http_status(:ok) + end + end end end @@ -577,14 +618,14 @@ describe 'Git HTTP requests' do it 'rejects pulls with personal access token error message' do download(path, user: 'foo', password: 'bar') do |response| expect(response).to have_gitlab_http_status(:unauthorized) - expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP') + expect(response.body).to include('You must use a personal access token with \'read_repository\' or \'write_repository\' scope for Git over HTTP') end end it 'rejects pushes with personal access token error message' do upload(path, user: 'foo', password: 'bar') do |response| expect(response).to have_gitlab_http_status(:unauthorized) - expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP') + expect(response.body).to include('You must use a personal access token with \'read_repository\' or \'write_repository\' scope for Git over HTTP') end end @@ -598,7 +639,7 @@ describe 'Git HTTP requests' do it 'does not display the personal access token error message' do upload(path, user: 'foo', password: 'bar') do |response| expect(response).to have_gitlab_http_status(:unauthorized) - expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP') + expect(response.body).not_to include('You must use a personal access token with \'read_repository\' or \'write_repository\' scope for Git over HTTP') end end end diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb index 4bb3b848e17..bba473f1c20 100644 --- a/spec/requests/jwt_controller_spec.rb +++ b/spec/requests/jwt_controller_spec.rb @@ -142,7 +142,7 @@ describe JwtController do end it 'allows read access' do - expect(service).to receive(:execute).with(authentication_abilities: Gitlab::Auth.read_authentication_abilities) + expect(service).to receive(:execute).with(authentication_abilities: Gitlab::Auth.read_only_authentication_abilities) get '/jwt/auth', params: parameters end diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb index 2a455523e2c..86e41cbdf00 100644 --- a/spec/requests/openid_connect_spec.rb +++ b/spec/requests/openid_connect_spec.rb @@ -187,7 +187,7 @@ describe 'OpenID Connect requests' do expect(response).to have_gitlab_http_status(200) expect(json_response['issuer']).to eq('http://localhost') expect(json_response['jwks_uri']).to eq('http://www.example.com/oauth/discovery/keys') - expect(json_response['scopes_supported']).to eq(%w[api read_user sudo read_repository openid profile email]) + expect(json_response['scopes_supported']).to eq(%w[api read_user read_repository write_repository sudo openid profile email]) end end |