mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-10 13:16:09 +10:00
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> Conflicts: LICENSE VERSION app/controllers/omniauth_callbacks_controller.rb app/helpers/application_helper.rb app/helpers/merge_requests_helper.rb app/models/group.rb app/models/project.rb app/models/project_team.rb app/views/admin/groups/edit.html.haml app/views/groups/_projects.html.haml app/views/groups/edit.html.haml db/schema.rb doc/install/installation.md doc/integration/README.md lib/gitlab/git_access.rb lib/gitlab/markdown.rb spec/helpers/merge_requests_helper.rb spec/models/merge_request_spec.rb
103 lines
3.0 KiB
Ruby
103 lines
3.0 KiB
Ruby
module Gitlab
|
|
class GitAccess
|
|
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
|
|
PUSH_COMMANDS = %w{ git-receive-pack }
|
|
|
|
attr_reader :params, :project, :git_cmd, :user
|
|
|
|
def allowed?(actor, cmd, project, ref = nil, oldrev = nil, newrev = nil, forced_push = false)
|
|
case cmd
|
|
when *DOWNLOAD_COMMANDS
|
|
if actor.is_a? User
|
|
download_allowed?(actor, project)
|
|
elsif actor.is_a? DeployKey
|
|
actor.projects.include?(project)
|
|
elsif actor.is_a? Key
|
|
download_allowed?(actor.user, project)
|
|
else
|
|
raise 'Wrong actor'
|
|
end
|
|
when *PUSH_COMMANDS
|
|
if actor.is_a? User
|
|
push_allowed?(actor, project, ref, oldrev, newrev, forced_push)
|
|
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)
|
|
else
|
|
raise 'Wrong actor'
|
|
end
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def download_allowed?(user, project)
|
|
if user && user_allowed?(user)
|
|
user.can?(:download_code, project)
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def push_allowed?(user, project, ref, oldrev, newrev, forced_push)
|
|
if user && user_allowed?(user)
|
|
action = if project.protected_branch?(ref)
|
|
# we dont allow force push to protected branch
|
|
if forced_push.to_s == 'true'
|
|
:force_push_code_to_protected_branches
|
|
# and we dont allow remove of protected branch
|
|
elsif newrev =~ /0000000/
|
|
:remove_protected_branches
|
|
else
|
|
:push_code_to_protected_branches
|
|
end
|
|
elsif project.repository && project.repository.tag_names.include?(ref)
|
|
# Prevent any changes to existing git tag unless user has permissions
|
|
:admin_project
|
|
else
|
|
:push_code
|
|
end
|
|
user.can?(action, project) &&
|
|
pass_git_hooks?(user, project, ref, oldrev, newrev)
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def pass_git_hooks?(user, project, ref, oldrev, newrev)
|
|
return true unless project.git_hook
|
|
|
|
return true unless newrev && oldrev
|
|
|
|
git_hook = project.git_hook
|
|
|
|
# Prevent tag removal
|
|
if git_hook.deny_delete_tag
|
|
if project.repository.tag_names.include?(ref) && newrev =~ /0000000/
|
|
return false
|
|
end
|
|
end
|
|
|
|
# Check commit messages unless its branch removal
|
|
if git_hook.commit_message_regex.present? && newrev !~ /00000000/
|
|
commits = project.repository.commits_between(oldrev, newrev)
|
|
commits.each do |commit|
|
|
unless commit.safe_message =~ Regexp.new(git_hook.commit_message_regex)
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def user_allowed?(user)
|
|
Gitlab::UserAccess.allowed?(user)
|
|
end
|
|
end
|
|
end
|