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