summaryrefslogtreecommitdiff
path: root/app/controllers/projects/git_http_client_controller.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/projects/git_http_client_controller.rb')
-rw-r--r--app/controllers/projects/git_http_client_controller.rb76
1 files changed, 56 insertions, 20 deletions
diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb
index a5b4031c30f..3f41916e6d3 100644
--- a/app/controllers/projects/git_http_client_controller.rb
+++ b/app/controllers/projects/git_http_client_controller.rb
@@ -4,7 +4,11 @@ class Projects::GitHttpClientController < Projects::ApplicationController
include ActionController::HttpAuthentication::Basic
include KerberosSpnegoHelper
- attr_reader :user
+ attr_reader :authentication_result
+
+ delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true
+
+ alias_method :user, :actor
# Git clients will not know what authenticity token to send along
skip_before_action :verify_authenticity_token
@@ -15,39 +19,34 @@ class Projects::GitHttpClientController < Projects::ApplicationController
private
def authenticate_user
- if project && project.public? && download_request?
- return # Allow access
- end
+ @authentication_result = Gitlab::Auth::Result.new
if allow_basic_auth? && basic_auth_provided?
login, password = user_name_and_password(request)
- auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
-
- if auth_result.type == :ci && download_request?
- @ci = true
- elsif auth_result.type == :oauth && !download_request?
- # Not allowed
- elsif auth_result.type == :missing_personal_token
- render_missing_personal_token
- return # Render above denied access, nothing left to do
- else
- @user = auth_result.user
- end
- if ci? || user
+ if handle_basic_authentication(login, password)
return # Allow access
end
elsif allow_kerberos_spnego_auth? && spnego_provided?
- @user = find_kerberos_user
+ kerberos_user = find_kerberos_user
+
+ if kerberos_user
+ @authentication_result = Gitlab::Auth::Result.new(
+ kerberos_user, nil, :kerberos, Gitlab::Auth.full_authentication_abilities)
- if user
send_final_spnego_response
return # Allow access
end
+ elsif project && download_request? && Guest.can?(:download_code, project)
+ @authentication_result = Gitlab::Auth::Result.new(nil, project, :none, [:download_code])
+
+ return # Allow access
end
send_challenges
render plain: "HTTP Basic: Access denied\n", status: 401
+ rescue Gitlab::Auth::MissingPersonalTokenError
+ render_missing_personal_token
end
def basic_auth_provided?
@@ -114,7 +113,44 @@ class Projects::GitHttpClientController < Projects::ApplicationController
render plain: 'Not Found', status: :not_found
end
+ def handle_basic_authentication(login, password)
+ @authentication_result = Gitlab::Auth.find_for_git_client(
+ login, password, project: project, ip: request.ip)
+
+ return false unless @authentication_result.success?
+
+ if download_request?
+ authentication_has_download_access?
+ else
+ authentication_has_upload_access?
+ end
+ end
+
def ci?
- @ci.present?
+ authentication_result.ci?(project)
+ end
+
+ def lfs_deploy_token?
+ authentication_result.lfs_deploy_token?(project)
+ end
+
+ def authentication_has_download_access?
+ has_authentication_ability?(:download_code) || has_authentication_ability?(:build_download_code)
+ end
+
+ def authentication_has_upload_access?
+ has_authentication_ability?(:push_code)
+ end
+
+ def has_authentication_ability?(capability)
+ (authentication_abilities || []).include?(capability)
+ end
+
+ def authentication_project
+ authentication_result.project
+ end
+
+ def verify_workhorse_api!
+ Gitlab::Workhorse.verify_api_request!(request.headers)
end
end