debian-mirror-gitlab/spec/lib/gitlab/middleware/go_spec.rb

286 lines
9.9 KiB
Ruby
Raw Normal View History

2020-01-01 13:55:28 +05:30
# frozen_string_literal: true
2016-06-02 11:05:42 +05:30
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec.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'
2020-01-01 13:55:28 +05:30
env['PATH_INFO'] = +"/#{path}"
2018-03-27 19:54:05 +05:30
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
2020-01-01 13:55:28 +05:30
let!(:project) { create(:project, :private, :repository) }
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
2020-01-01 13:55:28 +05:30
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
2018-03-17 18:26:18 +05:30
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
2020-01-01 13:55:28 +05:30
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
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) }
2020-01-01 13:55:28 +05:30
let!(:project) { create(:project, :public, :repository, 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
2020-01-01 13:55:28 +05:30
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
2018-03-17 18:26:18 +05:30
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
2020-01-01 13:55:28 +05:30
expect_response_with_path(go, enabled_protocol, group.full_path, project.default_branch)
2018-03-27 19:54:05 +05:30
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
2020-01-01 13:55:28 +05:30
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
2018-03-27 19:54:05 +05:30
end
2020-04-08 14:13:33 +05:30
context 'with an empty ssh_user' do
it 'returns the full project path' do
allow(Gitlab.config.gitlab_shell).to receive(:ssh_user).and_return('')
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
end
end
2018-03-27 19:54:05 +05:30
end
2021-11-18 22:05:49 +05:30
context 'without access to the project', :sidekiq_inline do
2018-03-27 19:54:05 +05:30
before do
project.team.find_member(current_user).destroy
end
it_behaves_like 'unauthorized'
end
2019-02-15 15:39:39 +05:30
context 'with user is blocked' do
2018-03-27 19:54:05 +05:30
before do
2019-02-15 15:39:39 +05:30
current_user.block
2018-03-27 19:54:05 +05:30
end
it_behaves_like 'unauthorized'
end
end
2019-02-15 15:39:39 +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-15 15:39:39 +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-15 15:39:39 +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
2021-01-03 14:25:43 +05:30
context 'with a blacklisted ip' do
it 'returns forbidden' do
expect(Gitlab::Auth).to receive(:find_for_git_client).and_raise(Gitlab::Auth::IpBlacklisted)
response = go
expect(response[0]).to eq(403)
expect(response[1]['Content-Length']).to be_nil
expect(response[2]).to eq([''])
end
end
2021-12-11 22:18:48 +05:30
end
context 'when a personal access token is missing' do
before do
env['REMOTE_ADDR'] = '192.168.0.1'
env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(current_user.username, 'dummy_password')
end
it 'returns unauthorized' do
expect(Gitlab::Auth).to receive(:find_for_git_client).and_raise(Gitlab::Auth::MissingPersonalAccessTokenError)
response = go
expect(response[0]).to eq(401)
expect(response[1]['Content-Length']).to be_nil
expect(response[2]).to eq([''])
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
2020-01-01 13:55:28 +05:30
context 'with a public project without a repository' do
let!(:project) { create(:project, :public) }
let(:path) { project.full_path }
it 'returns 404' do
response = go
2021-01-03 14:25:43 +05:30
2020-01-01 13:55:28 +05:30
expect(response[0]).to eq(404)
expect(response[1]['Content-Type']).to eq('text/html')
expected_body = %{<html><body>go get #{Gitlab.config.gitlab.url}/#{project.full_path}</body></html>}
2021-01-03 14:25:43 +05:30
expect(response[2]).to eq([expected_body])
2020-01-01 13:55:28 +05:30
end
end
context 'with a non-standard head' do
let(:user) { create(:user) }
let!(:project) { create(:project, :public, :repository) }
let(:path) { project.full_path }
let(:default_branch) { 'default_branch' }
before do
project.add_maintainer(user)
project.repository.add_branch(user, default_branch, 'master')
project.change_head(default_branch)
end
it 'returns the full project path' do
expect_response_with_path(go, enabled_protocol, project.full_path, default_branch)
end
end
2018-03-17 18:26:18 +05:30
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
2020-01-01 13:55:28 +05:30
def expect_response_with_path(response, protocol, path, branch)
2018-03-17 18:26:18 +05:30
repository_url = case protocol
when :ssh
2020-04-08 14:13:33 +05:30
shell = Gitlab.config.gitlab_shell
user = "#{shell.ssh_user}@" unless shell.ssh_user.empty?
"ssh://#{user}#{shell.ssh_host}/#{path}.git"
2018-03-17 18:26:18 +05:30
when :http, nil
"http://#{Gitlab.config.gitlab.host}/#{path}.git"
end
2020-01-01 13:55:28 +05:30
project_url = "http://#{Gitlab.config.gitlab.host}/#{path}"
2017-08-17 22:00:37 +05:30
expect(response[0]).to eq(200)
expect(response[1]['Content-Type']).to eq('text/html')
2020-03-13 15:44:24 +05:30
expected_body = %{<html><head><meta name="go-import" content="#{Gitlab.config.gitlab.host}/#{path} git #{repository_url}" /><meta name="go-source" content="#{Gitlab.config.gitlab.host}/#{path} #{project_url} #{project_url}/-/tree/#{branch}{/dir} #{project_url}/-/blob/#{branch}{/dir}/{file}#L{line}" /></head><body>go get #{Gitlab.config.gitlab.url}/#{path}</body></html>}
2021-01-03 14:25:43 +05:30
expect(response[2]).to eq([expected_body])
2017-08-17 22:00:37 +05:30
end
2016-06-02 11:05:42 +05:30
end
end