Module: Gitlab::Auth::AuthFinders
- Includes:
- ActionController::HttpAuthentication::Basic, ActionController::HttpAuthentication::Token, Utils::StrongMemoize
- Included in:
- API::APIGuard::HelperMethods, ApplicationCable::Channel, ApplicationCable::Connection, RequestAuthenticator
- Defined in:
- lib/gitlab/auth/auth_finders.rb
Constant Summary collapse
- PRIVATE_TOKEN_HEADER =
'HTTP_PRIVATE_TOKEN'
- PRIVATE_TOKEN_PARAM =
:private_token
- JOB_TOKEN_HEADER =
'HTTP_JOB_TOKEN'
- JOB_TOKEN_PARAM =
:job_token
- DEPLOY_TOKEN_HEADER =
'HTTP_DEPLOY_TOKEN'
- RUNNER_TOKEN_PARAM =
:token
- RUNNER_JOB_TOKEN_PARAM =
:token
- PATH_DEPENDENT_FEED_TOKEN_REGEX =
/\A#{User::FEED_TOKEN_PREFIX}(\h{64})-(\d+)\z/
- PARAM_TOKEN_KEYS =
[ PRIVATE_TOKEN_PARAM, JOB_TOKEN_PARAM, RUNNER_JOB_TOKEN_PARAM ].map(&:to_s).freeze
- HEADER_TOKEN_KEYS =
[ PRIVATE_TOKEN_HEADER, JOB_TOKEN_HEADER, DEPLOY_TOKEN_HEADER ].freeze
Instance Method Summary collapse
- #authentication_token_present? ⇒ Boolean
- #cluster_agent_token_from_authorization_token ⇒ Object
-
#deploy_token_from_request ⇒ Object
This returns a deploy token, not a user since a deploy token does not belong to a user.
- #find_runner_from_token ⇒ Object
- #find_user_from_access_token ⇒ Object
- #find_user_from_basic_auth_password ⇒ Object
- #find_user_from_bearer_token ⇒ Object
- #find_user_from_feed_token(request_format) ⇒ Object
- #find_user_from_job_token ⇒ Object
- #find_user_from_lfs_token ⇒ Object
- #find_user_from_personal_access_token ⇒ Object
- #find_user_from_static_object_token(request_format) ⇒ Object
-
#find_user_from_warden ⇒ Object
Check the Rails session for valid authentication details.
-
#find_user_from_web_access_token(request_format, scopes: [:api]) ⇒ Object
We allow private access tokens with ‘api` scope to be used by web requests on RSS feeds or ICS files for backwards compatibility.
- #validate_and_save_access_token!(scopes: [], save_auth_context: true) ⇒ Object
Instance Method Details
#authentication_token_present? ⇒ Boolean
219 220 221 222 223 |
# File 'lib/gitlab/auth/auth_finders.rb', line 219 def authentication_token_present? PARAM_TOKEN_KEYS.intersection(current_request.params.keys).any? || HEADER_TOKEN_KEYS.intersection(current_request.env.keys).any? || parsed_oauth_token.present? end |
#cluster_agent_token_from_authorization_token ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/gitlab/auth/auth_finders.rb', line 163 def return unless route_authentication_setting[:cluster_agent_token_allowed] # We are migrating from the `Authorization` header to one specific to cluster # agents, `Gitlab-Agentk-Api-Request`. Both must be supported until KAS has # been updated to use the new header, and then this first lookup can be removed. # See https://gitlab.com/gitlab-org/gitlab/-/issues/406582. token, _ = if current_request..present? (current_request) else current_request.headers[Gitlab::Kas::INTERNAL_API_AGENTK_REQUEST_HEADER] end return unless token.present? ::Clusters::AgentToken.active.find_by_token(token.to_s) end |
#deploy_token_from_request ⇒ Object
This returns a deploy token, not a user since a deploy token does not belong to a user.
deploy tokens are accepted with deploy token headers and basic auth headers
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/gitlab/auth/auth_finders.rb', line 147 def deploy_token_from_request return unless route_authentication_setting[:deploy_token_allowed] return unless Gitlab::ExternalAuthorization.allow_deploy_tokens_and_deploy_keys? token = current_request.env[DEPLOY_TOKEN_HEADER].presence || parsed_oauth_token if has_basic_credentials?(current_request) _, token = user_name_and_password(current_request) end deploy_token = DeployToken.active.find_by_token(token.to_s) @current_authenticated_deploy_token = deploy_token # rubocop:disable Gitlab/ModuleWithInstanceVariables deploy_token end |
#find_runner_from_token ⇒ Object
181 182 183 184 185 186 187 188 |
# File 'lib/gitlab/auth/auth_finders.rb', line 181 def find_runner_from_token return unless api_request? token = current_request.params[RUNNER_TOKEN_PARAM].presence return unless token ::Ci::Runner.find_by_token(token.to_s) || raise(UnauthorizedError) end |
#find_user_from_access_token ⇒ Object
133 134 135 136 137 138 139 140 141 |
# File 'lib/gitlab/auth/auth_finders.rb', line 133 def find_user_from_access_token return unless access_token validate_and_save_access_token! ::PersonalAccessTokens::LastUsedService.new(access_token).execute access_token.user || raise(UnauthorizedError) end |
#find_user_from_basic_auth_password ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/gitlab/auth/auth_finders.rb', line 91 def find_user_from_basic_auth_password return unless has_basic_credentials?(current_request) login, password = user_name_and_password(current_request) return if ::Gitlab::Auth::CI_JOB_USER == login Gitlab::Auth.find_with_user_password(login.to_s, password.to_s) end |
#find_user_from_bearer_token ⇒ Object
78 79 80 |
# File 'lib/gitlab/auth/auth_finders.rb', line 78 def find_user_from_bearer_token find_user_from_job_bearer_token || find_user_from_access_token end |
#find_user_from_feed_token(request_format) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/gitlab/auth/auth_finders.rb', line 66 def find_user_from_feed_token(request_format) return unless valid_rss_format?(request_format) return if Gitlab::CurrentSettings.disable_feed_token # NOTE: feed_token was renamed from rss_token but both needs to be supported because # users might have already added the feed to their RSS reader before the rename token = current_request.params[:feed_token].presence || current_request.params[:rss_token].presence return unless token find_feed_token_user(token) || raise(UnauthorizedError) end |
#find_user_from_job_token ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/gitlab/auth/auth_finders.rb', line 82 def find_user_from_job_token return unless route_authentication_setting[:job_token_allowed] user = find_user_from_job_token_basic_auth if can_authenticate_job_token_basic_auth? return user if user find_user_from_job_token_query_params_or_header if can_authenticate_job_token_request? end |
#find_user_from_lfs_token ⇒ Object
100 101 102 103 104 105 106 107 |
# File 'lib/gitlab/auth/auth_finders.rb', line 100 def find_user_from_lfs_token return unless has_basic_credentials?(current_request) login, token = user_name_and_password(current_request) user = User.find_by_login(login.to_s) user if user && Gitlab::LfsToken.new(user, nil).token_valid?(token.to_s) end |
#find_user_from_personal_access_token ⇒ Object
109 110 111 112 113 114 115 |
# File 'lib/gitlab/auth/auth_finders.rb', line 109 def find_user_from_personal_access_token return unless access_token validate_and_save_access_token! access_token&.user || raise(UnauthorizedError) end |
#find_user_from_static_object_token(request_format) ⇒ Object
57 58 59 60 61 62 63 64 |
# File 'lib/gitlab/auth/auth_finders.rb', line 57 def find_user_from_static_object_token(request_format) return unless valid_static_objects_format?(request_format) token = current_request.params[:token].presence || current_request.headers['X-Gitlab-Static-Object-Token'].presence return unless token User.find_by_static_object_token(token.to_s) || raise(UnauthorizedError) end |
#find_user_from_warden ⇒ Object
Check the Rails session for valid authentication details
53 54 55 |
# File 'lib/gitlab/auth/auth_finders.rb', line 53 def find_user_from_warden current_request.env['warden']&.authenticate if verified_request? end |
#find_user_from_web_access_token(request_format, scopes: [:api]) ⇒ Object
We allow private access tokens with ‘api` scope to be used by web requests on RSS feeds or ICS files for backwards compatibility. It is also used by GraphQL/API requests. And to allow accessing /archive programatically as it was a big pain point for users gitlab.com/gitlab-org/gitlab/-/issues/28978. Used for release downloading as well
123 124 125 126 127 128 129 130 131 |
# File 'lib/gitlab/auth/auth_finders.rb', line 123 def find_user_from_web_access_token(request_format, scopes: [:api]) return unless access_token && valid_web_access_format?(request_format) validate_and_save_access_token!(scopes: scopes) ::PersonalAccessTokens::LastUsedService.new(access_token).execute access_token.user || raise(UnauthorizedError) end |
#validate_and_save_access_token!(scopes: [], save_auth_context: true) ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/gitlab/auth/auth_finders.rb', line 190 def validate_and_save_access_token!(scopes: [], save_auth_context: true) # return early if we've already authenticated via a job token return if @current_authenticated_job.present? # rubocop:disable Gitlab/ModuleWithInstanceVariables # return early if we've already authenticated via a deploy token return if @current_authenticated_deploy_token.present? # rubocop:disable Gitlab/ModuleWithInstanceVariables return unless access_token case AccessTokenValidationService.new(access_token, request: request).validate(scopes: scopes) when AccessTokenValidationService::INSUFFICIENT_SCOPE save_auth_failure_in_application_context(access_token, :insufficient_scope, scopes) if save_auth_context raise InsufficientScopeError, scopes when AccessTokenValidationService::EXPIRED save_auth_failure_in_application_context(access_token, :token_expired, scopes) if save_auth_context raise ExpiredError when AccessTokenValidationService::REVOKED save_auth_failure_in_application_context(access_token, :token_revoked, scopes) if save_auth_context revoke_token_family(access_token) raise RevokedError when AccessTokenValidationService::IMPERSONATION_DISABLED save_auth_failure_in_application_context(access_token, :impersonation_disabled, scopes) if save_auth_context raise ImpersonationDisabled end save_current_token_in_env end |