diff options
author | Patricio Cano <suprnova32@gmail.com> | 2016-08-25 17:34:34 -0500 |
---|---|---|
committer | Patricio Cano <suprnova32@gmail.com> | 2016-09-06 12:06:45 -0500 |
commit | dbf374e10ad859a02ef69af53031e245913b6e65 (patch) | |
tree | 304e387c2702db9f9685f8a951ef3d65c60ad09c | |
parent | c6d8af599dc797ec8ba7874380abad393b439c9e (diff) | |
download | gitlab-shell-dbf374e10ad859a02ef69af53031e245913b6e65.tar.gz |
Added LFS support to SSH
- Required changes to GitLab Shell include the actual handling of the `git-lfs-authenticate` command and the retrieval of the correct credentials.
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | lib/gitlab_access_status.rb | 7 | ||||
-rw-r--r-- | lib/gitlab_net.rb | 2 | ||||
-rw-r--r-- | lib/gitlab_shell.rb | 23 | ||||
-rw-r--r-- | spec/gitlab_access_spec.rb | 4 | ||||
-rw-r--r-- | spec/gitlab_net_spec.rb | 3 | ||||
-rw-r--r-- | spec/gitlab_shell_spec.rb | 16 | ||||
-rw-r--r-- | spec/vcr_cassettes/allowed-pull.yml | 2 | ||||
-rw-r--r-- | spec/vcr_cassettes/discover-ok.yml | 2 |
9 files changed, 50 insertions, 10 deletions
@@ -1,5 +1,6 @@ v3.5.0 - Add option to recover 2FA via SSH + - Added full support for `git-lfs-authenticate` to properly handle LFS requests and pass them on to Workhorse v3.4.0 - Redis Sentinel support diff --git a/lib/gitlab_access_status.rb b/lib/gitlab_access_status.rb index 7fb88be..1ae0528 100644 --- a/lib/gitlab_access_status.rb +++ b/lib/gitlab_access_status.rb @@ -1,17 +1,18 @@ require 'json' class GitAccessStatus - attr_reader :message, :repository_path + attr_reader :message, :repository_path, :repository_http_path - def initialize(status, message, repository_path) + def initialize(status, message, repository_path, repository_http_path) @status = status @message = message @repository_path = repository_path + @repository_http_path = repository_http_path end def self.create_from_json(json) values = JSON.parse(json) - self.new(values["status"], values["message"], values["repository_path"]) + self.new(values["status"], values["message"], values["repository_path"], values["repository_http_path"]) end def allowed? diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb index 47bae95..42ff94c 100644 --- a/lib/gitlab_net.rb +++ b/lib/gitlab_net.rb @@ -39,7 +39,7 @@ class GitlabNet if resp.code == '200' GitAccessStatus.create_from_json(resp.body) else - GitAccessStatus.new(false, 'API is not accessible', nil) + GitAccessStatus.new(false, 'API is not accessible', nil, nil) end end diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb index 1fdb9e5..ab98a6e 100644 --- a/lib/gitlab_shell.rb +++ b/lib/gitlab_shell.rb @@ -1,4 +1,6 @@ require 'shellwords' +require 'base64' +require 'json' require_relative 'gitlab_net' @@ -11,7 +13,7 @@ class GitlabShell API_COMMANDS = %w(2fa_recovery_codes) GL_PROTOCOL = 'ssh'.freeze - attr_accessor :key_id, :repo_name, :command + attr_accessor :key_id, :repo_name, :command, :git_access, :repository_http_path attr_reader :repo_path def initialize(key_id) @@ -94,6 +96,7 @@ class GitlabShell raise AccessDeniedError, status.message unless status.allowed? self.repo_path = status.repository_path + @repository_http_path = status.repository_http_path end def process_cmd(args) @@ -117,6 +120,11 @@ class GitlabShell $logger.info "gitlab-shell: executing git-annex command <#{parsed_args.join(' ')}> for #{log_username}." exec_cmd(*parsed_args) + + elsif @command == 'git-lfs-authenticate' + $logger.info "gitlab-shell: Processing LFS authentication for #{log_username}." + lfs_authenticate + else $logger.info "gitlab-shell: executing git command <#{@command} #{repo_path}> for #{log_username}." exec_cmd(@command, repo_path) @@ -184,6 +192,19 @@ class GitlabShell non_dashed[0, 2] == %w{git-annex-shell gcryptsetup} end + def lfs_authenticate + return unless user + + authorization = { + header: { + Authorization: "Basic #{Base64.strict_encode64("#{user['username']}:#{user['lfs_token']}")}" + }, + href: "#{repository_http_path}/info/lfs/" + } + + puts JSON.generate(authorization) + end + private def continue?(question) diff --git a/spec/gitlab_access_spec.rb b/spec/gitlab_access_spec.rb index 2781aa9..e2a0c77 100644 --- a/spec/gitlab_access_spec.rb +++ b/spec/gitlab_access_spec.rb @@ -7,7 +7,7 @@ describe GitlabAccess do let(:repo_path) { File.join(repository_path, repo_name) + ".git" } let(:api) do double(GitlabNet).tap do |api| - api.stub(check_access: GitAccessStatus.new(true, 'ok', '/home/git/repositories')) + api.stub(check_access: GitAccessStatus.new(true, 'ok', '/home/git/repositories', 'http://gitlab.dev/repo')) end end subject do @@ -39,7 +39,7 @@ describe GitlabAccess do context "access is denied" do before do - api.stub(check_access: GitAccessStatus.new(false, 'denied', nil)) + api.stub(check_access: GitAccessStatus.new(false, 'denied', nil, nil)) end it "returns false" do diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb index bcd0d79..cee5b91 100644 --- a/spec/gitlab_net_spec.rb +++ b/spec/gitlab_net_spec.rb @@ -38,6 +38,8 @@ describe GitlabNet, vcr: true do VCR.use_cassette("discover-ok") do user = gitlab_net.discover('key-126') user['name'].should == 'Dmitriy Zaporozhets' + user['lfs_token'].should == 'wsnys8Zm8Jn7zyhHTAAK' + user['username'].should == 'dzaporozhets' end end @@ -130,6 +132,7 @@ describe GitlabNet, vcr: true do VCR.use_cassette("allowed-pull") do access = gitlab_net.check_access('git-receive-pack', 'gitlab/gitlabhq.git', 'key-126', changes, 'ssh') access.allowed?.should be_true + access.repository_http_path.should == 'http://gitlab.dev/gitlab/gitlabhq.git' end end diff --git a/spec/gitlab_shell_spec.rb b/spec/gitlab_shell_spec.rb index ea11652..378b964 100644 --- a/spec/gitlab_shell_spec.rb +++ b/spec/gitlab_shell_spec.rb @@ -36,6 +36,7 @@ describe GitlabShell do let(:repo_name) { 'gitlab-ci.git' } let(:repo_path) { File.join(tmp_repos_path, repo_name) } + let(:repo_http_path) { 'http://gitlab.dev/dzaporozhets/gitlab.git' } before do GitlabConfig.any_instance.stub(audit_usernames: false) @@ -112,6 +113,19 @@ describe GitlabShell do its(:repo_name) { should == 'dzaporozhets/gitlab.git' } its(:command) { should == 'git-annex-shell' } end + + describe 'git-lfs' do + let(:repo_name) { 'dzaporozhets/gitlab.git' } + let(:ssh_args) { %W(git-lfs-authenticate dzaporozhets/gitlab.git download) } + + before do + subject.send :parse_cmd, ssh_args + end + + its(:repo_name) { should == 'dzaporozhets/gitlab.git' } + its(:command) { should == 'git-lfs-authenticate' } + its(:git_access) { should == 'git-upload-pack' } + end end describe :exec do @@ -306,7 +320,7 @@ describe GitlabShell do end it "should disallow access and log the attempt if check_access returns false status" do - api.stub(check_access: GitAccessStatus.new(false, 'denied', nil)) + api.stub(check_access: GitAccessStatus.new(false, 'denied', nil, nil)) message = "gitlab-shell: Access denied for git command <git-upload-pack gitlab-ci.git> " message << "by user with key #{key_id}." $logger.should_receive(:warn).with(message) diff --git a/spec/vcr_cassettes/allowed-pull.yml b/spec/vcr_cassettes/allowed-pull.yml index 5a10ec9..8e01cd3 100644 --- a/spec/vcr_cassettes/allowed-pull.yml +++ b/spec/vcr_cassettes/allowed-pull.yml @@ -42,7 +42,7 @@ http_interactions: - '0.089741' body: encoding: UTF-8 - string: '{"status": "true"}' + string: '{"status": "true","repository_http_path": "http://gitlab.dev/gitlab/gitlabhq.git"}' http_version: recorded_at: Wed, 03 Sep 2014 11:27:36 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/discover-ok.yml b/spec/vcr_cassettes/discover-ok.yml index a86243c..c2cee40 100644 --- a/spec/vcr_cassettes/discover-ok.yml +++ b/spec/vcr_cassettes/discover-ok.yml @@ -40,7 +40,7 @@ http_interactions: - '0.016934' body: encoding: UTF-8 - string: '{"name":"Dmitriy Zaporozhets","username":"dzaporozhets"}' + string: '{"name":"Dmitriy Zaporozhets","username":"dzaporozhets","lfs_token":"wsnys8Zm8Jn7zyhHTAAK"}' http_version: recorded_at: Wed, 03 Sep 2014 11:27:35 GMT recorded_with: VCR 2.4.0 |