spec/gitlab_shell_custom_git_upload_pack_spec.rb
require_relative 'spec_helper'
require 'open3'
require 'json'
require 'base64'
describe 'Custom bin/gitlab-shell git-upload-pack' do
include_context 'gitlab shell'
let(:env) { {'SSH_CONNECTION' => 'fake', 'SSH_ORIGINAL_COMMAND' => 'git-upload-pack group/repo' } }
let(:divider) { "remote: ========================================================================\n" }
before(:context) do
write_config("gitlab_url" => "http+unix://#{CGI.escape(tmp_socket_path)}")
end
def mock_server(server)
server.mount_proc('/geo/proxy_git_ssh/info_refs_upload_pack') do |req, res|
res.content_type = 'application/json'
res.status = 200
res.body = {"result" => "#{Base64.encode64('custom')}"}.to_json
end
server.mount_proc('/geo/proxy_git_ssh/upload_pack') do |req, res|
res.content_type = 'application/json'
res.status = 200
output = JSON.parse(req.body)['output']
res.body = {"result" => output}.to_json
end
server.mount_proc('/api/v4/internal/allowed') do |req, res|
res.content_type = 'application/json'
key_id = req.query['key_id'] || req.query['username']
unless key_id
body = JSON.parse(req.body)
key_id = body['key_id'] || body['username'].to_s
end
case key_id
when '100', 'someone' then
res.status = 300
body = {
"gl_id" => "user-100",
"status" => true,
"payload" => {
"action" => "geo_proxy_to_primary",
"data" => {
"api_endpoints" => ["/geo/proxy_git_ssh/info_refs_upload_pack", "/geo/proxy_git_ssh/upload_pack"],
"gl_username" => "custom",
"primary_repo" => "https://repo/path"
},
},
"gl_console_messages" => ["console", "message"]
}
res.body = body.to_json
else
res.status = 403
end
end
end
describe 'dialog for performing a custom action' do
context 'when API calls perform successfully' do
let(:remote_blank_line) { "remote: \n" }
def verify_successful_call!(cmd)
Open3.popen3(env, cmd) do |stdin, stdout, stderr|
expect(stderr.gets).to eq(remote_blank_line)
expect(stderr.gets).to eq("remote: console\n")
expect(stderr.gets).to eq("remote: message\n")
expect(stderr.gets).to eq(remote_blank_line)
stdin.puts("0032want 343d70886785dc1f98aaf70f3b4ca87c93a5d0dd\n")
stdin.close
expect(stdout.gets(6)).to eq("custom")
expect(stdout.flush.read).to eq("0032want 343d70886785dc1f98aaf70f3b4ca87c93a5d0dd\n")
end
end
context 'when key is provided' do
let(:cmd) { "#{gitlab_shell_path} key-100" }
it 'custom action is performed' do
verify_successful_call!(cmd)
end
end
context 'when username is provided' do
let(:cmd) { "#{gitlab_shell_path} username-someone" }
it 'custom action is performed' do
verify_successful_call!(cmd)
end
end
end
context 'when API error occurs' do
let(:cmd) { "#{gitlab_shell_path} key-101" }
it 'custom action is not performed' do
Open3.popen2e(env, cmd) do |stdin, stdout|
expect(stdout.gets).to eq("remote: \n")
expect(stdout.gets).to eq(divider)
expect(stdout.gets).to eq("remote: \n")
expect(stdout.gets).to eq("remote: Internal API error (403)\n")
expect(stdout.gets).to eq("remote: \n")
expect(stdout.gets).to eq(divider)
expect(stdout.gets).to eq("remote: \n")
end
end
end
end
end