summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-09-02 09:20:15 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-09-02 09:20:15 +0000
commit3a3c4ea436c7e2b65c93e54e6f110722c8371fb9 (patch)
tree1ffab592d96867cdac0ec3fb5dfb46e3ccfc38cf
parent7e7f52862b2953f0b36a6fea37ca179e0182d0d8 (diff)
parent7f99aa57a28f56c6e04263cd7c2785ed867ec9a1 (diff)
downloadgitlab-ce-3a3c4ea436c7e2b65c93e54e6f110722c8371fb9.tar.gz
Merge branch 'gitlab-shell-2-0' into 'master'
Modify GitLab to work with gitlab-shell 2.0 Related to #1516 See merge request !1057
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--app/workers/post_receive.rb27
-rw-r--r--lib/api/internal.rb5
-rw-r--r--lib/gitlab/git_access.rb39
-rw-r--r--spec/requests/api/internal_spec.rb3
-rw-r--r--spec/workers/post_receive_spec.rb11
6 files changed, 57 insertions, 30 deletions
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index fee0a2788b2..227cea21564 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-1.9.7
+2.0.0
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index f110e20bf00..1406cba2db3 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -4,8 +4,7 @@ class PostReceive
sidekiq_options queue: :post_receive
- def perform(repo_path, oldrev, newrev, ref, identifier)
-
+ def perform(repo_path, identifier, changes)
if repo_path.start_with?(Gitlab.config.gitlab_shell.repos_path.to_s)
repo_path.gsub!(Gitlab.config.gitlab_shell.repos_path.to_s, "")
else
@@ -22,17 +21,23 @@ class PostReceive
return false
end
- user = identify(identifier, project, newrev)
+ changes = changes.lines if changes.kind_of?(String)
- unless user
- log("Triggered hook for non-existing user \"#{identifier} \"")
- return false
- end
+ changes.each do |change|
+ oldrev, newrev, ref = change.strip.split(' ')
- if tag?(ref)
- GitTagPushService.new.execute(project, user, oldrev, newrev, ref)
- else
- GitPushService.new.execute(project, user, oldrev, newrev, ref)
+ @user ||= identify(identifier, project, newrev)
+
+ unless @user
+ log("Triggered hook for non-existing user \"#{identifier} \"")
+ return false
+ end
+
+ if tag?(ref)
+ GitTagPushService.new.execute(project, @user, oldrev, newrev, ref)
+ else
+ GitPushService.new.execute(project, @user, oldrev, newrev, ref)
+ end
end
end
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 5850892df07..86fa149d050 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -34,10 +34,7 @@ module API
actor,
params[:action],
project,
- params[:ref],
- params[:oldrev],
- params[:newrev],
- params[:forced_push]
+ params[:changes]
)
end
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index 38b3d82e2f4..e75a5a1d62e 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -5,7 +5,7 @@ module Gitlab
attr_reader :params, :project, :git_cmd, :user
- def allowed?(actor, cmd, project, ref = nil, oldrev = nil, newrev = nil, forced_push = false)
+ def allowed?(actor, cmd, project, changes = nil)
case cmd
when *DOWNLOAD_COMMANDS
if actor.is_a? User
@@ -19,12 +19,12 @@ module Gitlab
end
when *PUSH_COMMANDS
if actor.is_a? User
- push_allowed?(actor, project, ref, oldrev, newrev, forced_push)
+ push_allowed?(actor, project, changes)
elsif actor.is_a? DeployKey
# Deploy key not allowed to push
return false
elsif actor.is_a? Key
- push_allowed?(actor.user, project, ref, oldrev, newrev, forced_push)
+ push_allowed?(actor.user, project, changes)
else
raise 'Wrong actor'
end
@@ -41,13 +41,21 @@ module Gitlab
end
end
- def push_allowed?(user, project, ref, oldrev, newrev, forced_push)
- if user && user_allowed?(user)
+ def push_allowed?(user, project, changes)
+ return false unless user && user_allowed?(user)
+ return true if changes.blank?
+
+ changes = changes.lines if changes.kind_of?(String)
+
+ # Iterate over all changes to find if user allowed all of them to be applied
+ changes.each do |change|
+ oldrev, newrev, ref = changes.split('')
+
action = if project.protected_branch?(ref)
# we dont allow force push to protected branch
- if forced_push.to_s == 'true'
+ if forced_push?(oldrev, newrev)
:force_push_code_to_protected_branches
- # and we dont allow remove of protected branch
+ # and we dont allow remove of protected branch
elsif newrev =~ /0000000/
:remove_protected_branches
else
@@ -59,7 +67,22 @@ module Gitlab
else
:push_code
end
- user.can?(action, project)
+ unless user.can?(action, project)
+ # If user does not have access to make at least one change - cancel all push
+ return false
+ end
+ end
+
+ # If user has access to make all changes
+ true
+ end
+
+ def forced_push?(oldrev, newrev)
+ return false if project.empty_repo?
+
+ if oldrev !~ /00000000/ && newrev !~ /00000000/
+ missed_refs = IO.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})).read
+ missed_refs.split("\n").size > 0
else
false
end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index dbe8043c633..47da82c061f 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -157,7 +157,6 @@ describe API::API, api: true do
def pull(key, project)
get(
api("/internal/allowed"),
- ref: 'master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-upload-pack'
@@ -167,7 +166,7 @@ describe API::API, api: true do
def push(key, project)
get(
api("/internal/allowed"),
- ref: 'master',
+ changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-receive-pack'
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index e6bf79b853c..4273fd1019a 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'
describe PostReceive do
-
context "as a resque worker" do
it "reponds to #perform" do
PostReceive.new.should respond_to(:perform)
@@ -15,7 +14,7 @@ describe PostReceive do
it "fetches the correct project" do
Project.should_receive(:find_with_namespace).with(project.path_with_namespace).and_return(project)
- PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
+ PostReceive.new.perform(pwd(project), key_id, changes)
end
it "does not run if the author is not in the project" do
@@ -23,7 +22,7 @@ describe PostReceive do
project.should_not_receive(:execute_hooks)
- PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
+ PostReceive.new.perform(pwd(project), key_id, changes).should be_false
end
it "asks the project to trigger all hooks" do
@@ -32,11 +31,15 @@ describe PostReceive do
project.should_receive(:execute_services)
project.should_receive(:update_merge_requests)
- PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
+ PostReceive.new.perform(pwd(project), key_id, changes)
end
end
def pwd(project)
File.join(Gitlab.config.gitlab_shell.repos_path, project.path_with_namespace)
end
+
+ def changes
+ 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master'
+ end
end