diff options
author | Francisco Lopez <fjlopez@gitlab.com> | 2017-11-07 10:52:05 +0100 |
---|---|---|
committer | Francisco Lopez <fjlopez@gitlab.com> | 2017-11-17 10:00:08 +0100 |
commit | d948e6791300b14d18b95881290ccfcba7928ea0 (patch) | |
tree | e752174260df3d61daad098b8dd21acc29643c58 | |
parent | 987e7b774403e0ebd7ebe2faed4f2ed276504a69 (diff) | |
download | gitlab-ce-d948e6791300b14d18b95881290ccfcba7928ea0.tar.gz |
First refactor
-rw-r--r-- | lib/api/api_guard.rb | 58 | ||||
-rw-r--r-- | lib/gitlab/auth/request_authenticator.rb | 47 | ||||
-rw-r--r-- | lib/gitlab/auth/user_auth_finders.rb | 92 | ||||
-rw-r--r-- | spec/requests/api/helpers_spec.rb | 1 |
4 files changed, 116 insertions, 82 deletions
diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index c1c0d344917..0a93e71858e 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -74,43 +74,27 @@ module API private - def find_user_from_access_token - return unless access_token - - validate_access_token! - - access_token.user || raise(UnauthorizedError) - end - - # Check the Rails session for valid authentication details - def find_user_from_warden - warden.try(:authenticate) if verified_request? - end - - def warden - env['warden'] - end - - # Check if the request is GET/HEAD, or if CSRF token is valid. - def verified_request? - Gitlab::RequestForgeryProtection.verified?(env) - end - - def find_oauth_access_token - token = Doorkeeper::OAuth::Token.from_request(doorkeeper_request, *Doorkeeper.configuration.access_token_methods) - return unless token - - # Expiration, revocation and scopes are verified in `find_user_by_access_token` - access_token = OauthAccessToken.by_token(token) - raise UnauthorizedError unless access_token - - access_token.revoke_previous_refresh_token! - access_token + def raise_unauthorized_error! + raise UnauthorizedError end - def find_personal_access_token - token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - return unless token.present? + # If token is presented and valid, then it sets @current_user. + # + # If the token does not have sufficient scopes to cover the requred scopes, + # then it raises InsufficientScopeError. + # + # If the token is expired, then it raises ExpiredError. + # + # If the token is revoked, then it raises RevokedError. + # + # If the token is not found (nil), then it returns nil + # + # Arguments: + # + # scopes: (optional) scopes required for this guard. + # Defaults to empty array. + def find_user_by_access_token(access_token) + scopes = scopes_registered_for_endpoint # Expiration, revocation and scopes are verified in `find_user_by_access_token` access_token = PersonalAccessToken.find_by(token: token) @@ -119,10 +103,6 @@ module API access_token end - def doorkeeper_request - @doorkeeper_request ||= ActionDispatch::Request.new(env) - end - # An array of scopes that were registered (using `allow_access_with_scope`) # for the current endpoint class. It also returns scopes registered on # `API::API`, since these are meant to apply to all API routes. diff --git a/lib/gitlab/auth/request_authenticator.rb b/lib/gitlab/auth/request_authenticator.rb index 999104f91f5..123a39dea75 100644 --- a/lib/gitlab/auth/request_authenticator.rb +++ b/lib/gitlab/auth/request_authenticator.rb @@ -3,6 +3,10 @@ module Gitlab module Auth class RequestAuthenticator + include UserAuthFinders + + attr_reader :request + def initialize(request) @request = ensure_action_dispatch_request(request) end @@ -14,49 +18,6 @@ module Gitlab def find_sessionless_user find_user_by_private_token || find_user_by_rss_token || find_user_by_oauth_token end - - private - - def find_session_user - @request.env['warden']&.authenticate if verified_request? - end - - def find_user_by_private_token - token = @request.params[:private_token].presence || @request.headers['PRIVATE-TOKEN'].presence - return unless token.present? - - User.find_by_authentication_token(token) || User.find_by_personal_access_token(token) - end - - def find_user_by_rss_token - return unless @request.path.ends_with?('atom') || @request.format == 'atom' - - token = @request.params[:rss_token].presence - return unless token.present? - - User.find_by_rss_token(token) - end - - def find_user_by_oauth_token - access_token = find_oauth_access_token - access_token&.user - end - - def find_oauth_access_token - token = Doorkeeper::OAuth::Token.from_request(@request, *Doorkeeper.configuration.access_token_methods) - OauthAccessToken.by_token(token) if token - end - - # Check if the request is GET/HEAD, or if CSRF token is valid. - def verified_request? - Gitlab::RequestForgeryProtection.verified?(@request.env) - end - - def ensure_action_dispatch_request(request) - return request if request.is_a?(ActionDispatch::Request) - - ActionDispatch::Request.new(request.env) - end end end end diff --git a/lib/gitlab/auth/user_auth_finders.rb b/lib/gitlab/auth/user_auth_finders.rb new file mode 100644 index 00000000000..2f4aeff14ac --- /dev/null +++ b/lib/gitlab/auth/user_auth_finders.rb @@ -0,0 +1,92 @@ +module Gitlab + module Auth + module UserAuthFinders + # Check the Rails session for valid authentication details + def find_session_user + request.env['warden']&.authenticate if verified_request? + end + + def find_user_by_private_token + token = private_token + return unless token.present? + + user = + find_user_by_authentication_token(token) || + find_user_by_personal_access_token(token) + + raise_unauthorized_error! unless user + + user + end + + def private_token + request.params[:private_token].presence || + request.headers['PRIVATE-TOKEN'].presence + end + + def find_user_by_authentication_token(token_string) + User.find_by_authentication_token(token_string) + end + + def find_user_by_personal_access_token(token_string) + access_token = PersonalAccessToken.find_by_token(token_string) + return unless access_token + + find_user_by_access_token(access_token) + end + + def find_user_by_rss_token + return unless request.path.ends_with?('atom') || request.format.atom? + + token = request.params[:rss_token].presence + return unless token.present? + + user = User.find_by_rss_token(token) + raise_unauthorized_error! unless user + + user + end + + def find_user_by_oauth_token + access_token = find_oauth_access_token + + return unless access_token + + find_user_by_access_token(access_token) + end + + def find_oauth_access_token + return @oauth_access_token if defined?(@oauth_access_token) + + current_request = ensure_action_dispatch_request(request) + token = Doorkeeper::OAuth::Token.from_request(current_request, *Doorkeeper.configuration.access_token_methods) + return @oauth_access_token = nil unless token + + @oauth_access_token = OauthAccessToken.by_token(token) + raise_unauthorized_error! unless @oauth_access_token + + @oauth_access_token.revoke_previous_refresh_token! + @oauth_access_token + end + + def find_user_by_access_token(access_token) + access_token&.user + end + + # Check if the request is GET/HEAD, or if CSRF token is valid. + def verified_request? + Gitlab::RequestForgeryProtection.verified?(request.env) + end + + def ensure_action_dispatch_request(request) + return request if request.is_a?(ActionDispatch::Request) + + ActionDispatch::Request.new(request.env) + end + + def raise_unauthorized_error! + return nil + end + end + end +end diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index 6c0996c543d..fc1444e4018 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -23,6 +23,7 @@ describe API::Helpers do } end let(:header) { } + let(:request) { Grape::Request.new(env)} before do allow_any_instance_of(self.class).to receive(:options).and_return({}) |