Commit 7fbf987c authored by Markus Koller's avatar Markus Koller

Merge branch 'refactor_authfinders_specs' into 'master'

Refactor Gitlab::Auth::AuthFinders specs

See merge request gitlab-org/gitlab!53038
parents c57bf235 32e65111
...@@ -7,7 +7,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -7,7 +7,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do
include HttpBasicAuthHelpers include HttpBasicAuthHelpers
# Create the feed_token and static_object_token for the user # Create the feed_token and static_object_token for the user
let_it_be(:user) { create(:user).tap(&:feed_token).tap(&:static_object_token) } let_it_be(:user, freeze: true) { create(:user).tap(&:feed_token).tap(&:static_object_token) }
let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, user: user) }
let_it_be(:project, freeze: true) { create(:project, :private) }
let_it_be(:pipeline, freeze: true) { create(:ci_pipeline, project: project) }
let_it_be(:job, freeze: true) { create(:ci_build, :running, pipeline: pipeline, user: user) }
let_it_be(:failed_job, freeze: true) { create(:ci_build, :failed, pipeline: pipeline, user: user) }
let_it_be(:project2, freeze: true) { create(:project, :private) }
let_it_be(:pipeline2, freeze: true) { create(:ci_pipeline, project: project2) }
let_it_be(:job2, freeze: true) { create(:ci_build, :running, pipeline: pipeline2, user: user) }
let(:env) do let(:env) do
{ {
'rack.input' => '' 'rack.input' => ''
...@@ -15,6 +26,12 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -15,6 +26,12 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
let(:request) { ActionDispatch::Request.new(env) } let(:request) { ActionDispatch::Request.new(env) }
let(:params) { {} }
before_all do
project.add_developer(user)
project2.add_developer(user)
end
def set_param(key, value) def set_param(key, value)
request.update_param(key, value) request.update_param(key, value)
...@@ -28,75 +45,93 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -28,75 +45,93 @@ RSpec.describe Gitlab::Auth::AuthFinders do
env.merge!(basic_auth_header(username, password)) env.merge!(basic_auth_header(username, password))
end end
shared_examples 'find user from job token' do def set_bearer_token(token)
env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
end
shared_examples 'find user from job token' do |without_job_token_allowed|
context 'when route is allowed to be authenticated' do context 'when route is allowed to be authenticated' do
let(:route_authentication_setting) { { job_token_allowed: true } } let(:route_authentication_setting) { { job_token_allowed: true } }
it "returns an Unauthorized exception for an invalid token" do context 'for an invalid token' do
set_token('invalid token') let(:token) { 'invalid token' }
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError) it "returns an Unauthorized exception" do
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
expect(@current_authenticated_job).to be_nil
end
end end
context 'with a running job' do context 'with a running job' do
before do let(:token) { job.token }
job.update!(status: :running)
end
it 'return user if token is valid' do
set_token(job.token)
it 'return user' do
expect(subject).to eq(user) expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job expect(@current_authenticated_job).to eq job
end end
end end
context 'with a job that is not running' do context 'with a job that is not running' do
before do let(:token) { failed_job.token }
job.update!(status: :failed)
end
it 'returns an Unauthorized exception' do it 'returns an Unauthorized exception' do
set_token(job.token)
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError) expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
expect(@current_authenticated_job).to be_nil
end
end
end
context 'when route is not allowed to be authenticated' do
let(:route_authentication_setting) { { job_token_allowed: false } }
context 'with a running job' do
let(:token) { job.token }
if without_job_token_allowed == :error
it 'returns an Unauthorized exception' do
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
expect(@current_authenticated_job).to be_nil
end
elsif without_job_token_allowed == :user
it 'returns the user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
end
else
it 'returns nil' do
is_expected.to be_nil
expect(@current_authenticated_job).to be_nil
end
end end
end end
end end
end end
describe '#find_user_from_bearer_token' do describe '#find_user_from_bearer_token' do
let_it_be_with_reload(:job) { create(:ci_build, user: user) }
subject { find_user_from_bearer_token } subject { find_user_from_bearer_token }
context 'when the token is passed as an oauth token' do context 'when the token is passed as an oauth token' do
def set_token(token) before do
env['HTTP_AUTHORIZATION'] = "Bearer #{token}" set_bearer_token(token)
end end
context 'with a job token' do it_behaves_like 'find user from job token', :error
it_behaves_like 'find user from job token' end
end
context 'with oauth token' do context 'with oauth token' do
let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) } let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
let(:token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api').token } let(:doorkeeper_access_token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
before do before do
set_token(token) set_bearer_token(doorkeeper_access_token.token)
end
it { is_expected.to eq user }
end end
it { is_expected.to eq user }
end end
context 'with a personal access token' do context 'with a personal access token' do
let_it_be(:pat) { create(:personal_access_token, user: user) }
let(:token) { pat.token }
before do before do
env[described_class::PRIVATE_TOKEN_HEADER] = pat.token env[described_class::PRIVATE_TOKEN_HEADER] = personal_access_token.token
end end
it { is_expected.to eq user } it { is_expected.to eq user }
...@@ -277,7 +312,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -277,7 +312,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#deploy_token_from_request' do describe '#deploy_token_from_request' do
let_it_be(:deploy_token) { create(:deploy_token) } let_it_be(:deploy_token, freeze: true) { create(:deploy_token) }
let_it_be(:route_authentication_setting) { { deploy_token_allowed: true } } let_it_be(:route_authentication_setting) { { deploy_token_allowed: true } }
subject { deploy_token_from_request } subject { deploy_token_from_request }
...@@ -293,11 +328,13 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -293,11 +328,13 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'with deploy token headers' do context 'with deploy token headers' do
before do context 'with valid deploy token' do
set_header(described_class::DEPLOY_TOKEN_HEADER, deploy_token.token) before do
end set_header(described_class::DEPLOY_TOKEN_HEADER, deploy_token.token)
end
it { is_expected.to eq deploy_token } it { is_expected.to eq deploy_token }
end
it_behaves_like 'an unauthenticated route' it_behaves_like 'an unauthenticated route'
...@@ -311,17 +348,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -311,17 +348,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'with oauth headers' do context 'with oauth headers' do
before do context 'with valid token' do
set_header('HTTP_AUTHORIZATION', "Bearer #{deploy_token.token}") before do
end set_bearer_token(deploy_token.token)
end
it { is_expected.to eq deploy_token } it { is_expected.to eq deploy_token }
it_behaves_like 'an unauthenticated route' it_behaves_like 'an unauthenticated route'
end
context 'with invalid token' do context 'with invalid token' do
before do before do
set_header('HTTP_AUTHORIZATION', "Bearer invalid_token") set_bearer_token('invalid_token')
end end
it { is_expected.to be_nil } it { is_expected.to be_nil }
...@@ -348,8 +387,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -348,8 +387,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#find_user_from_access_token' do describe '#find_user_from_access_token' do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
before do before do
set_header('SCRIPT_NAME', 'url.atom') set_header('SCRIPT_NAME', 'url.atom')
end end
...@@ -374,24 +411,34 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -374,24 +411,34 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'with OAuth headers' do context 'with OAuth headers' do
it 'returns user' do context 'with valid personal access token' do
set_header('HTTP_AUTHORIZATION', "Bearer #{personal_access_token.token}") before do
set_bearer_token(personal_access_token.token)
end
expect(find_user_from_access_token).to eq user it 'returns user' do
expect(find_user_from_access_token).to eq user
end
end end
it 'returns exception if invalid personal_access_token' do context 'with invalid personal_access_token' do
env['HTTP_AUTHORIZATION'] = 'Bearer invalid_20byte_token' before do
set_bearer_token('invalid_20byte_token')
end
expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError) it 'returns exception' do
expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
end end
context 'when using a non-prefixed access token' do context 'when using a non-prefixed access token' do
let_it_be(:personal_access_token) { create(:personal_access_token, :no_prefix, user: user) } let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, :no_prefix, user: user) }
it 'returns user' do before do
set_header('HTTP_AUTHORIZATION', "Bearer #{personal_access_token.token}") set_bearer_token(personal_access_token.token)
end
it 'returns user' do
expect(find_user_from_access_token).to eq user expect(find_user_from_access_token).to eq user
end end
end end
...@@ -399,8 +446,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -399,8 +446,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#find_user_from_web_access_token' do describe '#find_user_from_web_access_token' do
let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
before do before do
set_header(described_class::PRIVATE_TOKEN_HEADER, personal_access_token.token) set_header(described_class::PRIVATE_TOKEN_HEADER, personal_access_token.token)
end end
...@@ -451,9 +496,9 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -451,9 +496,9 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'when the token has read_api scope' do context 'when the token has read_api scope' do
before do let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, user: user, scopes: ['read_api']) }
personal_access_token.update!(scopes: ['read_api'])
before do
set_header('SCRIPT_NAME', '/api/endpoint') set_header('SCRIPT_NAME', '/api/endpoint')
end end
...@@ -481,8 +526,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -481,8 +526,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#find_personal_access_token' do describe '#find_personal_access_token' do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
before do before do
set_header('SCRIPT_NAME', 'url.atom') set_header('SCRIPT_NAME', 'url.atom')
end end
...@@ -516,21 +559,23 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -516,21 +559,23 @@ RSpec.describe Gitlab::Auth::AuthFinders do
describe '#find_oauth_access_token' do describe '#find_oauth_access_token' do
let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) } let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
let(:token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') } let(:doorkeeper_access_token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
context 'passed as header' do context 'passed as header' do
it 'returns token if valid oauth_access_token' do before do
set_header('HTTP_AUTHORIZATION', "Bearer #{token.token}") set_bearer_token(doorkeeper_access_token.token)
end
expect(find_oauth_access_token.token).to eq token.token it 'returns token if valid oauth_access_token' do
expect(find_oauth_access_token.token).to eq doorkeeper_access_token.token
end end
end end
context 'passed as param' do context 'passed as param' do
it 'returns user if valid oauth_access_token' do it 'returns user if valid oauth_access_token' do
set_param(:access_token, token.token) set_param(:access_token, doorkeeper_access_token.token)
expect(find_oauth_access_token.token).to eq token.token expect(find_oauth_access_token.token).to eq doorkeeper_access_token.token
end end
end end
...@@ -538,10 +583,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -538,10 +583,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do
expect(find_oauth_access_token).to be_nil expect(find_oauth_access_token).to be_nil
end end
it 'returns exception if invalid oauth_access_token' do context 'with invalid token' do
set_header('HTTP_AUTHORIZATION', "Bearer invalid_token") before do
set_bearer_token('invalid_token')
end
expect { find_oauth_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError) it 'returns exception if invalid oauth_access_token' do
expect { find_oauth_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
end end
end end
...@@ -551,7 +600,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -551,7 +600,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'access token is valid' do context 'access token is valid' do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let(:route_authentication_setting) { { basic_auth_personal_access_token: true } } let(:route_authentication_setting) { { basic_auth_personal_access_token: true } }
it 'finds the token from basic auth' do it 'finds the token from basic auth' do
...@@ -572,8 +620,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -572,8 +620,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'route_setting is not set' do context 'route_setting is not set' do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
it 'returns nil' do it 'returns nil' do
auth_header_with(personal_access_token.token) auth_header_with(personal_access_token.token)
...@@ -582,7 +628,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -582,7 +628,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'route_setting is not correct' do context 'route_setting is not correct' do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let(:route_authentication_setting) { { basic_auth_personal_access_token: false } } let(:route_authentication_setting) { { basic_auth_personal_access_token: false } }
it 'returns nil' do it 'returns nil' do
...@@ -629,44 +674,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -629,44 +674,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do
context 'with CI username' do context 'with CI username' do
let(:username) { ::Gitlab::Auth::CI_JOB_USER } let(:username) { ::Gitlab::Auth::CI_JOB_USER }
let_it_be(:user) { create(:user) } before do
let_it_be(:build) { create(:ci_build, user: user, status: :running) } set_basic_auth_header(username, token)
it 'returns nil without password' do
set_basic_auth_header(username, nil)
is_expected.to be_nil
end
it 'returns user with valid token' do
set_basic_auth_header(username, build.token)
is_expected.to eq user
expect(@current_authenticated_job).to eq build
end
it 'raises error with invalid token' do
set_basic_auth_header(username, 'token')
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
end end
it 'returns exception if the job is not running' do it_behaves_like 'find user from job token', :user
set_basic_auth_header(username, build.token)
build.success!
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
end end
end end
describe '#validate_access_token!' do describe '#validate_access_token!' do
subject { validate_access_token! } subject { validate_access_token! }
let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
context 'with a job token' do context 'with a job token' do
let_it_be(:job) { create(:ci_build, user: user, status: :running) }
let(:route_authentication_setting) { { job_token_allowed: true } } let(:route_authentication_setting) { { job_token_allowed: true } }
before do before do
...@@ -684,6 +703,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -684,6 +703,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'token is not valid' do context 'token is not valid' do
let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
before do before do
allow_any_instance_of(described_class).to receive(:access_token).and_return(personal_access_token) allow_any_instance_of(described_class).to receive(:access_token).and_return(personal_access_token)
end end
...@@ -706,7 +727,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -706,7 +727,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
context 'with impersonation token' do context 'with impersonation token' do
let_it_be(:personal_access_token) { create(:personal_access_token, :impersonation, user: user) } let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, :impersonation, user: user) }
context 'when impersonation is disabled' do context 'when impersonation is disabled' do
before do before do
...@@ -722,96 +743,30 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -722,96 +743,30 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#find_user_from_job_token' do describe '#find_user_from_job_token' do
let_it_be(:job) { create(:ci_build, user: user, status: :running) }
let(:route_authentication_setting) { { job_token_allowed: true } }
subject { find_user_from_job_token } subject { find_user_from_job_token }
context 'when the job token is in the headers' do context 'when the token is in the headers' do
it 'returns the user if valid job token' do before do
set_header(described_class::JOB_TOKEN_HEADER, job.token) set_header(described_class::JOB_TOKEN_HEADER, token)
is_expected.to eq(user)
expect(@current_authenticated_job).to eq(job)
end
it 'returns nil without job token' do
set_header(described_class::JOB_TOKEN_HEADER, '')
is_expected.to be_nil
end
it 'returns exception if invalid job token' do
set_header(described_class::JOB_TOKEN_HEADER, 'invalid token')
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
end end
it 'returns exception if the job is not running' do it_behaves_like 'find user from job token'
set_header(described_class::JOB_TOKEN_HEADER, job.token) end
job.success!
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError) context 'when the token is in the job_token param' do
before do
set_param(described_class::JOB_TOKEN_PARAM, token)
end end
context 'when route is not allowed to be authenticated' do it_behaves_like 'find user from job token'
let(:route_authentication_setting) { { job_token_allowed: false } }
it 'sets current_user to nil' do
set_header(described_class::JOB_TOKEN_HEADER, job.token)
allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(true)
is_expected.to be_nil
end
end
end end
context 'when the job token is in the params' do context 'when the token is in the token param' do
shared_examples 'job token params' do |token_key_name| before do
before do set_param(described_class::RUNNER_JOB_TOKEN_PARAM, token)
set_param(token_key_name, token)
end
context 'with valid job token' do
let(:token) { job.token }
it 'returns the user' do
is_expected.to eq(user)
expect(@current_authenticated_job).to eq(job)
end
end
context 'with empty job token' do
let(:token) { '' }
it 'returns nil' do
is_expected.to be_nil
end
end
context 'with invalid job token' do
let(:token) { 'invalid token' }
it 'returns exception' do
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
end
context 'when route is not allowed to be authenticated' do
let(:route_authentication_setting) { { job_token_allowed: false } }
let(:token) { job.token }
it 'sets current_user to nil' do
allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(true)
is_expected.to be_nil
end
end
end end
it_behaves_like 'job token params', described_class::JOB_TOKEN_PARAM it_behaves_like 'find user from job token'
it_behaves_like 'job token params', described_class::RUNNER_JOB_TOKEN_PARAM
end end
context 'when the job token is provided via basic auth' do context 'when the job token is provided via basic auth' do
...@@ -834,7 +789,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -834,7 +789,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#cluster_agent_token_from_authorization_token' do describe '#cluster_agent_token_from_authorization_token' do
let_it_be(:agent_token) { create(:cluster_agent_token) } let_it_be(:agent_token, freeze: true) { create(:cluster_agent_token) }
context 'when route_setting is empty' do context 'when route_setting is empty' do
it 'returns nil' do it 'returns nil' do
...@@ -884,7 +839,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do ...@@ -884,7 +839,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end end
describe '#find_runner_from_token' do describe '#find_runner_from_token' do
let_it_be(:runner) { create(:ci_runner) } let_it_be(:runner, freeze: true) { create(:ci_runner) }
context 'with API requests' do context 'with API requests' do
before do before do
......
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