Homogenising the type of the request handled by UserAuthFinder. Also tests fixed

This commit is contained in:
Francisco Lopez 2017-11-09 19:04:19 +01:00
parent aecc3eb080
commit 21153a4f47
4 changed files with 32 additions and 29 deletions

View file

@ -6,9 +6,6 @@ module API
module APIGuard module APIGuard
extend ActiveSupport::Concern extend ActiveSupport::Concern
PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN".freeze
PRIVATE_TOKEN_PARAM = :private_token
included do |base| included do |base|
# OAuth2 Resource Server Authentication # OAuth2 Resource Server Authentication
use Rack::OAuth2::Server::Resource::Bearer, 'The API' do |request| use Rack::OAuth2::Server::Resource::Bearer, 'The API' do |request|

View file

@ -7,8 +7,6 @@ module Gitlab
attr_reader :request attr_reader :request
delegate :params, :env, to: :request
def initialize(request) def initialize(request)
@request = request @request = request
end end

View file

@ -6,13 +6,13 @@ module Gitlab
# Check the Rails session for valid authentication details # Check the Rails session for valid authentication details
def find_user_from_warden def find_user_from_warden
env['warden']&.authenticate if verified_request? current_request.env['warden']&.authenticate if verified_request?
end end
def find_user_from_rss_token def find_user_from_rss_token
return unless request.format.atom? return unless current_request.format.atom?
token = params[:rss_token].presence token = current_request.params[:rss_token].presence
return unless token return unless token
handle_return_value!(User.find_by_rss_token(token)) handle_return_value!(User.find_by_rss_token(token))
@ -23,7 +23,7 @@ module Gitlab
validate_access_token! validate_access_token!
handle_return_value!(access_token&.user) handle_return_value!(access_token.user)
end end
def validate_access_token!(scopes: []) def validate_access_token!(scopes: [])
@ -54,8 +54,8 @@ module Gitlab
end end
def private_token def private_token
params[PRIVATE_TOKEN_PARAM].presence || current_request.params[PRIVATE_TOKEN_PARAM].presence ||
env[PRIVATE_TOKEN_HEADER].presence current_request.env[PRIVATE_TOKEN_HEADER].presence
end end
def find_personal_access_token def find_personal_access_token
@ -67,7 +67,6 @@ module Gitlab
end end
def find_oauth_access_token def find_oauth_access_token
current_request = ensure_action_dispatch_request(request)
token = Doorkeeper::OAuth::Token.from_request(current_request, *Doorkeeper.configuration.access_token_methods) token = Doorkeeper::OAuth::Token.from_request(current_request, *Doorkeeper.configuration.access_token_methods)
return unless token return unless token
@ -80,7 +79,7 @@ module Gitlab
# Check if the request is GET/HEAD, or if CSRF token is valid. # Check if the request is GET/HEAD, or if CSRF token is valid.
def verified_request? def verified_request?
Gitlab::RequestForgeryProtection.verified?(request.env) Gitlab::RequestForgeryProtection.verified?(current_request.env)
end end
def ensure_action_dispatch_request(request) def ensure_action_dispatch_request(request)
@ -88,6 +87,10 @@ module Gitlab
ActionDispatch::Request.new(request.env) ActionDispatch::Request.new(request.env)
end end
def current_request
@current_request ||= ensure_action_dispatch_request(request)
end
end end
end end
end end

View file

@ -11,7 +11,6 @@ describe API::Helpers do
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
let(:key) { create(:key, user: user) } let(:key) { create(:key, user: user) }
let(:params) { {} }
let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) } let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) }
let(:env) do let(:env) do
{ {
@ -19,11 +18,13 @@ describe API::Helpers do
'rack.session' => { 'rack.session' => {
_csrf_token: csrf_token _csrf_token: csrf_token
}, },
'REQUEST_METHOD' => 'GET' 'REQUEST_METHOD' => 'GET',
'CONTENT_TYPE' => 'text/plain;charset=utf-8'
} }
end end
let(:header) { } let(:header) { }
let(:request) { Grape::Request.new(env)} let(:request) { Grape::Request.new(env)}
let(:params) { request.params }
before do before do
allow_any_instance_of(self.class).to receive(:options).and_return({}) allow_any_instance_of(self.class).to receive(:options).and_return({})
@ -38,6 +39,10 @@ describe API::Helpers do
raise Exception.new("#{status} - #{message}") raise Exception.new("#{status} - #{message}")
end end
def set_param(key, value)
request.update_param(key, value)
end
describe ".current_user" do describe ".current_user" do
subject { current_user } subject { current_user }
@ -133,13 +138,13 @@ describe API::Helpers do
let(:personal_access_token) { create(:personal_access_token, user: user) } let(:personal_access_token) { create(:personal_access_token, user: user) }
it "returns a 401 response for an invalid token" do it "returns a 401 response for an invalid token" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = 'invalid token' env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = 'invalid token'
expect { current_user }.to raise_error /401/ expect { current_user }.to raise_error /401/
end end
it "returns a 403 response for a user without access" do it "returns a 403 response for a user without access" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false) allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect { current_user }.to raise_error /403/ expect { current_user }.to raise_error /403/
@ -147,33 +152,33 @@ describe API::Helpers do
it 'returns a 403 response for a user who is blocked' do it 'returns a 403 response for a user who is blocked' do
user.block! user.block!
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect { current_user }.to raise_error /403/ expect { current_user }.to raise_error /403/
end end
it "sets current_user" do it "sets current_user" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect(current_user).to eq(user) expect(current_user).to eq(user)
end end
it "does not allow tokens without the appropriate scope" do it "does not allow tokens without the appropriate scope" do
personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user']) personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user'])
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect { current_user }.to raise_error API::APIGuard::InsufficientScopeError expect { current_user }.to raise_error API::APIGuard::InsufficientScopeError
end end
it 'does not allow revoked tokens' do it 'does not allow revoked tokens' do
personal_access_token.revoke! personal_access_token.revoke!
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect { current_user }.to raise_error API::APIGuard::RevokedError expect { current_user }.to raise_error API::APIGuard::RevokedError
end end
it 'does not allow expired tokens' do it 'does not allow expired tokens' do
personal_access_token.update_attributes!(expires_at: 1.day.ago) personal_access_token.update_attributes!(expires_at: 1.day.ago)
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect { current_user }.to raise_error API::APIGuard::ExpiredError expect { current_user }.to raise_error API::APIGuard::ExpiredError
end end
@ -351,7 +356,7 @@ describe API::Helpers do
context 'when using param' do context 'when using param' do
context 'when providing username' do context 'when providing username' do
before do before do
params[API::Helpers::SUDO_PARAM] = user.username set_param(API::Helpers::SUDO_PARAM, user.username)
end end
it_behaves_like 'successful sudo' it_behaves_like 'successful sudo'
@ -359,7 +364,7 @@ describe API::Helpers do
context 'when providing user ID' do context 'when providing user ID' do
before do before do
params[API::Helpers::SUDO_PARAM] = user.id.to_s set_param(API::Helpers::SUDO_PARAM, user.id.to_s)
end end
it_behaves_like 'successful sudo' it_behaves_like 'successful sudo'
@ -369,7 +374,7 @@ describe API::Helpers do
context 'when user does not exist' do context 'when user does not exist' do
before do before do
params[API::Helpers::SUDO_PARAM] = 'nonexistent' set_param(API::Helpers::SUDO_PARAM, 'nonexistent')
end end
it 'raises an error' do it 'raises an error' do
@ -383,7 +388,7 @@ describe API::Helpers do
token.scopes = %w[api] token.scopes = %w[api]
token.save! token.save!
params[API::Helpers::SUDO_PARAM] = user.id.to_s set_param(API::Helpers::SUDO_PARAM, user.id.to_s)
end end
it 'raises an error' do it 'raises an error' do
@ -397,7 +402,7 @@ describe API::Helpers do
token.user = user token.user = user
token.save! token.save!
params[API::Helpers::SUDO_PARAM] = user.id.to_s set_param(API::Helpers::SUDO_PARAM, user.id.to_s)
end end
it 'raises an error' do it 'raises an error' do
@ -421,7 +426,7 @@ describe API::Helpers do
context 'passed as param' do context 'passed as param' do
before do before do
params[API::APIGuard::PRIVATE_TOKEN_PARAM] = token.token set_param(Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_PARAM, token.token)
end end
it_behaves_like 'sudo' it_behaves_like 'sudo'
@ -429,7 +434,7 @@ describe API::Helpers do
context 'passed as header' do context 'passed as header' do
before do before do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = token.token env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = token.token
end end
it_behaves_like 'sudo' it_behaves_like 'sudo'