Commit 4eb3821e authored by Ash McKenzie's avatar Ash McKenzie

Merge branch...

Merge branch '22465-rack-attack-authenticate-runner-requests-with-job-token-basic-auth' into 'master'

Auth requests with job token as auth header

See merge request gitlab-org/gitlab!21562
parents 47b10c4c 0f9e1f3b
---
title: Authenticate requests with job token as basic auth header for request limiting
merge_request: 21562
author:
type: fixed
......@@ -21,6 +21,7 @@ module Gitlab
prepend_if_ee('::EE::Gitlab::Auth::AuthFinders') # rubocop: disable Cop/InjectEnterpriseEditionModule
include Gitlab::Utils::StrongMemoize
include ActionController::HttpAuthentication::Basic
PRIVATE_TOKEN_HEADER = 'HTTP_PRIVATE_TOKEN'
PRIVATE_TOKEN_PARAM = :private_token
......@@ -67,6 +68,19 @@ module Gitlab
job.user
end
def find_user_from_basic_auth_job
return unless has_basic_credentials?(current_request)
login, password = user_name_and_password(current_request)
return unless login.present? && password.present?
return unless ::Ci::Build::CI_REGISTRY_USER == login
job = ::Ci::Build.find_by_token(password)
raise UnauthorizedError unless job
job.user
end
# We only allow Private Access Tokens with `api` scope to be used by web
# requests on RSS feeds or ICS files for backwards compatibility.
# It is also used by GraphQL/API requests.
......
......@@ -32,7 +32,8 @@ module Gitlab
def find_sessionless_user(request_format)
find_user_from_web_access_token(request_format) ||
find_user_from_feed_token(request_format) ||
find_user_from_static_object_token(request_format)
find_user_from_static_object_token(request_format) ||
find_user_from_basic_auth_job
rescue Gitlab::Auth::AuthenticationError
nil
end
......
......@@ -335,6 +335,72 @@ describe Gitlab::Auth::AuthFinders do
end
end
describe '#find_user_from_basic_auth_job' do
def basic_http_auth(username, password)
ActionController::HttpAuthentication::Basic.encode_credentials(username, password)
end
def set_auth(username, password)
env['HTTP_AUTHORIZATION'] = basic_http_auth(username, password)
end
subject { find_user_from_basic_auth_job }
context 'when the request does not have AUTHORIZATION header' do
it { is_expected.to be_nil }
end
context 'with wrong credentials' do
it 'returns nil without user and password' do
set_auth(nil, nil)
is_expected.to be_nil
end
it 'returns nil without password' do
set_auth('some-user', nil)
is_expected.to be_nil
end
it 'returns nil without user' do
set_auth(nil, 'password')
is_expected.to be_nil
end
it 'returns nil without CI username' do
set_auth('user', 'password')
is_expected.to be_nil
end
end
context 'with CI username' do
let(:username) { ::Ci::Build::CI_REGISTRY_USER }
let(:user) { create(:user) }
let(:build) { create(:ci_build, user: user) }
it 'returns nil without password' do
set_auth(username, nil)
is_expected.to be_nil
end
it 'returns user with valid token' do
set_auth(username, build.token)
is_expected.to eq user
end
it 'raises error with invalid token' do
set_auth(username, 'token')
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
end
end
describe '#validate_access_token!' do
let(:personal_access_token) { create(:personal_access_token, user: user) }
......
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