diff options
-rw-r--r-- | lib/api/api_guard.rb | 35 | ||||
-rw-r--r-- | lib/api/helpers.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/auth/user_auth_finders.rb | 32 | ||||
-rw-r--r-- | spec/lib/gitlab/auth/request_authenticator_spec.rb | 4 | ||||
-rw-r--r-- | spec/lib/gitlab/auth/user_auth_finders_spec.rb | 20 | ||||
-rw-r--r-- | spec/requests/api/helpers_spec.rb | 8 |
6 files changed, 52 insertions, 49 deletions
diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index 0caf2aa25bc..a07015406b1 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -93,8 +93,11 @@ module API private def install_error_responders(base) - error_classes = [MissingTokenError, TokenNotFoundError, - ExpiredError, RevokedError, InsufficientScopeError] + error_classes = [Gitlab::Auth::UserAuthFinders::MissingTokenError, + Gitlab::Auth::UserAuthFinders::TokenNotFoundError, + Gitlab::Auth::UserAuthFinders::ExpiredError, + Gitlab::Auth::UserAuthFinders::RevokedError, + Gitlab::Auth::UserAuthFinders::InsufficientScopeError] base.__send__(:rescue_from, *error_classes, oauth2_bearer_token_error_handler) # rubocop:disable GitlabSecurity/PublicSend end @@ -103,25 +106,25 @@ module API proc do |e| response = case e - when MissingTokenError + when Gitlab::Auth::UserAuthFinders::MissingTokenError Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new - when TokenNotFoundError + when Gitlab::Auth::UserAuthFinders::TokenNotFoundError Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( :invalid_token, "Bad Access Token.") - when ExpiredError + when Gitlab::Auth::UserAuthFinders::ExpiredError Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( :invalid_token, "Token is expired. You can either do re-authorization or token refresh.") - when RevokedError + when Gitlab::Auth::UserAuthFinders::RevokedError Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( :invalid_token, "Token was revoked. You have to re-authorize from the user.") - when InsufficientScopeError + when Gitlab::Auth::UserAuthFinders::InsufficientScopeError # FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2) # does not include WWW-Authenticate header, which breaks the standard. Rack::OAuth2::Server::Resource::Bearer::Forbidden.new( @@ -134,23 +137,5 @@ module API end end end - - # - # Exceptions - # - - AuthenticationException = Class.new(StandardError) - MissingTokenError = Class.new(AuthenticationException) - TokenNotFoundError = Class.new(AuthenticationException) - ExpiredError = Class.new(AuthenticationException) - RevokedError = Class.new(AuthenticationException) - UnauthorizedError = Class.new(AuthenticationException) - - class InsufficientScopeError < AuthenticationException - attr_reader :scopes - def initialize(scopes) - @scopes = scopes.map { |s| s.try(:name) || s } - end - end end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3c8960cb1ab..09e9753b010 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -398,7 +398,7 @@ module API begin @initial_current_user = Gitlab::Auth::UniqueIpsLimiter.limit_user! { find_current_user! } - rescue APIGuard::UnauthorizedError + rescue Gitlab::Auth::UserAuthFinders::UnauthorizedError unauthorized! end end diff --git a/lib/gitlab/auth/user_auth_finders.rb b/lib/gitlab/auth/user_auth_finders.rb index 06b934fa042..6ee957a0cd6 100644 --- a/lib/gitlab/auth/user_auth_finders.rb +++ b/lib/gitlab/auth/user_auth_finders.rb @@ -4,6 +4,24 @@ module Gitlab PRIVATE_TOKEN_HEADER = 'HTTP_PRIVATE_TOKEN'.freeze PRIVATE_TOKEN_PARAM = :private_token + # + # Exceptions + # + + AuthenticationException = Class.new(StandardError) + MissingTokenError = Class.new(AuthenticationException) + TokenNotFoundError = Class.new(AuthenticationException) + ExpiredError = Class.new(AuthenticationException) + RevokedError = Class.new(AuthenticationException) + UnauthorizedError = Class.new(AuthenticationException) + + class InsufficientScopeError < AuthenticationException + attr_reader :scopes + def initialize(scopes) + @scopes = scopes.map { |s| s.try(:name) || s } + end + end + # Check the Rails session for valid authentication details def find_user_from_warden current_request.env['warden']&.authenticate if verified_request? @@ -15,7 +33,7 @@ module Gitlab token = current_request.params[:rss_token].presence return unless token - User.find_by_rss_token(token) || raise(API::APIGuard::UnauthorizedError) + User.find_by_rss_token(token) || raise(UnauthorizedError) end def find_user_from_access_token @@ -23,7 +41,7 @@ module Gitlab validate_access_token! - access_token.user || raise(API::APIGuard::UnauthorizedError) + access_token.user || raise(UnauthorizedError) end def validate_access_token!(scopes: []) @@ -31,11 +49,11 @@ module Gitlab case AccessTokenValidationService.new(access_token, request: request).validate(scopes: scopes) when AccessTokenValidationService::INSUFFICIENT_SCOPE - raise API::APIGuard::InsufficientScopeError.new(scopes) + raise InsufficientScopeError.new(scopes) when AccessTokenValidationService::EXPIRED - raise API::APIGuard::ExpiredError + raise ExpiredError when AccessTokenValidationService::REVOKED - raise API::APIGuard::RevokedError + raise RevokedError end end @@ -55,7 +73,7 @@ module Gitlab return unless token # Expiration, revocation and scopes are verified in `validate_access_token!` - PersonalAccessToken.find_by(token: token) || raise(API::APIGuard::UnauthorizedError) + PersonalAccessToken.find_by(token: token) || raise(UnauthorizedError) end def find_oauth_access_token @@ -64,7 +82,7 @@ module Gitlab # Expiration, revocation and scopes are verified in `validate_access_token!` oauth_token = OauthAccessToken.by_token(token) - raise API::APIGuard::UnauthorizedError unless oauth_token + raise UnauthorizedError unless oauth_token oauth_token.revoke_previous_refresh_token! oauth_token diff --git a/spec/lib/gitlab/auth/request_authenticator_spec.rb b/spec/lib/gitlab/auth/request_authenticator_spec.rb index 4ddebed119f..6b8a8759314 100644 --- a/spec/lib/gitlab/auth/request_authenticator_spec.rb +++ b/spec/lib/gitlab/auth/request_authenticator_spec.rb @@ -33,7 +33,7 @@ describe Gitlab::Auth::RequestAuthenticator do end it 'bubbles up exceptions' do - allow_any_instance_of(described_class).to receive(:find_user_from_warden).and_raise(API::APIGuard::UnauthorizedError) + allow_any_instance_of(described_class).to receive(:find_user_from_warden).and_raise(Gitlab::Auth::UserAuthFinders::UnauthorizedError) end end @@ -59,7 +59,7 @@ describe Gitlab::Auth::RequestAuthenticator do end it 'rescue API::APIGuard::AuthenticationException exceptions' do - allow_any_instance_of(described_class).to receive(:find_user_from_access_token).and_raise(API::APIGuard::UnauthorizedError) + allow_any_instance_of(described_class).to receive(:find_user_from_access_token).and_raise(Gitlab::Auth::UserAuthFinders::UnauthorizedError) expect(subject.find_sessionless_user).to be_blank end diff --git a/spec/lib/gitlab/auth/user_auth_finders_spec.rb b/spec/lib/gitlab/auth/user_auth_finders_spec.rb index 1b3bc2fc65c..522e82c5912 100644 --- a/spec/lib/gitlab/auth/user_auth_finders_spec.rb +++ b/spec/lib/gitlab/auth/user_auth_finders_spec.rb @@ -65,7 +65,7 @@ describe Gitlab::Auth::UserAuthFinders do it 'returns exception if invalid rss_token' do set_param(:rss_token, 'invalid_token') - expect { find_user_from_rss_token }.to raise_error(API::APIGuard::UnauthorizedError) + expect { find_user_from_rss_token }.to raise_error(Gitlab::Auth::UserAuthFinders::UnauthorizedError) end end @@ -96,7 +96,7 @@ describe Gitlab::Auth::UserAuthFinders do env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token allow_any_instance_of(PersonalAccessToken).to receive(:user).and_return(nil) - expect { find_user_from_access_token }.to raise_error(API::APIGuard::UnauthorizedError) + expect { find_user_from_access_token }.to raise_error(Gitlab::Auth::UserAuthFinders::UnauthorizedError) end end end @@ -127,7 +127,7 @@ describe Gitlab::Auth::UserAuthFinders do it 'returns exception if invalid personal_access_token' do env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = 'invalid_token' - expect { find_personal_access_token }.to raise_error(API::APIGuard::UnauthorizedError) + expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UserAuthFinders::UnauthorizedError) end end @@ -158,7 +158,7 @@ describe Gitlab::Auth::UserAuthFinders do it 'returns exception if invalid oauth_access_token' do env['HTTP_AUTHORIZATION'] = "Bearer invalid_token" - expect { find_oauth_access_token }.to raise_error(API::APIGuard::UnauthorizedError) + expect { find_oauth_access_token }.to raise_error(Gitlab::Auth::UserAuthFinders::UnauthorizedError) end end @@ -174,20 +174,20 @@ describe Gitlab::Auth::UserAuthFinders do allow_any_instance_of(described_class).to receive(:access_token).and_return(personal_access_token) end - it 'returns API::APIGuard::ExpiredError if token expired' do + it 'returns Gitlab::Auth::UserAuthFinders::ExpiredError if token expired' do personal_access_token.expires_at = 1.day.ago - expect { validate_access_token! }.to raise_error(API::APIGuard::ExpiredError) + expect { validate_access_token! }.to raise_error(Gitlab::Auth::UserAuthFinders::ExpiredError) end - it 'returns API::APIGuard::RevokedError if token revoked' do + it 'returns Gitlab::Auth::UserAuthFinders::RevokedError if token revoked' do personal_access_token.revoke! - expect { validate_access_token! }.to raise_error(API::APIGuard::RevokedError) + expect { validate_access_token! }.to raise_error(Gitlab::Auth::UserAuthFinders::RevokedError) end - it 'returns API::APIGuard::InsufficientScopeError if invalid token scope' do - expect { validate_access_token!(scopes: [:sudo]) }.to raise_error(API::APIGuard::InsufficientScopeError) + it 'returns Gitlab::Auth::UserAuthFinders::InsufficientScopeError if invalid token scope' do + expect { validate_access_token!(scopes: [:sudo]) }.to raise_error(Gitlab::Auth::UserAuthFinders::InsufficientScopeError) end end end diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index dbb82136919..919df575c6e 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -166,21 +166,21 @@ describe API::Helpers do personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user']) env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token - expect { current_user }.to raise_error API::APIGuard::InsufficientScopeError + expect { current_user }.to raise_error Gitlab::Auth::UserAuthFinders::InsufficientScopeError end it 'does not allow revoked tokens' do personal_access_token.revoke! env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token - expect { current_user }.to raise_error API::APIGuard::RevokedError + expect { current_user }.to raise_error Gitlab::Auth::UserAuthFinders::RevokedError end it 'does not allow expired tokens' do personal_access_token.update_attributes!(expires_at: 1.day.ago) env[Gitlab::Auth::UserAuthFinders::PRIVATE_TOKEN_HEADER] = personal_access_token.token - expect { current_user }.to raise_error API::APIGuard::ExpiredError + expect { current_user }.to raise_error Gitlab::Auth::UserAuthFinders::ExpiredError end end end @@ -392,7 +392,7 @@ describe API::Helpers do end it 'raises an error' do - expect { current_user }.to raise_error API::APIGuard::InsufficientScopeError + expect { current_user }.to raise_error Gitlab::Auth::UserAuthFinders::InsufficientScopeError end end end |