Commit 5c158002 authored by Nick Thomas's avatar Nick Thomas

Merge branch 'add-protocol-v2-logic' into 'master'

Add Git protocol v2

See merge request gitlab-org/gitlab-shell!217
parents e3fead94 66e00351
v8.0.0 v8.0.0
- SSH certificate support (!207) - SSH certificate support (!207)
- Support Git v2 protocol (!217)
v7.2.0 v7.2.0
- Update gitaly-proto to 0.109.0 (!216) - Update gitaly-proto to 0.109.0 (!216)
......
require 'json' require 'json'
class GitAccessStatus class GitAccessStatus
attr_reader :message, :gl_repository, :gl_id, :gl_username, :repository_path, :gitaly attr_reader :message, :gl_repository, :gl_id, :gl_username, :repository_path, :gitaly, :git_protocol
def initialize(status, message, gl_repository:, gl_id:, gl_username:, repository_path:, gitaly:) def initialize(status, message, gl_repository:, gl_id:, gl_username:, repository_path:, gitaly:, git_protocol:)
@status = status @status = status
@message = message @message = message
@gl_repository = gl_repository @gl_repository = gl_repository
...@@ -11,6 +11,7 @@ class GitAccessStatus ...@@ -11,6 +11,7 @@ class GitAccessStatus
@gl_username = gl_username @gl_username = gl_username
@repository_path = repository_path @repository_path = repository_path
@gitaly = gitaly @gitaly = gitaly
@git_protocol = git_protocol
end end
def self.create_from_json(json) def self.create_from_json(json)
...@@ -21,7 +22,8 @@ class GitAccessStatus ...@@ -21,7 +22,8 @@ class GitAccessStatus
gl_id: values["gl_id"], gl_id: values["gl_id"],
gl_username: values["gl_username"], gl_username: values["gl_username"],
repository_path: values["repository_path"], repository_path: values["repository_path"],
gitaly: values["gitaly"]) gitaly: values["gitaly"],
git_protocol: values["git_protocol"])
end end
def allowed? def allowed?
......
...@@ -44,7 +44,8 @@ class GitlabNet # rubocop:disable Metrics/ClassLength ...@@ -44,7 +44,8 @@ class GitlabNet # rubocop:disable Metrics/ClassLength
gl_id: nil, gl_id: nil,
gl_username: nil, gl_username: nil,
repository_path: nil, repository_path: nil,
gitaly: nil) gitaly: nil,
git_protocol: nil)
end end
end end
......
...@@ -18,7 +18,7 @@ class GitlabShell # rubocop:disable Metrics/ClassLength ...@@ -18,7 +18,7 @@ class GitlabShell # rubocop:disable Metrics/ClassLength
API_COMMANDS = %w(2fa_recovery_codes).freeze API_COMMANDS = %w(2fa_recovery_codes).freeze
GL_PROTOCOL = 'ssh'.freeze GL_PROTOCOL = 'ssh'.freeze
attr_accessor :gl_id, :gl_repository, :repo_name, :command, :git_access attr_accessor :gl_id, :gl_repository, :repo_name, :command, :git_access, :git_protocol
attr_reader :repo_path attr_reader :repo_path
def initialize(who) def initialize(who)
...@@ -118,6 +118,7 @@ class GitlabShell # rubocop:disable Metrics/ClassLength ...@@ -118,6 +118,7 @@ class GitlabShell # rubocop:disable Metrics/ClassLength
self.repo_path = status.repository_path self.repo_path = status.repository_path
@gl_repository = status.gl_repository @gl_repository = status.gl_repository
@git_protocol = ENV['GIT_PROTOCOL']
@gitaly = status.gitaly @gitaly = status.gitaly
@username = status.gl_username @username = status.gl_username
if defined?(@who) if defined?(@who)
...@@ -150,7 +151,8 @@ class GitlabShell # rubocop:disable Metrics/ClassLength ...@@ -150,7 +151,8 @@ class GitlabShell # rubocop:disable Metrics/ClassLength
'repository' => @gitaly['repository'], 'repository' => @gitaly['repository'],
'gl_repository' => @gl_repository, 'gl_repository' => @gl_repository,
'gl_id' => @gl_id, 'gl_id' => @gl_id,
'gl_username' => @username 'gl_username' => @username,
'git_protocol' => @git_protocol
} }
args = [gitaly_address, JSON.dump(gitaly_request)] args = [gitaly_address, JSON.dump(gitaly_request)]
......
...@@ -13,7 +13,8 @@ describe GitlabAccess do ...@@ -13,7 +13,8 @@ describe GitlabAccess do
gl_id: 'user-123', gl_id: 'user-123',
gl_username: 'testuser', gl_username: 'testuser',
repository_path: '/home/git/repositories', repository_path: '/home/git/repositories',
gitaly: nil)) gitaly: nil,
git_protocol: 'version=2'))
end end
end end
subject do subject do
...@@ -35,14 +36,12 @@ describe GitlabAccess do ...@@ -35,14 +36,12 @@ describe GitlabAccess do
describe "#exec" do describe "#exec" do
context "access is granted" do context "access is granted" do
it "returns true" do it "returns true" do
expect(subject.exec).to be_truthy expect(subject.exec).to be_truthy
end end
end end
context "access is denied" do context "access is denied" do
before do before do
api.stub(check_access: GitAccessStatus.new( api.stub(check_access: GitAccessStatus.new(
false, false,
...@@ -51,7 +50,8 @@ describe GitlabAccess do ...@@ -51,7 +50,8 @@ describe GitlabAccess do
gl_id: nil, gl_id: nil,
gl_username: nil, gl_username: nil,
repository_path: nil, repository_path: nil,
gitaly: nil gitaly: nil,
git_protocol: nil
)) ))
end end
...@@ -61,7 +61,6 @@ describe GitlabAccess do ...@@ -61,7 +61,6 @@ describe GitlabAccess do
end end
context "API connection fails" do context "API connection fails" do
before do before do
api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError) api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
end end
......
...@@ -27,7 +27,8 @@ describe GitlabShell do ...@@ -27,7 +27,8 @@ describe GitlabShell do
gl_id: gl_id, gl_id: gl_id,
gl_username: gl_username, gl_username: gl_username,
repository_path: repo_path, repository_path: repo_path,
gitaly: { 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default'} , 'address' => 'unix:gitaly.socket' } gitaly: { 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default'} , 'address' => 'unix:gitaly.socket' },
git_protocol: git_protocol
) )
} }
...@@ -41,10 +42,11 @@ describe GitlabShell do ...@@ -41,10 +42,11 @@ describe GitlabShell do
gl_id: gl_id, gl_id: gl_id,
gl_username: gl_username, gl_username: gl_username,
repository_path: repo_path, repository_path: repo_path,
gitaly: nil)) gitaly: nil,
git_protocol: git_protocol))
api.stub(two_factor_recovery_codes: { api.stub(two_factor_recovery_codes: {
'success' => true, 'success' => true,
'recovery_codes' => ['f67c514de60c4953', '41278385fc00c1e0'] 'recovery_codes' => %w[f67c514de60c4953 41278385fc00c1e0]
}) })
end end
end end
...@@ -58,6 +60,7 @@ describe GitlabShell do ...@@ -58,6 +60,7 @@ describe GitlabShell do
let(:gl_repository) { 'project-1' } let(:gl_repository) { 'project-1' }
let(:gl_id) { 'user-1' } let(:gl_id) { 'user-1' }
let(:gl_username) { 'testuser' } let(:gl_username) { 'testuser' }
let(:git_protocol) { 'version=2' }
before do before do
GitlabConfig.any_instance.stub(audit_usernames: false) GitlabConfig.any_instance.stub(audit_usernames: false)
...@@ -72,7 +75,7 @@ describe GitlabShell do ...@@ -72,7 +75,7 @@ describe GitlabShell do
describe :parse_cmd do describe :parse_cmd do
describe 'git' do describe 'git' do
context 'w/o namespace' do context 'w/o namespace' do
let(:ssh_args) { %W(git-upload-pack gitlab-ci.git) } let(:ssh_args) { %w(git-upload-pack gitlab-ci.git) }
before do before do
subject.send :parse_cmd, ssh_args subject.send :parse_cmd, ssh_args
...@@ -84,7 +87,7 @@ describe GitlabShell do ...@@ -84,7 +87,7 @@ describe GitlabShell do
context 'namespace' do context 'namespace' do
let(:repo_name) { 'dmitriy.zaporozhets/gitlab-ci.git' } let(:repo_name) { 'dmitriy.zaporozhets/gitlab-ci.git' }
let(:ssh_args) { %W(git-upload-pack dmitriy.zaporozhets/gitlab-ci.git) } let(:ssh_args) { %w(git-upload-pack dmitriy.zaporozhets/gitlab-ci.git) }
before do before do
subject.send :parse_cmd, ssh_args subject.send :parse_cmd, ssh_args
...@@ -95,7 +98,7 @@ describe GitlabShell do ...@@ -95,7 +98,7 @@ describe GitlabShell do
end end
context 'with an invalid number of arguments' do context 'with an invalid number of arguments' do
let(:ssh_args) { %W(foobar) } let(:ssh_args) { %w(foobar) }
it "should raise an DisallowedCommandError" do it "should raise an DisallowedCommandError" do
expect { subject.send :parse_cmd, ssh_args }.to raise_error(GitlabShell::DisallowedCommandError) expect { subject.send :parse_cmd, ssh_args }.to raise_error(GitlabShell::DisallowedCommandError)
...@@ -123,7 +126,7 @@ describe GitlabShell do ...@@ -123,7 +126,7 @@ describe GitlabShell do
describe 'git-lfs' do describe 'git-lfs' do
let(:repo_name) { 'dzaporozhets/gitlab.git' } let(:repo_name) { 'dzaporozhets/gitlab.git' }
let(:ssh_args) { %W(git-lfs-authenticate dzaporozhets/gitlab.git download) } let(:ssh_args) { %w(git-lfs-authenticate dzaporozhets/gitlab.git download) }
before do before do
subject.send :parse_cmd, ssh_args subject.send :parse_cmd, ssh_args
...@@ -136,7 +139,7 @@ describe GitlabShell do ...@@ -136,7 +139,7 @@ describe GitlabShell do
describe 'git-lfs old clients' do describe 'git-lfs old clients' do
let(:repo_name) { 'dzaporozhets/gitlab.git' } let(:repo_name) { 'dzaporozhets/gitlab.git' }
let(:ssh_args) { %W(git-lfs-authenticate dzaporozhets/gitlab.git download long_oid) } let(:ssh_args) { %w(git-lfs-authenticate dzaporozhets/gitlab.git download long_oid) }
before do before do
subject.send :parse_cmd, ssh_args subject.send :parse_cmd, ssh_args
...@@ -149,14 +152,26 @@ describe GitlabShell do ...@@ -149,14 +152,26 @@ describe GitlabShell do
end end
describe :exec do describe :exec do
let(:gitaly_message) { JSON.dump({ 'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default' }, 'gl_repository' => gl_repository, 'gl_id' => gl_id, 'gl_username' => gl_username}) } let(:gitaly_message) do
JSON.dump(
'repository' => { 'relative_path' => repo_name, 'storage_name' => 'default' },
'gl_repository' => gl_repository,
'gl_id' => gl_id,
'gl_username' => gl_username,
'git_protocol' => git_protocol
)
end
before do
allow(ENV).to receive(:[]).with('GIT_PROTOCOL').and_return(git_protocol)
end
shared_examples_for 'upload-pack' do |command| shared_examples_for 'upload-pack' do |command|
let(:ssh_cmd) { "#{command} gitlab-ci.git" } let(:ssh_cmd) { "#{command} gitlab-ci.git" }
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should process the command" do it "should process the command" do
subject.should_receive(:process_cmd).with(%W(git-upload-pack gitlab-ci.git)) subject.should_receive(:process_cmd).with(%w(git-upload-pack gitlab-ci.git))
end end
it "should execute the command" do it "should execute the command" do
...@@ -185,13 +200,13 @@ describe GitlabShell do ...@@ -185,13 +200,13 @@ describe GitlabShell do
context 'gitaly-upload-pack' do context 'gitaly-upload-pack' do
let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" } let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" }
before { before do
api.stub(check_access: gitaly_check_access) api.stub(check_access: gitaly_check_access)
} end
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should process the command" do it "should process the command" do
subject.should_receive(:process_cmd).with(%W(git-upload-pack gitlab-ci.git)) subject.should_receive(:process_cmd).with(%w(git-upload-pack gitlab-ci.git))
end end
it "should execute the command" do it "should execute the command" do
...@@ -215,7 +230,7 @@ describe GitlabShell do ...@@ -215,7 +230,7 @@ describe GitlabShell do
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should process the command" do it "should process the command" do
subject.should_receive(:process_cmd).with(%W(git-receive-pack gitlab-ci.git)) subject.should_receive(:process_cmd).with(%w(git-receive-pack gitlab-ci.git))
end end
it "should execute the command" do it "should execute the command" do
...@@ -231,13 +246,13 @@ describe GitlabShell do ...@@ -231,13 +246,13 @@ describe GitlabShell do
context 'gitaly-receive-pack' do context 'gitaly-receive-pack' do
let(:ssh_cmd) { "git-receive-pack gitlab-ci.git" } let(:ssh_cmd) { "git-receive-pack gitlab-ci.git" }
before { before do
api.stub(check_access: gitaly_check_access) api.stub(check_access: gitaly_check_access)
} end
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should process the command" do it "should process the command" do
subject.should_receive(:process_cmd).with(%W(git-receive-pack gitlab-ci.git)) subject.should_receive(:process_cmd).with(%w(git-receive-pack gitlab-ci.git))
end end
it "should execute the command" do it "should execute the command" do
...@@ -264,7 +279,7 @@ describe GitlabShell do ...@@ -264,7 +279,7 @@ describe GitlabShell do
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should process the command" do it "should process the command" do
subject.should_receive(:process_cmd).with(%W(git-upload-archive gitlab-ci.git)) subject.should_receive(:process_cmd).with(%w(git-upload-archive gitlab-ci.git))
end end
it "should execute the command" do it "should execute the command" do
...@@ -341,9 +356,9 @@ describe GitlabShell do ...@@ -341,9 +356,9 @@ describe GitlabShell do
context "failed connection" do context "failed connection" do
let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' } let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' }
before { before do
api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError) api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
} end
after { subject.exec(ssh_cmd) } after { subject.exec(ssh_cmd) }
it "should not process the command" do it "should not process the command" do
...@@ -412,7 +427,8 @@ describe GitlabShell do ...@@ -412,7 +427,8 @@ describe GitlabShell do
gl_id: nil, gl_id: nil,
gl_username: nil, gl_username: nil,
repository_path: nil, repository_path: nil,
gitaly: nil)) gitaly: nil,
git_protocol: nil))
message = 'Access denied' message = 'Access denied'
user_string = "user with id #{gl_id}" user_string = "user with id #{gl_id}"
$logger.should_receive(:warn).with(message, command: 'git-upload-pack gitlab-ci.git', user: user_string) $logger.should_receive(:warn).with(message, command: 'git-upload-pack gitlab-ci.git', user: user_string)
...@@ -457,6 +473,7 @@ describe GitlabShell do ...@@ -457,6 +473,7 @@ describe GitlabShell do
before do before do
Kernel.stub(:exec) Kernel.stub(:exec)
shell.gl_repository = gl_repository shell.gl_repository = gl_repository
shell.git_protocol = git_protocol
shell.instance_variable_set(:@username, gl_username) shell.instance_variable_set(:@username, gl_username)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment