diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-09-01 19:00:06 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-09-01 19:00:06 +0300 |
commit | 119aae7d71cac17af9a68122c8b3021adf5cbfd9 (patch) | |
tree | 40c4756ad1b647dd655c13b0805ecf14ae2be372 | |
parent | c6909d0c941784d60cb552d5685e1ff808323991 (diff) | |
download | gitlab-shell-119aae7d71cac17af9a68122c8b3021adf5cbfd9.tar.gz |
GitlabAccess and GitlabPostReceive classes added
Gitlab Access handles security check. GitlabPostReceive creates a sidekiq job
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
-rw-r--r-- | lib/gitlab_access.rb | 34 | ||||
-rw-r--r-- | lib/gitlab_post_receive.rb | 31 | ||||
-rw-r--r-- | lib/gitlab_projects.rb | 8 | ||||
-rw-r--r-- | spec/gitlab_access_spec.rb | 18 |
4 files changed, 88 insertions, 3 deletions
diff --git a/lib/gitlab_access.rb b/lib/gitlab_access.rb new file mode 100644 index 0000000..1f328b7 --- /dev/null +++ b/lib/gitlab_access.rb @@ -0,0 +1,34 @@ +require_relative 'gitlab_init' +require_relative 'gitlab_net' +require_relative 'names_helper' +require 'json' + +class GitlabAccess + include NamesHelper + + attr_reader :config, :repo_path, :repo_name, :changes + + def initialize(repo_path, actor, changes) + @config = GitlabConfig.new + @repo_path, @actor = repo_path.strip, actor + @repo_name = extract_repo_name(@repo_path.dup, config.repos_path.to_s) + @changes = changes.lines + end + + def exec + if api.allowed?('git-receive-pack', @repo_name, @actor, @changes) + exit 0 + else + # reset GL_ID env since we stop git push here + ENV['GL_ID'] = nil + puts "GitLab: You are not allowed to access #{@ref_name}!" + exit 1 + end + end + + protected + + def api + GitlabNet.new + end +end diff --git a/lib/gitlab_post_receive.rb b/lib/gitlab_post_receive.rb new file mode 100644 index 0000000..3f9f384 --- /dev/null +++ b/lib/gitlab_post_receive.rb @@ -0,0 +1,31 @@ +require_relative 'gitlab_init' +require 'json' + +class GitlabPostReceive + attr_reader :config, :repo_path, :changes + + def initialize(repo_path, actor, changes) + @config = GitlabConfig.new + @repo_path, @actor = repo_path.strip, actor + @changes = changes.lines + end + + def exec + # reset GL_ID env since we already + # get value from it + ENV['GL_ID'] = nil + + update_redis + end + + protected + + def update_redis + queue = "#{config.redis_namespace}:queue:post_receive" + msg = JSON.dump({'class' => 'PostReceive', 'args' => [@repo_path, @actor, @changes]}) + unless system(*config.redis_command, 'rpush', queue, msg, err: '/dev/null', out: '/dev/null') + puts "GitLab: An unexpected error occurred (redis-cli returned #{$?.exitstatus})." + exit 1 + end + end +end diff --git a/lib/gitlab_projects.rb b/lib/gitlab_projects.rb index a6fa1b5..a27036b 100644 --- a/lib/gitlab_projects.rb +++ b/lib/gitlab_projects.rb @@ -18,9 +18,11 @@ class GitlabProjects attr_reader :full_path def self.create_hooks(path) - hook = File.join(path, 'hooks', 'update') - File.delete(hook) if File.exists?(hook) - File.symlink(File.join(ROOT_PATH, 'hooks', 'update'), hook) + %w(pre-receive post-receive).each do |hook_name| + hook = File.join(path, 'hooks', hook_name) + File.delete(hook) if File.exists?(hook) + File.symlink(File.join(ROOT_PATH, 'hooks', hook_name), hook) + end end def initialize diff --git a/spec/gitlab_access_spec.rb b/spec/gitlab_access_spec.rb new file mode 100644 index 0000000..81de152 --- /dev/null +++ b/spec/gitlab_access_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' +require 'gitlab_access' + +describe GitlabAccess do + let(:repository_path) { "/home/git/repositories" } + let(:repo_name) { 'dzaporozhets/gitlab-ci' } + let(:repo_path) { File.join(repository_path, repo_name) + ".git" } + let(:gitlab_access) { GitlabAccess.new(repo_path, 'key-123', '') } + + before do + GitlabConfig.any_instance.stub(repos_path: repository_path) + end + + describe :initialize do + it { gitlab_access.repo_name.should == repo_name } + it { gitlab_access.repo_path.should == repo_path } + end +end |