d9bb4230cc
Added visibility_level icons to project view (rather than just text). Added public projects to search results. Added ability to restrict visibility levels standard users can set.
139 lines
3.2 KiB
Ruby
139 lines
3.2 KiB
Ruby
require_relative 'shell_env'
|
|
require_relative 'grack_helpers'
|
|
|
|
module Grack
|
|
class Auth < Rack::Auth::Basic
|
|
include Helpers
|
|
|
|
attr_accessor :user, :project, :ref, :env
|
|
|
|
def call(env)
|
|
@env = env
|
|
@request = Rack::Request.new(env)
|
|
@auth = Request.new(env)
|
|
|
|
# Need this patch due to the rails mount
|
|
|
|
# Need this if under RELATIVE_URL_ROOT
|
|
unless Gitlab.config.gitlab.relative_url_root.empty?
|
|
# If website is mounted using relative_url_root need to remove it first
|
|
@env['PATH_INFO'] = @request.path.sub(Gitlab.config.gitlab.relative_url_root,'')
|
|
else
|
|
@env['PATH_INFO'] = @request.path
|
|
end
|
|
|
|
@env['SCRIPT_NAME'] = ""
|
|
|
|
auth!
|
|
end
|
|
|
|
private
|
|
|
|
def auth!
|
|
return render_not_found unless project
|
|
|
|
if @auth.provided?
|
|
return bad_request unless @auth.basic?
|
|
|
|
# Authentication with username and password
|
|
login, password = @auth.credentials
|
|
|
|
# Allow authentication for GitLab CI service
|
|
# if valid token passed
|
|
if login == "gitlab-ci-token" && project.gitlab_ci?
|
|
token = project.gitlab_ci_service.token
|
|
|
|
if token.present? && token == password && service_name == 'git-upload-pack'
|
|
return @app.call(env)
|
|
end
|
|
end
|
|
|
|
@user = authenticate_user(login, password)
|
|
|
|
if @user
|
|
Gitlab::ShellEnv.set_env(@user)
|
|
@env['REMOTE_USER'] = @auth.username
|
|
else
|
|
return unauthorized
|
|
end
|
|
|
|
else
|
|
return unauthorized unless project.public?
|
|
end
|
|
|
|
if authorized_git_request?
|
|
@app.call(env)
|
|
else
|
|
unauthorized
|
|
end
|
|
end
|
|
|
|
def authorized_git_request?
|
|
authorize_request(service_name)
|
|
end
|
|
|
|
def authenticate_user(login, password)
|
|
auth = Gitlab::Auth.new
|
|
auth.find(login, password)
|
|
end
|
|
|
|
def authorize_request(service)
|
|
case service
|
|
when 'git-upload-pack'
|
|
can?(user, :download_code, project)
|
|
when'git-receive-pack'
|
|
refs.each do |ref|
|
|
action = if project.protected_branch?(ref)
|
|
:push_code_to_protected_branches
|
|
else
|
|
:push_code
|
|
end
|
|
|
|
return false unless can?(user, action, project)
|
|
end
|
|
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def service_name
|
|
if @request.get?
|
|
@request.params['service']
|
|
elsif @request.post?
|
|
File.basename(@request.path)
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def project
|
|
@project ||= project_by_path(@request.path_info)
|
|
end
|
|
|
|
def refs
|
|
@refs ||= parse_refs
|
|
end
|
|
|
|
def parse_refs
|
|
input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
|
|
Zlib::GzipReader.new(@request.body).read
|
|
else
|
|
@request.body.read
|
|
end
|
|
|
|
# Need to reset seek point
|
|
@request.body.rewind
|
|
|
|
# Parse refs
|
|
refs = input.force_encoding('ascii-8bit').scan(/refs\/heads\/([\/\w\.-]+)/n).flatten.compact
|
|
|
|
# Cleanup grabare from refs
|
|
# if push to multiple branches
|
|
refs.map do |ref|
|
|
ref.gsub(/00.*/, "")
|
|
end
|
|
end
|
|
end
|
|
end
|