Merge branch 'dm-go-get-api-token' into 'master'

Allow token authentication on go-get request

Closes #42817

See merge request gitlab-org/gitlab-ce!17148
This commit is contained in:
Nick Thomas 2018-02-23 10:33:47 +00:00
commit 58a312f509
4 changed files with 98 additions and 18 deletions

View file

@ -0,0 +1,5 @@
---
title: Allow token authentication on go-get request
merge_request:
author:
type: changed

View file

@ -20,6 +20,14 @@ module Gitlab
rescue Gitlab::Auth::AuthenticationError
nil
end
def valid_access_token?(scopes: [])
validate_access_token!(scopes: scopes)
true
rescue Gitlab::Auth::AuthenticationError
false
end
end
end
end

View file

@ -114,7 +114,15 @@ module Gitlab
end
def current_user(request)
request.env['warden']&.authenticate
authenticator = Gitlab::Auth::RequestAuthenticator.new(request)
user = authenticator.find_user_from_access_token || authenticator.find_user_from_warden
return unless user&.can?(:access_api)
# Right now, the `api` scope is the only one that should be able to determine private project existence.
return unless authenticator.valid_access_token?(scopes: [:api])
user
end
end
end

View file

@ -3,19 +3,30 @@ require 'spec_helper'
describe Gitlab::Middleware::Go do
let(:app) { double(:app) }
let(:middleware) { described_class.new(app) }
let(:env) do
{
'rack.input' => '',
'REQUEST_METHOD' => 'GET'
}
end
describe '#call' do
describe 'when go-get=0' do
before do
env['QUERY_STRING'] = 'go-get=0'
end
it 'skips go-import generation' do
env = { 'rack.input' => '',
'QUERY_STRING' => 'go-get=0' }
expect(app).to receive(:call).with(env).and_return('no-go')
middleware.call(env)
end
end
describe 'when go-get=1' do
let(:current_user) { nil }
before do
env['QUERY_STRING'] = 'go-get=1'
env['PATH_INFO'] = "/#{path}"
end
shared_examples 'go-get=1' do |enabled_protocol:|
context 'with simple 2-segment project path' do
@ -54,21 +65,75 @@ describe Gitlab::Middleware::Go do
project.update_attribute(:visibility_level, Project::PRIVATE)
end
context 'with access to the project' do
shared_examples 'unauthorized' do
it 'returns the 2-segment group path' do
expect_response_with_path(go, enabled_protocol, group.full_path)
end
end
context 'when not authenticated' do
it_behaves_like 'unauthorized'
end
context 'when authenticated' do
let(:current_user) { project.creator }
before do
project.team.add_master(current_user)
end
shared_examples 'authenticated' do
context 'with access to the project' do
it 'returns the full project path' do
expect_response_with_path(go, enabled_protocol, project.full_path)
end
end
context 'without access to the project' do
it 'returns the 2-segment group path' do
expect_response_with_path(go, enabled_protocol, group.full_path)
before do
project.team.find_member(current_user).destroy
end
it_behaves_like 'unauthorized'
end
end
context 'using warden' do
before do
env['warden'] = double(authenticate: current_user)
end
context 'when active' do
it_behaves_like 'authenticated'
end
context 'when blocked' do
before do
current_user.block!
end
it_behaves_like 'unauthorized'
end
end
context 'using a personal access token' do
let(:personal_access_token) { create(:personal_access_token, user: current_user) }
before do
env['HTTP_PRIVATE_TOKEN'] = personal_access_token.token
end
context 'with api scope' do
it_behaves_like 'authenticated'
end
context 'with read_user scope' do
before do
personal_access_token.update_attribute(:scopes, [:read_user])
end
it_behaves_like 'unauthorized'
end
end
end
end
@ -138,12 +203,6 @@ describe Gitlab::Middleware::Go do
end
def go
env = {
'rack.input' => '',
'QUERY_STRING' => 'go-get=1',
'PATH_INFO' => "/#{path}",
'warden' => double(authenticate: current_user)
}
middleware.call(env)
end