Commit 80b8921a9a0adb60c7eb8edeaf195d9dc2530cb9
1 parent
eff6d3c1
Exists in
master
and in
4 other branches
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 | ... | ... |