summaryrefslogtreecommitdiff
path: root/lib/gitlab/auth
diff options
context:
space:
mode:
authorMichael Kozono <mkozono@gmail.com>2017-10-13 17:05:18 -0700
committerFrancisco Lopez <fjlopez@gitlab.com>2017-11-17 09:58:18 +0100
commit43a682ccaa694d2a14f3d639d66708057859a628 (patch)
treed77db36eb817035efed3fdb2ec163615bdbc9336 /lib/gitlab/auth
parentd87030714a654b0dfa47aa6b38eb970731e7a04e (diff)
downloadgitlab-ce-43a682ccaa694d2a14f3d639d66708057859a628.tar.gz
Fix OAuth API and RSS rate limiting
Diffstat (limited to 'lib/gitlab/auth')
-rw-r--r--lib/gitlab/auth/request_authenticator.rb64
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/gitlab/auth/request_authenticator.rb b/lib/gitlab/auth/request_authenticator.rb
new file mode 100644
index 00000000000..d3da4cc2d2b
--- /dev/null
+++ b/lib/gitlab/auth/request_authenticator.rb
@@ -0,0 +1,64 @@
+# Use for authentication only, in particular for Rack::Attack.
+# Does not perform authorization of scopes, etc.
+module Gitlab
+ module Auth
+ class RequestAuthenticator
+ def initialize(request)
+ @request = request
+ end
+
+ def user
+ find_sessionless_user || find_session_user
+ end
+
+ 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
+
+ # request may be Rack::Attack::Request which is just a Rack::Request, so
+ # we cannot use ActionDispatch::Request methods.
+ def find_user_by_private_token
+ token = @request.params['private_token'].presence || @request.env['HTTP_PRIVATE_TOKEN'].presence
+ return unless token.present?
+
+ User.find_by_authentication_token(token) || User.find_by_personal_access_token(token)
+ end
+
+ # request may be Rack::Attack::Request which is just a Rack::Request, so
+ # we cannot use ActionDispatch::Request methods.
+ def find_user_by_rss_token
+ return unless @request.path.ends_with?('atom') || @request.env['HTTP_ACCEPT'] == 'application/atom+xml'
+
+ 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(doorkeeper_request, *Doorkeeper.configuration.access_token_methods)
+ OauthAccessToken.by_token(token) if token
+ end
+
+ def doorkeeper_request
+ ActionDispatch::Request.new(@request.env)
+ end
+
+ # Check if the request is GET/HEAD, or if CSRF token is valid.
+ def verified_request?
+ Gitlab::RequestForgeryProtection.verified?(@request.env)
+ end
+ end
+ end
+end