Commit 3a3c4ea4 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'gitlab-shell-2-0' into 'master'

Modify GitLab to work with gitlab-shell 2.0

Related to #1516

See merge request !1057
parents 7e7f5286 7f99aa57
......@@ -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)
changes.each do |change|
oldrev, newrev, ref = change.strip.split(' ')
unless user
@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)
GitTagPushService.new.execute(project, @user, oldrev, newrev, ref)
else
GitPushService.new.execute(project, user, oldrev, newrev, ref)
GitPushService.new.execute(project, @user, oldrev, newrev, ref)
end
end
end
......
......@@ -34,10 +34,7 @@ module API
actor,
params[:action],
project,
params[:ref],
params[:oldrev],
params[:newrev],
params[:forced_push]
params[:changes]
)
end
......
......@@ -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,11 +41,19 @@ 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
elsif newrev =~ /0000000/
......@@ -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
......
......@@ -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'
......
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
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