diff options
-rw-r--r-- | .gitlab-ci.yml | 22 | ||||
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | config.yml.example | 5 | ||||
-rw-r--r-- | lib/gitlab_keys.rb | 15 | ||||
-rw-r--r-- | lib/gitlab_shell.rb | 19 | ||||
-rw-r--r-- | spec/gitlab_keys_spec.rb | 8 |
7 files changed, 89 insertions, 17 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..fa4f2d4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,22 @@ +before_script: + - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin + - gem install bundler + - cp config.yml.example config.yml + - bundle install + +rspec: + script: + - bundle exec rspec spec + tags: + - git-annex + - ruby + except: + - tags + +rubocop: + script: + - bundle exec rubocop + tags: + - ruby + except: + - tags @@ -1,5 +1,7 @@ v2.6.4 + - Remove keys from authorized_keys in-place - Increase batch_add_keys lock timeout to 300 seconds + v2.6.3 - Prevent keys with a very specific comment from accidentally being deleted. @@ -40,7 +40,7 @@ An overview of the four cases described above: ## Code status -[](http://ci.gitlab.org/projects/4?ref=master) +[](https://ci.gitlab.org/projects/4?ref=master) [](https://semaphoreapp.com/gitlabhq/gitlab-shell) [](https://codeclimate.com/github/gitlabhq/gitlab-shell) [](https://coveralls.io/r/gitlabhq/gitlab-shell) @@ -91,7 +91,7 @@ List repos: Import repo: # Default timeout is 2 minutes - ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git + ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git # Override timeout in seconds ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git 90 @@ -114,7 +114,7 @@ Remove branch: Create tag (lightweight & annotated): - ./bin/gitlab-projects create-tag gitlab/gitlab-ci.git v3.0.0 3-0-stable + ./bin/gitlab-projects create-tag gitlab/gitlab-ci.git v3.0.0 3-0-stable ./bin/gitlab-projects create-tag gitlab/gitlab-ci.git v3.0.0 3-0-stable 'annotated message goes here' Remove tag: @@ -139,3 +139,32 @@ List all keys: Remove all keys from authorized_keys file: ./bin/gitlab-keys clear + +## Git LFS remark + +If you want to play with git-lfs (https://git-lfs.github.com/) on GitLab, you should do the following: + + * Install LFS-server (no production-ready implementation yet, but you can use https://github.com/github/lfs-test-server) on any host; + * Add some user on LFS-server (for example: user ```foo``` with password ```bar```); + * Add ```git-lfs-authenticate``` script in any PATH-available directory on GIT-server like this: +``` +#!/bin/sh +echo "{ + \"href\": \"http://lfs.test.local:9999/test/test\", + \"header\": { + \"Authorization\": \"Basic `echo -n foo:bar | base64`\" + } +}" + ``` + +After that you can play with git-lfs (git-lfs feature will be available via ssh protocol). + +This design will work without a script git-lfs-authenticate, but with the following limitations: + + * You will need to manually configure lfs-server URL for every user working copy; + * SSO don't work and you need to manually add lfs-server credentials for every user working copy (otherwise, git-lfs will ask for the password for each file). + +Usefull links: + + * https://github.com/github/git-lfs/tree/master/docs/api - Git LFS API, also contains more information about ```git-lfs-authenticate```; + * https://github.com/github/git-lfs/wiki/Implementations - Git LFS-server implementations. diff --git a/config.yml.example b/config.yml.example index 9dc30db..43d6e85 100644 --- a/config.yml.example +++ b/config.yml.example @@ -1,3 +1,8 @@ +# +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# + # GitLab user. git by default user: git diff --git a/lib/gitlab_keys.rb b/lib/gitlab_keys.rb index ca3a816..3710f96 100644 --- a/lib/gitlab_keys.rb +++ b/lib/gitlab_keys.rb @@ -1,4 +1,3 @@ -require 'tempfile' require 'timeout' require_relative 'gitlab_config' @@ -82,14 +81,14 @@ class GitlabKeys def rm_key lock do $logger.info "Removing key #{@key_id}" - Tempfile.open('authorized_keys') do |temp| - open(auth_file, 'r+') do |current| - current.each do |line| - temp.puts(line) unless line.start_with?("command=\"#{key_command(@key_id)}\"") - end + open(auth_file, 'r+') do |f| + while line = f.gets do + next unless line.start_with?("command=\"#{key_command(@key_id)}\"") + f.seek(-line.length, IO::SEEK_CUR) + # Overwrite the line with #'s. Because the 'line' variable contains + # a terminating '\n', we write line.length - 1 '#' characters. + f.write('#' * (line.length - 1)) end - temp.close - FileUtils.cp(temp.path, auth_file) end end true diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb index 7249836..7c75910 100644 --- a/lib/gitlab_shell.rb +++ b/lib/gitlab_shell.rb @@ -7,7 +7,7 @@ class GitlabShell class DisallowedCommandError < StandardError; end class InvalidRepositoryPathError < StandardError; end - GIT_COMMANDS = %w(git-upload-pack git-receive-pack git-upload-archive git-annex-shell).freeze + GIT_COMMANDS = %w(git-upload-pack git-receive-pack git-upload-archive git-annex-shell git-lfs-authenticate).freeze attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name @@ -56,16 +56,29 @@ class GitlabShell def parse_cmd args = Shellwords.shellwords(@origin_cmd) @git_cmd = args.first + @git_access = @git_cmd raise DisallowedCommandError unless GIT_COMMANDS.include?(@git_cmd) - if @git_cmd == 'git-annex-shell' + case @git_cmd + when 'git-annex-shell' raise DisallowedCommandError unless @config.git_annex_enabled? @repo_name = escape_path(args[2].sub(/\A\/~\//, '')) # Make sure repository has git-annex enabled init_git_annex(@repo_name) + when 'git-lfs-authenticate' + raise DisallowedCommandError unless args.count >= 2 + @repo_name = escape_path(args[1]) + case args[2] + when 'download' + @git_access = 'git-upload-pack' + when 'upload' + @git_access = 'git-receive-pack' + else + raise DisallowedCommandError + end else raise DisallowedCommandError unless args.count == 2 @repo_name = escape_path(args.last) @@ -73,7 +86,7 @@ class GitlabShell end def verify_access - status = api.check_access(@git_cmd, @repo_name, @key_id, '_any') + status = api.check_access(@git_access, @repo_name, @key_id, '_any') raise AccessDeniedError, status.message unless status.allowed? end diff --git a/spec/gitlab_keys_spec.rb b/spec/gitlab_keys_spec.rb index bcce628..ed2fd58 100644 --- a/spec/gitlab_keys_spec.rb +++ b/spec/gitlab_keys_spec.rb @@ -109,17 +109,19 @@ describe GitlabKeys do it "removes the right line" do create_authorized_keys_fixture other_line = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-742\",options ssh-rsa AAAAB3NzaDAxx2E" + delete_line = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-741\",options ssh-rsa AAAAB3NzaDAxx2E" open(tmp_authorized_keys_path, 'a') do |auth_file| - auth_file.puts "command=\"#{ROOT_PATH}/bin/gitlab-shell key-741\",options ssh-rsa AAAAB3NzaDAxx2E" + auth_file.puts delete_line auth_file.puts other_line end gitlab_keys.send :rm_key - File.read(tmp_authorized_keys_path).should == "existing content\n#{other_line}\n" + erased_line = delete_line.gsub(/./, '#') + File.read(tmp_authorized_keys_path).should == "existing content\n#{erased_line}\n#{other_line}\n" end context "without file writing" do before do - Tempfile.stub(:open) + gitlab_keys.stub(:open) gitlab_keys.stub(:lock).and_yield end |