Commit 80b8921a9a0adb60c7eb8edeaf195d9dc2530cb9

Authored by Jeremy Slater
1 parent eff6d3c1

Public HTTP clones and remove auth request for public projects

Showing 1 changed file with 48 additions and 20 deletions   Show diff stats
lib/gitlab/backend/grack_auth.rb
... ... @@ -2,30 +2,42 @@ module Grack
2 2 class Auth < Rack::Auth::Basic
3 3 attr_accessor :user, :project
4 4  
5   - def valid?
6   - # Find project by PATH_INFO from env
7   - if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
8   - self.project = Project.find_with_namespace(m.last)
9   - return false unless project
10   - end
  5 + def call(env)
  6 + @env = env
  7 + @request = Rack::Request.new(env)
  8 + @auth = Request.new(env)
11 9  
12   - if @request.get? && project.public
13   - return true
14   - end
  10 + # Pass Gitolite update hook
  11 + ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
15 12  
16   - # Authentication with username and password
17   - login, password = @auth.credentials
  13 + # Need this patch due to the rails mount
  14 + @env['PATH_INFO'] = @request.path
  15 + @env['SCRIPT_NAME'] = ""
18 16  
19   - self.user = User.find_by_email(login) || User.find_by_username(login)
  17 + return render_not_found unless project
  18 + return unauthorized unless project.public || @auth.provided?
  19 + return bad_request if @auth.provided? && !@auth.basic?
20 20  
21   - return false unless user.try(:valid_password?, password)
  21 + if valid?
  22 + if @auth.provided?
  23 + @env['REMOTE_USER'] = @auth.username
  24 + end
  25 + return @app.call(env)
  26 + else
  27 + unauthorized
  28 + end
  29 + end
22 30  
23   - email = user.email
  31 + def valid?
  32 + if @auth.provided?
  33 + # Authentication with username and password
  34 + login, password = @auth.credentials
  35 + self.user = User.find_by_email(login) || User.find_by_username(login)
  36 + return false unless user.try(:valid_password?, password)
24 37  
25   - # Set GL_USER env variable
26   - ENV['GL_USER'] = email
27   - # Pass Gitolite update hook
28   - ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
  38 + # Set GL_USER env variable
  39 + ENV['GL_USER'] = user.email
  40 + end
29 41  
30 42 # Git upload and receive
31 43 if @request.get?
... ... @@ -38,12 +50,12 @@ module Grack
38 50 end
39 51  
40 52 def validate_get_request
41   - can?(user, :download_code, project)
  53 + project.public || can?(user, :download_code, project)
42 54 end
43 55  
44 56 def validate_post_request
45 57 if @request.path_info.end_with?('git-upload-pack')
46   - can?(user, :download_code, project)
  58 + project.public || can?(user, :download_code, project)
47 59 elsif @request.path_info.end_with?('git-receive-pack')
48 60 action = if project.protected_branch?(current_ref)
49 61 :push_code_to_protected_branches
... ... @@ -72,6 +84,22 @@ module Grack
72 84 /refs\/heads\/([\w\.-]+)/.match(input).to_a.first
73 85 end
74 86  
  87 + def project
  88 + unless instance_variable_defined? :@project
  89 + # Find project by PATH_INFO from env
  90 + if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
  91 + @project = Project.find_with_namespace(m.last)
  92 + end
  93 + end
  94 + return @project
  95 + end
  96 +
  97 + PLAIN_TYPE = {"Content-Type" => "text/plain"}
  98 +
  99 + def render_not_found
  100 + [404, PLAIN_TYPE, ["Not Found"]]
  101 + end
  102 +
75 103 protected
76 104  
77 105 def abilities
... ...