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,30 +2,42 @@ module Grack
2 class Auth < Rack::Auth::Basic 2 class Auth < Rack::Auth::Basic
3 attr_accessor :user, :project 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 # Git upload and receive 42 # Git upload and receive
31 if @request.get? 43 if @request.get?
@@ -38,12 +50,12 @@ module Grack @@ -38,12 +50,12 @@ module Grack
38 end 50 end
39 51
40 def validate_get_request 52 def validate_get_request
41 - can?(user, :download_code, project) 53 + project.public || can?(user, :download_code, project)
42 end 54 end
43 55
44 def validate_post_request 56 def validate_post_request
45 if @request.path_info.end_with?('git-upload-pack') 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 elsif @request.path_info.end_with?('git-receive-pack') 59 elsif @request.path_info.end_with?('git-receive-pack')
48 action = if project.protected_branch?(current_ref) 60 action = if project.protected_branch?(current_ref)
49 :push_code_to_protected_branches 61 :push_code_to_protected_branches
@@ -72,6 +84,22 @@ module Grack @@ -72,6 +84,22 @@ module Grack
72 /refs\/heads\/([\w\.-]+)/.match(input).to_a.first 84 /refs\/heads\/([\w\.-]+)/.match(input).to_a.first
73 end 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 protected 103 protected
76 104
77 def abilities 105 def abilities