From 80b8921a9a0adb60c7eb8edeaf195d9dc2530cb9 Mon Sep 17 00:00:00 2001 From: Jeremy Slater Date: Mon, 14 Jan 2013 09:46:55 -0500 Subject: [PATCH] Public HTTP clones and remove auth request for public projects --- lib/gitlab/backend/grack_auth.rb | 74 ++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 0defee2b..c921ec0d 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -2,31 +2,43 @@ module Grack class Auth < Rack::Auth::Basic attr_accessor :user, :project - def valid? - # Find project by PATH_INFO from env - if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a - self.project = Project.find_with_namespace(m.last) - return false unless project - end + def call(env) + @env = env + @request = Rack::Request.new(env) + @auth = Request.new(env) - if @request.get? && project.public - return true - end - - # Authentication with username and password - login, password = @auth.credentials - - self.user = User.find_by_email(login) || User.find_by_username(login) - - return false unless user.try(:valid_password?, password) - - email = user.email - - # Set GL_USER env variable - ENV['GL_USER'] = email # Pass Gitolite update hook ENV['GL_BYPASS_UPDATE_HOOK'] = "true" + # Need this patch due to the rails mount + @env['PATH_INFO'] = @request.path + @env['SCRIPT_NAME'] = "" + + return render_not_found unless project + return unauthorized unless project.public || @auth.provided? + return bad_request if @auth.provided? && !@auth.basic? + + if valid? + if @auth.provided? + @env['REMOTE_USER'] = @auth.username + end + return @app.call(env) + else + unauthorized + end + end + + def valid? + if @auth.provided? + # Authentication with username and password + login, password = @auth.credentials + self.user = User.find_by_email(login) || User.find_by_username(login) + return false unless user.try(:valid_password?, password) + + # Set GL_USER env variable + ENV['GL_USER'] = user.email + end + # Git upload and receive if @request.get? validate_get_request @@ -38,12 +50,12 @@ module Grack end def validate_get_request - can?(user, :download_code, project) + project.public || can?(user, :download_code, project) end def validate_post_request if @request.path_info.end_with?('git-upload-pack') - can?(user, :download_code, project) + project.public || can?(user, :download_code, project) elsif @request.path_info.end_with?('git-receive-pack') action = if project.protected_branch?(current_ref) :push_code_to_protected_branches @@ -72,6 +84,22 @@ module Grack /refs\/heads\/([\w\.-]+)/.match(input).to_a.first end + def project + unless instance_variable_defined? :@project + # Find project by PATH_INFO from env + if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a + @project = Project.find_with_namespace(m.last) + end + end + return @project + end + + PLAIN_TYPE = {"Content-Type" => "text/plain"} + + def render_not_found + [404, PLAIN_TYPE, ["Not Found"]] + end + protected def abilities