summaryrefslogtreecommitdiff
path: root/lib/gitlab/backend/grack_auth.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/backend/grack_auth.rb')
-rw-r--r--lib/gitlab/backend/grack_auth.rb141
1 files changed, 54 insertions, 87 deletions
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 4f3f7b02a5b..e7217c7c7e6 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -1,9 +1,13 @@
require_relative 'shell_env'
-require 'omniauth-ldap'
+require_relative 'grack_ldap'
+require_relative 'grack_helpers'
module Grack
class Auth < Rack::Auth::Basic
- attr_accessor :user, :project
+ include LDAP
+ include Helpers
+
+ attr_accessor :user, :project, :ref, :env
def call(env)
@env = env
@@ -14,42 +18,52 @@ module Grack
@env['PATH_INFO'] = @request.path
@env['SCRIPT_NAME'] = ""
- return render_not_found unless project
- return unauthorized unless project.public || @auth.provided?
- return bad_request if @auth.provided? && !@auth.basic?
-
- if valid?
- if @auth.provided?
- @env['REMOTE_USER'] = @auth.username
- end
- return @app.call(env)
- else
- unauthorized
- end
+ auth!
end
- def valid?
+ private
+
+ def auth!
+ return render_not_found unless project
+
if @auth.provided?
+ return bad_request unless @auth.basic?
+
# Authentication with username and password
login, password = @auth.credentials
- @user = authenticate(login, password)
- return false unless @user
+ @user = authenticate_user(login, password)
- Gitlab::ShellEnv.set_env(@user)
+ if @user
+ Gitlab::ShellEnv.set_env(@user)
+ @env['REMOTE_USER'] = @auth.username
+ else
+ return unauthorized
+ end
+
+ else
+ return unauthorized unless project.public
end
+ if authorized_git_request?
+ @app.call(env)
+ else
+ unauthorized
+ end
+ end
+
+ def authorized_git_request?
# Git upload and receive
if @request.get?
- validate_get_request
+ authorize_request(@request.params['service'])
elsif @request.post?
- validate_post_request
+ authorize_request(File.basename(@request.path))
else
false
end
end
- def authenticate(login, password)
+ def authenticate_user(login, password)
user = User.find_by_email(login) || User.find_by_username(login)
# If the provided login was not a known email or username
@@ -65,34 +79,12 @@ module Grack
end
end
- def ldap_auth(login, password)
- # Check user against LDAP backend if user is not authenticated
- # Only check with valid login and password to prevent anonymous bind results
- return nil unless ldap_conf.enabled && !login.blank? && !password.blank?
-
- ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf)
- ldap_user = ldap.bind_as(
- filter: Net::LDAP::Filter.eq(ldap.uid, login),
- size: 1,
- password: password
- )
-
- User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap') if ldap_user
- end
-
- def validate_get_request
- validate_request(@request.params['service'])
- end
-
- def validate_post_request
- validate_request(File.basename(@request.path))
- end
-
- def validate_request(service)
- if service == 'git-upload-pack'
+ def authorize_request(service)
+ case service
+ when 'git-upload-pack'
project.public || can?(user, :download_code, project)
- elsif service == 'git-receive-pack'
- action = if project.protected_branch?(current_ref)
+ when'git-receive-pack'
+ action = if project.protected_branch?(ref)
:push_code_to_protected_branches
else
:push_code
@@ -104,49 +96,24 @@ module Grack
end
end
- def can?(object, action, subject)
- abilities.allowed?(object, action, subject)
- end
-
- def current_ref
- if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
- input = Zlib::GzipReader.new(@request.body).read
- else
- input = @request.body.read
- end
- # Need to reset seek point
- @request.body.rewind
- /refs\/heads\/([\w\.-]+)/n.match(input.force_encoding('ascii-8bit')).to_a.last
- end
-
def project
- unless instance_variable_defined? :@project
- # Find project by PATH_INFO from env
- if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
- @project = Project.find_with_namespace(m.last)
- end
- end
- return @project
+ @project ||= project_by_path(@request.path_info)
end
- PLAIN_TYPE = {"Content-Type" => "text/plain"}
-
- def render_not_found
- [404, PLAIN_TYPE, ["Not Found"]]
+ def ref
+ @ref ||= parse_ref
end
- protected
+ def parse_ref
+ input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
+ Zlib::GzipReader.new(@request.body).read
+ else
+ @request.body.read
+ end
- def abilities
- @abilities ||= begin
- abilities = Six.new
- abilities << Ability
- abilities
- end
- end
-
- def ldap_conf
- @ldap_conf ||= Gitlab.config.ldap
+ # Need to reset seek point
+ @request.body.rewind
+ /refs\/heads\/([\w\.-]+)/n.match(input.force_encoding('ascii-8bit')).to_a.last
end
- end# Auth
-end# Grack
+ end
+end