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,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 |