Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api/helpers/authentication.rb')
-rw-r--r--lib/api/helpers/authentication.rb73
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb
new file mode 100644
index 00000000000..a6cfe930190
--- /dev/null
+++ b/lib/api/helpers/authentication.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+module API
+ module Helpers
+ module Authentication
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def authenticate_with(&block)
+ strategies = ::Gitlab::APIAuthentication::Builder.new.build(&block)
+ namespace_inheritable :authentication, strategies
+ end
+ end
+
+ included do
+ helpers ::Gitlab::Utils::StrongMemoize
+
+ helpers do
+ def token_from_namespace_inheritable
+ strong_memoize(:token_from_namespace_inheritable) do
+ strategies = namespace_inheritable(:authentication)
+ next unless strategies&.any?
+
+ # Extract credentials from the request
+ found = strategies.to_h { |location, _| [location, ::Gitlab::APIAuthentication::TokenLocator.new(location).extract(current_request)] }
+ found.filter! { |location, raw| raw }
+ next unless found.any?
+
+ # Specifying multiple credentials is an error
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38627#note_475984136
+ bad_request!('Found more than one set of credentials') if found.size > 1
+
+ location, raw = found.first
+ find_token_from_raw_credentials(strategies[location], raw)
+ end
+
+ rescue ::Gitlab::Auth::UnauthorizedError
+ # TODO: this should be rescued and converted by the exception handling middleware
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38627#note_475174516
+ unauthorized!
+ end
+
+ def access_token_from_namespace_inheritable
+ token = token_from_namespace_inheritable
+ token if token.is_a? PersonalAccessToken
+ end
+
+ def user_from_namespace_inheritable
+ token = token_from_namespace_inheritable
+ return token if token.is_a? DeployToken
+
+ token&.user
+ end
+
+ private
+
+ def find_token_from_raw_credentials(token_types, raw)
+ token_types.each do |token_type|
+ # Resolve a token from the raw credentials
+ token = ::Gitlab::APIAuthentication::TokenResolver.new(token_type).resolve(raw)
+ return token if token
+ end
+
+ # If a request provides credentials via an allowed transport, the
+ # credentials must be valid. If we reach this point, the credentials
+ # must not be valid credentials of an allowed type.
+ raise ::Gitlab::Auth::UnauthorizedError
+ end
+ end
+ end
+ end
+ end
+end