Module: Gitlab::Auth

Defined in:
lib/gitlab/auth.rb,
lib/gitlab/auth/result.rb,
lib/gitlab/auth/ldap/dn.rb,
lib/gitlab/auth/activity.rb,
lib/gitlab/auth/ldap/user.rb,
lib/gitlab/auth/saml/user.rb,
lib/gitlab/auth/ldap/access.rb,
lib/gitlab/auth/ldap/config.rb,
lib/gitlab/auth/ldap/person.rb,
lib/gitlab/auth/o_auth/user.rb,
lib/gitlab/auth/saml/config.rb,
lib/gitlab/auth/auth_finders.rb,
lib/gitlab/auth/ldap/adapter.rb,
lib/gitlab/auth/otp/fortinet.rb,
lib/gitlab/auth/too_many_ips.rb,
lib/gitlab/auth/atlassian/user.rb,
lib/gitlab/auth/ldap/auth_hash.rb,
lib/gitlab/auth/o_auth/session.rb,
lib/gitlab/auth/saml/auth_hash.rb,
lib/gitlab/auth/ip_rate_limiter.rb,
lib/gitlab/auth/o_auth/provider.rb,
lib/gitlab/auth/scope_validator.rb,
lib/gitlab/auth/o_auth/auth_hash.rb,
lib/gitlab/auth/current_user_mode.rb,
lib/gitlab/auth/key_status_checker.rb,
lib/gitlab/auth/unique_ips_limiter.rb,
lib/gitlab/auth/atlassian/auth_hash.rb,
lib/gitlab/auth/ldap/authentication.rb,
lib/gitlab/auth/otp/strategies/base.rb,
lib/gitlab/auth/blocked_user_tracker.rb,
lib/gitlab/auth/crowd/authentication.rb,
lib/gitlab/auth/saml/identity_linker.rb,
lib/gitlab/auth/o_auth/authentication.rb,
lib/gitlab/auth/otp/strategies/devise.rb,
lib/gitlab/auth/request_authenticator.rb,
lib/gitlab/auth/saml/origin_validator.rb,
lib/gitlab/auth/o_auth/identity_linker.rb,
lib/gitlab/auth/u2f_webauthn_converter.rb,
lib/gitlab/auth/database/authentication.rb,
lib/gitlab/auth/two_factor_auth_verifier.rb,
lib/gitlab/auth/atlassian/identity_linker.rb,
lib/gitlab/auth/user_access_denied_reason.rb,
lib/gitlab/auth/ldap/ldap_connection_error.rb,
lib/gitlab/auth/omniauth_identity_linker_base.rb,
lib/gitlab/auth/otp/strategies/forti_token_cloud.rb,
lib/gitlab/auth/otp/strategies/forti_authenticator.rb

Defined Under Namespace

Modules: Atlassian, AuthFinders, Crowd, Database, Ldap, OAuth, Otp, Saml Classes: Activity, BlockedUserTracker, CurrentUserMode, InsufficientScopeError, IpRateLimiter, KeyStatusChecker, OmniauthIdentityLinkerBase, RequestAuthenticator, Result, ScopeValidator, TooManyIps, TwoFactorAuthVerifier, U2fWebauthnConverter, UniqueIpsLimiter, UserAccessDeniedReason

Constant Summary collapse

MissingPersonalAccessTokenError =
Class.new(StandardError)
IpBlacklisted =
Class.new(StandardError)
API_SCOPE =

Scopes used for GitLab API access

:api
READ_API_SCOPE =
:read_api
READ_USER_SCOPE =
:read_user
API_SCOPES =
[API_SCOPE, READ_API_SCOPE, READ_USER_SCOPE].freeze
PROFILE_SCOPE =
:profile
EMAIL_SCOPE =
:email
OPENID_SCOPE =
:openid
OPENID_SCOPES =

Scopes used for OpenID Connect

[OPENID_SCOPE].freeze
PROFILE_SCOPES =

OpenID Connect profile scopes

[PROFILE_SCOPE, EMAIL_SCOPE].freeze
READ_REPOSITORY_SCOPE =

Scopes used for GitLab Repository access

:read_repository
WRITE_REPOSITORY_SCOPE =
:write_repository
REPOSITORY_SCOPES =
[READ_REPOSITORY_SCOPE, WRITE_REPOSITORY_SCOPE].freeze
READ_REGISTRY_SCOPE =

Scopes used for GitLab Docker Registry access

:read_registry
WRITE_REGISTRY_SCOPE =
:write_registry
REGISTRY_SCOPES =
[READ_REGISTRY_SCOPE, WRITE_REGISTRY_SCOPE].freeze
SUDO_SCOPE =

Scopes used for GitLab as admin

:sudo
ADMIN_SCOPES =
[SUDO_SCOPE].freeze
DEFAULT_SCOPES =

Default scopes for OAuth applications that don't define their own

[API_SCOPE].freeze
CI_JOB_USER =
'gitlab-ci-token'
AuthenticationError =
Class.new(StandardError)
MissingTokenError =
Class.new(AuthenticationError)
TokenNotFoundError =
Class.new(AuthenticationError)
ExpiredError =
Class.new(AuthenticationError)
RevokedError =
Class.new(AuthenticationError)
ImpersonationDisabled =
Class.new(AuthenticationError)
UnauthorizedError =
Class.new(AuthenticationError)

Class Method Summary collapse

Class Method Details

.all_available_scopesObject


386
387
388
# File 'lib/gitlab/auth.rb', line 386

def all_available_scopes
  non_admin_available_scopes + ADMIN_SCOPES
end

.available_scopes_for(current_user) ⇒ Object


380
381
382
383
384
# File 'lib/gitlab/auth.rb', line 380

def available_scopes_for(current_user)
  scopes = non_admin_available_scopes
  scopes += ADMIN_SCOPES if current_user.admin?
  scopes
end

.build_authentication_abilitiesObject


338
339
340
341
342
343
344
345
346
# File 'lib/gitlab/auth.rb', line 338

def build_authentication_abilities
  [
    :read_project,
    :build_download_code,
    :build_read_container_image,
    :build_create_container_image,
    :build_destroy_container_image
  ]
end

.find_for_git_client(login, password, project:, ip:) ⇒ Object

Raises:


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/gitlab/auth.rb', line 48

def find_for_git_client(, password, project:, ip:)
  raise "Must provide an IP for rate limiting" if ip.nil?

  rate_limiter = Gitlab::Auth::IpRateLimiter.new(ip)

  raise IpBlacklisted if !skip_rate_limit?(login: ) && rate_limiter.banned?

  # `user_with_password_for_git` should be the last check
  # because it's the most expensive, especially when LDAP
  # is enabled.
  result =
    service_request_check(, password, project) ||
    build_access_token_check(, password) ||
    lfs_token_check(, password, project) ||
    oauth_access_token_check(, password) ||
    personal_access_token_check(password, project) ||
    deploy_token_check(, password, project) ||
    user_with_password_for_git(, password) ||
    Gitlab::Auth::Result::EMPTY

  rate_limit!(rate_limiter, success: result.success?, login: )
  look_to_limit_user(result.actor)

  return result if result.success? || authenticate_using_internal_or_ldap_password?

  # If sign-in is disabled and LDAP is not configured, recommend a
  # personal access token on failed auth attempts
  raise Gitlab::Auth::MissingPersonalAccessTokenError
end

.find_with_user_password(login, password, increment_failed_attempts: false) ⇒ Object

Find and return a user if the provided password is valid for various authenticators (OAuth, LDAP, Local Database).

Specify `increment_failed_attempts: true` to increment Devise `failed_attempts`. CAUTION: Avoid incrementing failed attempts when authentication falls through different mechanisms, as in `.find_for_git_client`. This may lead to unwanted access locks when the value provided for `password` was actually a PAT, deploy token, etc.


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/gitlab/auth.rb', line 86

def find_with_user_password(, password, increment_failed_attempts: false)
  # Avoid resource intensive checks if login credentials are not provided
  return unless .present? && password.present?

  # Nothing to do here if internal auth is disabled and LDAP is
  # not configured
  return unless authenticate_using_internal_or_ldap_password?

  Gitlab::Auth::UniqueIpsLimiter.limit_user! do
    user = User.()

    break if user && !user.

    authenticators = []

    if user
      authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, 'database')

      # Add authenticators for all identities if user is not nil
      user&.identities&.each do |identity|
        authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, identity.provider)
      end
    else
      # If no user is provided, try LDAP.
      #   LDAP users are only authenticated via LDAP
      authenticators << Gitlab::Auth::Ldap::Authentication
    end

    authenticators.compact!

    # return found user that was authenticated first for given login credentials
    authenticated_user = authenticators.find do |auth|
      authenticated_user = auth.(, password)
      break authenticated_user if authenticated_user
    end

    user_auth_attempt!(user, success: !!authenticated_user) if increment_failed_attempts

    authenticated_user
  end
end

.full_authentication_abilitiesObject


374
375
376
377
378
# File 'lib/gitlab/auth.rb', line 374

def full_authentication_abilities
  read_write_authentication_abilities + [
    :admin_container_image
  ]
end

.omniauth_enabled?Boolean

Returns:

  • (Boolean)

44
45
46
# File 'lib/gitlab/auth.rb', line 44

def omniauth_enabled?
  Gitlab.config.omniauth.enabled
end

.optional_scopesObject

Other available scopes


391
392
393
# File 'lib/gitlab/auth.rb', line 391

def optional_scopes
  all_available_scopes + OPENID_SCOPES + PROFILE_SCOPES - DEFAULT_SCOPES
end

.read_only_authentication_abilitiesObject


361
362
363
364
365
# File 'lib/gitlab/auth.rb', line 361

def read_only_authentication_abilities
  read_only_project_authentication_abilities + [
    :read_container_image
  ]
end

.read_only_project_authentication_abilitiesObject


348
349
350
351
352
353
# File 'lib/gitlab/auth.rb', line 348

def read_only_project_authentication_abilities
  [
    :read_project,
    :download_code
  ]
end

.read_write_authentication_abilitiesObject


367
368
369
370
371
372
# File 'lib/gitlab/auth.rb', line 367

def read_write_authentication_abilities
  read_only_authentication_abilities + [
    :push_code,
    :create_container_image
  ]
end

.read_write_project_authentication_abilitiesObject


355
356
357
358
359
# File 'lib/gitlab/auth.rb', line 355

def read_write_project_authentication_abilities
  read_only_project_authentication_abilities + [
    :push_code
  ]
end

.registry_scopesObject


395
396
397
398
399
# File 'lib/gitlab/auth.rb', line 395

def registry_scopes
  return [] unless Gitlab.config.registry.enabled

  REGISTRY_SCOPES
end

.resource_bot_scopesObject


401
402
403
# File 'lib/gitlab/auth.rb', line 401

def resource_bot_scopes
  Gitlab::Auth::API_SCOPES + Gitlab::Auth::REPOSITORY_SCOPES + Gitlab::Auth.registry_scopes - [:read_user]
end