2016-06-02 11:05:42 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
describe Gitlab::Middleware::Go do
|
2016-06-02 11:05:42 +05:30
|
|
|
let(:app) { double(:app) }
|
|
|
|
let(:middleware) { described_class.new(app) }
|
2018-03-27 19:54:05 +05:30
|
|
|
let(:env) do
|
|
|
|
{
|
|
|
|
'rack.input' => '',
|
|
|
|
'REQUEST_METHOD' => 'GET'
|
|
|
|
}
|
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
|
|
|
|
describe '#call' do
|
|
|
|
describe 'when go-get=0' do
|
2018-03-27 19:54:05 +05:30
|
|
|
before do
|
|
|
|
env['QUERY_STRING'] = 'go-get=0'
|
|
|
|
end
|
|
|
|
|
2016-06-02 11:05:42 +05:30
|
|
|
it 'skips go-import generation' do
|
|
|
|
expect(app).to receive(:call).with(env).and_return('no-go')
|
|
|
|
middleware.call(env)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'when go-get=1' do
|
2018-03-27 19:54:05 +05:30
|
|
|
before do
|
|
|
|
env['QUERY_STRING'] = 'go-get=1'
|
|
|
|
env['PATH_INFO'] = "/#{path}"
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
shared_examples 'go-get=1' do |enabled_protocol:|
|
|
|
|
context 'with simple 2-segment project path' do
|
|
|
|
let!(:project) { create(:project, :private) }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with subpackages' do
|
|
|
|
let(:path) { "#{project.full_path}/subpackage" }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
it 'returns the full project path' do
|
|
|
|
expect_response_with_path(go, enabled_protocol, project.full_path)
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'without subpackages' do
|
|
|
|
let(:path) { project.full_path }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
it 'returns the full project path' do
|
2018-03-17 18:26:18 +05:30
|
|
|
expect_response_with_path(go, enabled_protocol, project.full_path)
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with a nested project path' do
|
|
|
|
let(:group) { create(:group, :nested) }
|
|
|
|
let!(:project) { create(:project, :public, namespace: group) }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
shared_examples 'a nested project' do
|
|
|
|
context 'when the project is public' do
|
|
|
|
it 'returns the full project path' do
|
|
|
|
expect_response_with_path(go, enabled_protocol, project.full_path)
|
|
|
|
end
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'when the project is private' do
|
2017-08-17 22:00:37 +05:30
|
|
|
before do
|
2018-03-17 18:26:18 +05:30
|
|
|
project.update_attribute(:visibility_level, Project::PRIVATE)
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
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
|
2018-03-17 18:26:18 +05:30
|
|
|
let(:current_user) { project.creator }
|
|
|
|
|
|
|
|
before do
|
2018-11-18 11:00:15 +05:30
|
|
|
project.team.add_maintainer(current_user)
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
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
|
|
|
|
before do
|
|
|
|
project.team.find_member(current_user).destroy
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'unauthorized'
|
|
|
|
end
|
|
|
|
|
2019-02-13 22:33:31 +05:30
|
|
|
context 'with user is blocked' do
|
2018-03-27 19:54:05 +05:30
|
|
|
before do
|
2019-02-13 22:33:31 +05:30
|
|
|
current_user.block
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'unauthorized'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-13 22:33:31 +05:30
|
|
|
context 'using basic auth' do
|
|
|
|
context 'using a personal access token' do
|
|
|
|
let(:personal_access_token) { create(:personal_access_token, user: current_user) }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
before do
|
2019-02-13 22:33:31 +05:30
|
|
|
env['REMOTE_ADDR'] = "192.168.0.1"
|
|
|
|
env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(current_user.username, personal_access_token.token)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
2019-02-13 22:33:31 +05:30
|
|
|
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
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with subpackages' do
|
|
|
|
let(:path) { "#{project.full_path}/subpackage" }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
it_behaves_like 'a nested project'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a subpackage that is not a valid project path' do
|
|
|
|
let(:path) { "#{project.full_path}/---subpackage" }
|
|
|
|
|
|
|
|
it_behaves_like 'a nested project'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'without subpackages' do
|
|
|
|
let(:path) { project.full_path }
|
|
|
|
|
|
|
|
it_behaves_like 'a nested project'
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with a bogus path' do
|
|
|
|
let(:path) { "http:;url=http://www.example.com'http-equiv='refresh'x='?go-get=1" }
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
it 'skips go-import generation' do
|
|
|
|
expect(app).to receive(:call).and_return('no-go')
|
|
|
|
|
|
|
|
go
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with SSH disabled' do
|
|
|
|
before do
|
|
|
|
stub_application_setting(enabled_git_access_protocol: 'http')
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
include_examples 'go-get=1', enabled_protocol: :http
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with HTTP disabled' do
|
|
|
|
before do
|
|
|
|
stub_application_setting(enabled_git_access_protocol: 'ssh')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
include_examples 'go-get=1', enabled_protocol: :ssh
|
2016-06-02 11:05:42 +05:30
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with nothing disabled' do
|
|
|
|
before do
|
|
|
|
stub_application_setting(enabled_git_access_protocol: nil)
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
include_examples 'go-get=1', enabled_protocol: nil
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
context 'with nothing disabled (blank string)' do
|
|
|
|
before do
|
|
|
|
stub_application_setting(enabled_git_access_protocol: '')
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
include_examples 'go-get=1', enabled_protocol: nil
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
def go
|
|
|
|
middleware.call(env)
|
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
def expect_response_with_path(response, protocol, path)
|
|
|
|
repository_url = case protocol
|
|
|
|
when :ssh
|
|
|
|
"ssh://git@#{Gitlab.config.gitlab.host}/#{path}.git"
|
|
|
|
when :http, nil
|
|
|
|
"http://#{Gitlab.config.gitlab.host}/#{path}.git"
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
expect(response[0]).to eq(200)
|
|
|
|
expect(response[1]['Content-Type']).to eq('text/html')
|
2018-03-17 18:26:18 +05:30
|
|
|
expected_body = %{<html><head><meta name="go-import" content="#{Gitlab.config.gitlab.host}/#{path} git #{repository_url}" /></head></html>}
|
2017-08-17 22:00:37 +05:30
|
|
|
expect(response[2].body).to eq([expected_body])
|
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
end
|
|
|
|
end
|