diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-01-14 22:13:02 +0400 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-01-14 22:13:02 +0400 |
commit | b6da734824d0c74ef5bb4b784d404144c76d75f4 (patch) | |
tree | cc5c17e5ce351f1071018f456def4a1328fe1b91 | |
parent | eff6d3c12b8f1cd0d3f8f9bab8ceaeba31f915b2 (diff) | |
parent | 80b8921a9a0adb60c7eb8edeaf195d9dc2530cb9 (diff) |
Merge pull request #2584 from jasl8r/public-grack-clone
Public HTTP clones and remove auth request for public projects
-rw-r--r-- | lib/gitlab/backend/grack_auth.rb | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 0defee2b11c..c921ec0d50b 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -2,30 +2,42 @@ 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 + # Pass Gitolite update hook + ENV['GL_BYPASS_UPDATE_HOOK'] = "true" - # Authentication with username and password - login, password = @auth.credentials + # Need this patch due to the rails mount + @env['PATH_INFO'] = @request.path + @env['SCRIPT_NAME'] = "" - self.user = User.find_by_email(login) || User.find_by_username(login) + return render_not_found unless project + return unauthorized unless project.public || @auth.provided? + return bad_request if @auth.provided? && !@auth.basic? - return false unless user.try(:valid_password?, password) + if valid? + if @auth.provided? + @env['REMOTE_USER'] = @auth.username + end + return @app.call(env) + else + unauthorized + end + end - email = user.email + 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'] = email - # Pass Gitolite update hook - ENV['GL_BYPASS_UPDATE_HOOK'] = "true" + # Set GL_USER env variable + ENV['GL_USER'] = user.email + end # Git upload and receive if @request.get? @@ -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 |