diff options
Diffstat (limited to 'lib/gitlab/auth.rb')
-rw-r--r-- | lib/gitlab/auth.rb | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 099c45dcfb7..f461d0f97f1 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -2,6 +2,8 @@ module Gitlab module Auth MissingPersonalTokenError = Class.new(StandardError) + REGISTRY_SCOPES = [:read_registry].freeze + # Scopes used for GitLab API access API_SCOPES = [:api, :read_user].freeze @@ -11,8 +13,10 @@ module Gitlab # Default scopes for OAuth applications that don't define their own DEFAULT_SCOPES = [:api].freeze + AVAILABLE_SCOPES = (API_SCOPES + REGISTRY_SCOPES).freeze + # Other available scopes - OPTIONAL_SCOPES = (API_SCOPES + OPENID_SCOPES - DEFAULT_SCOPES).freeze + OPTIONAL_SCOPES = (AVAILABLE_SCOPES + OPENID_SCOPES - DEFAULT_SCOPES).freeze class << self def find_for_git_client(login, password, project:, ip:) @@ -26,8 +30,8 @@ module Gitlab build_access_token_check(login, password) || lfs_token_check(login, password) || oauth_access_token_check(login, password) || - user_with_password_for_git(login, password) || personal_access_token_check(password) || + user_with_password_for_git(login, password) || Gitlab::Auth::Result.new rate_limit!(ip, success: result.success?, login: login) @@ -103,15 +107,16 @@ module Gitlab raise Gitlab::Auth::MissingPersonalTokenError if user.two_factor_enabled? - Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities) + Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_api_abilities) end def oauth_access_token_check(login, password) if login == "oauth2" && password.present? token = Doorkeeper::AccessToken.by_token(password) + if valid_oauth_token?(token) user = User.find_by(id: token.resource_owner_id) - Gitlab::Auth::Result.new(user, nil, :oauth, full_authentication_abilities) + Gitlab::Auth::Result.new(user, nil, :oauth, full_api_abilities) end end end @@ -121,17 +126,26 @@ module Gitlab token = PersonalAccessTokensFinder.new(state: 'active').find_by(token: password) - if token && valid_api_token?(token) - Gitlab::Auth::Result.new(token.user, nil, :personal_token, full_authentication_abilities) + if token && valid_scoped_token?(token, scopes: AVAILABLE_SCOPES.map(&:to_s)) + Gitlab::Auth::Result.new(token.user, nil, :personal_token, abilities_for_scope(token.scopes)) end end def valid_oauth_token?(token) - token && token.accessible? && valid_api_token?(token) + token && token.accessible? && valid_scoped_token?(token) end - def valid_api_token?(token) - AccessTokenValidationService.new(token).include_any_scope?(['api']) + def valid_scoped_token?(token, scopes: %w[api]) + AccessTokenValidationService.new(token).include_any_scope?(scopes) + end + + def abilities_for_scope(scopes) + abilities = Set.new + + abilities.merge(full_api_abilities) if scopes.include?("api") + abilities << :read_container_image if scopes.include?("read_registry") + + abilities.to_a end def lfs_token_check(login, password) @@ -150,9 +164,9 @@ module Gitlab authentication_abilities = if token_handler.user? - full_authentication_abilities + full_api_abilities else - read_authentication_abilities + read_api_abilities end if Devise.secure_compare(token_handler.token, password) @@ -188,7 +202,7 @@ module Gitlab ] end - def read_authentication_abilities + def read_api_abilities [ :read_project, :download_code, @@ -196,8 +210,8 @@ module Gitlab ] end - def full_authentication_abilities - read_authentication_abilities + [ + def full_api_abilities + read_api_abilities + [ :push_code, :create_container_image ] |