Only allow Git Access on the allowed protocol

This commit is contained in:
Patricio Cano 2016-06-20 20:40:56 -05:00
parent ea9d910c8b
commit 7735ef86f0
8 changed files with 46 additions and 13 deletions

View File

@ -162,7 +162,7 @@ class Projects::GitHttpController < Projects::ApplicationController
return false unless Gitlab.config.gitlab_shell.upload_pack return false unless Gitlab.config.gitlab_shell.upload_pack
if user if user
Gitlab::GitAccess.new(user, project).download_access_check.allowed? Gitlab::GitAccess.new(user, project, 'http').download_access_check.allowed?
else else
ci? || project.public? ci? || project.public?
end end

View File

@ -47,9 +47,9 @@ module ApplicationSettingsHelper
def enabled_project_tooltip(project, protocol) def enabled_project_tooltip(project, protocol)
case protocol case protocol
when 'ssh' when 'ssh'
sanitize_clone_button(ssh_clone_button(project)) sanitize_clone_button(ssh_clone_button(project, 'bottom'))
else else
sanitize_clone_button(http_clone_button(project)) sanitize_clone_button(http_clone_button(project, 'bottom'))
end end
end end

View File

@ -40,7 +40,7 @@ module ButtonHelper
type: :button type: :button
end end
def http_clone_button(project) def http_clone_button(project, placement = 'right')
klass = 'http-selector' klass = 'http-selector'
klass << ' has-tooltip' if current_user.try(:require_password?) klass << ' has-tooltip' if current_user.try(:require_password?)
@ -51,13 +51,13 @@ module ButtonHelper
href: project.http_url_to_repo, href: project.http_url_to_repo,
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: "Set a password on your account<br>to pull or push via #{protocol}" title: "Set a password on your account<br>to pull or push via #{protocol}"
} }
end end
def ssh_clone_button(project) def ssh_clone_button(project, placement = 'right')
klass = 'ssh-selector' klass = 'ssh-selector'
klass << ' has-tooltip' if current_user.try(:require_ssh_key?) klass << ' has-tooltip' if current_user.try(:require_ssh_key?)
@ -66,7 +66,7 @@ module ButtonHelper
href: project.ssh_url_to_repo, href: project.ssh_url_to_repo,
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: 'Add an SSH key to your profile<br>to pull or push via SSH.' title: 'Add an SSH key to your profile<br>to pull or push via SSH.'
} }

View File

@ -59,7 +59,8 @@ class ApplicationSetting < ActiveRecord::Base
presence: true, presence: true,
inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } } inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
validates_inclusion_of :enabled_git_access_protocols, in: %w(ssh http), allow_blank: true, allow_nil: true validates :enabled_git_access_protocols,
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
validates_each :restricted_visibility_levels do |record, attr, value| validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil? unless value.nil?

View File

@ -13,6 +13,7 @@ module API
# action - git action (git-upload-pack or git-receive-pack) # action - git action (git-upload-pack or git-receive-pack)
# ref - branch name # ref - branch name
# forced_push - forced_push # forced_push - forced_push
# protocol - Git access protocol being used, e.g. HTTP or SSH
# #
helpers do helpers do
@ -46,11 +47,13 @@ module API
User.find_by(id: params[:user_id]) User.find_by(id: params[:user_id])
end end
protocol = params[:protocol]
access = access =
if wiki? if wiki?
Gitlab::GitAccessWiki.new(actor, project) Gitlab::GitAccessWiki.new(actor, project, protocol)
else else
Gitlab::GitAccess.new(actor, project) Gitlab::GitAccess.new(actor, project, protocol)
end end
access_status = access.check(params[:action], params[:changes]) access_status = access.check(params[:action], params[:changes])

View File

@ -34,7 +34,8 @@ module Gitlab
vars = { vars = {
'GL_ID' => gl_id, 'GL_ID' => gl_id,
'PWD' => repo_path 'PWD' => repo_path,
'PROTOCOL' => 'web'
} }
options = { options = {

View File

@ -3,11 +3,12 @@ module Gitlab
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
PUSH_COMMANDS = %w{ git-receive-pack } PUSH_COMMANDS = %w{ git-receive-pack }
attr_reader :actor, :project attr_reader :actor, :project, :protocol
def initialize(actor, project) def initialize(actor, project, protocol = nil)
@actor = actor @actor = actor
@project = project @project = project
@protocol = protocol
end end
def user def user
@ -49,6 +50,8 @@ module Gitlab
end end
def check(cmd, changes = nil) def check(cmd, changes = nil)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
unless actor unless actor
return build_status_object(false, "No user or key was provided.") return build_status_object(false, "No user or key was provided.")
end end
@ -72,6 +75,8 @@ module Gitlab
end end
def download_access_check def download_access_check
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if user if user
user_download_access_check user_download_access_check
elsif deploy_key elsif deploy_key
@ -82,6 +87,8 @@ module Gitlab
end end
def push_access_check(changes) def push_access_check(changes)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if user if user
user_push_access_check(changes) user_push_access_check(changes)
elsif deploy_key elsif deploy_key
@ -92,6 +99,8 @@ module Gitlab
end end
def user_download_access_check def user_download_access_check
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
unless user.can?(:download_code, project) unless user.can?(:download_code, project)
return build_status_object(false, "You are not allowed to download code from this project.") return build_status_object(false, "You are not allowed to download code from this project.")
end end
@ -100,6 +109,8 @@ module Gitlab
end end
def user_push_access_check(changes) def user_push_access_check(changes)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if changes.blank? if changes.blank?
return build_status_object(true) return build_status_object(true)
end end
@ -188,6 +199,10 @@ module Gitlab
Gitlab::UserAccess.allowed?(user) Gitlab::UserAccess.allowed?(user)
end end
def protocol_allowed?
protocol ? Gitlab::ProtocolAccess.allowed?(protocol) : true
end
def branch_name(ref) def branch_name(ref)
ref = ref.to_s ref = ref.to_s
if Gitlab::Git.branch_ref?(ref) if Gitlab::Git.branch_ref?(ref)

View File

@ -0,0 +1,13 @@
module Gitlab
module ProtocolAccess
def self.allowed?(protocol)
if protocol.to_s == 'web'
true
elsif !current_application_settings.enabled_git_access_protocols.present?
true
else
protocol.to_s == current_application_settings.enabled_git_access_protocols
end
end
end
end