summaryrefslogtreecommitdiff
path: root/lib
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
parentd87030714a654b0dfa47aa6b38eb970731e7a04e (diff)
downloadgitlab-ce-43a682ccaa694d2a14f3d639d66708057859a628.tar.gz
Fix OAuth API and RSS rate limiting
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/auth.rb30
-rw-r--r--lib/gitlab/auth/request_authenticator.rb64
2 files changed, 64 insertions, 30 deletions
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 8f39885c608..cbbc51db99e 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -82,36 +82,6 @@ module Gitlab
end
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(request)
- 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(request)
- return unless request.params['format'] == 'atom'
-
- token = request.params['rss_token'].presence
-
- return unless token.present?
-
- User.find_by_rss_token(token)
- end
-
- def find_session_user(request)
- request.env['warden']&.authenticate
- end
-
- def find_sessionless_user(request)
- find_user_by_private_token(request) || find_user_by_rss_token(request)
- end
-
private
def service_request_check(login, password, project)
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