-
Notifications
You must be signed in to change notification settings - Fork 234
/
doorkeeper.rb
42 lines (34 loc) · 1.37 KB
/
doorkeeper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# frozen_string_literal: true
# Strategy that allows login via OAuth baerer token
class Warden::Strategies::Doorkeeper < ::Warden::Strategies::Base
KEY = :doorkeeper
def valid?
request.authorization.to_s.start_with?("Bearer ")
end
def authenticate!
token = ::Doorkeeper::OAuth::Token.authenticate(request, :from_bearer_authorization)
requested_scopes = request.env.fetch('requested_oauth_scopes')
if !token
halt_json "Bearer token is invalid"
elsif !token.accessible?
halt_json "Bearer token is expired"
elsif !token.acceptable?(requested_scopes)
sentence = requested_scopes.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')
halt_json "Bearer token needs scope #{sentence}"
elsif !(user = User.find_by_id(token.resource_owner_id))
halt_json "Bearer token belongs to deleted user #{token.resource_owner_id}"
else
token.update_column(:last_used_at, Time.now) unless token.last_used_at&.> 1.minute.ago
request.session_options[:skip] = true # do not store user in session
success! user
end
end
private
def request
ActionDispatch::Request.new(super.env)
end
def halt_json(message)
custom! [401, {'Content-Type' => 'application/json'}, [{error: message}.to_json]]
end
end
Warden::Strategies.add(Warden::Strategies::Doorkeeper::KEY, Warden::Strategies::Doorkeeper)