forked from doorkeeper-gem/doorkeeper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pre_authorization.rb
118 lines (96 loc) · 3.13 KB
/
pre_authorization.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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# frozen_string_literal: true
module Doorkeeper
module OAuth
class PreAuthorization
include Validations
validate :response_type, error: :unsupported_response_type
validate :client, error: :invalid_client
validate :scopes, error: :invalid_scope
validate :redirect_uri, error: :invalid_redirect_uri
validate :code_challenge_method, error: :invalid_code_challenge_method
validate :client_supports_grant_flow, error: :unauthorized_client
attr_accessor :server, :client, :response_type, :redirect_uri, :state,
:code_challenge, :code_challenge_method
attr_writer :scope
def initialize(server, attrs = {})
@server = server
@client_id = attrs[:client_id]
@response_type = attrs[:response_type]
@redirect_uri = attrs[:redirect_uri]
@scope = attrs[:scope]
@state = attrs[:state]
@code_challenge = attrs[:code_challenge]
@code_challenge_method = attrs[:code_challenge_method]
end
def authorizable?
valid?
end
def validate_client_supports_grant_flow
Doorkeeper.configuration.allow_grant_flow_for_client?(grant_type, client.application)
end
def scopes
Scopes.from_string scope
end
def scope
@scope.presence || build_scopes
end
def error_response
OAuth::ErrorResponse.from_request(self)
end
def as_json(attributes = {})
return pre_auth_hash.merge(attributes.to_h) if attributes.respond_to?(:to_h)
pre_auth_hash
end
private
def build_scopes
client_scopes = client.scopes
if client_scopes.blank?
server.default_scopes.to_s
else
(server.default_scopes & client_scopes).to_s
end
end
def validate_response_type
server.authorization_response_types.include?(response_type)
end
def validate_client
@client = OAuth::Client.find(@client_id)
@client.present?
end
def validate_scopes
return true if scope.blank?
Helpers::ScopeChecker.valid?(
scope_str: scope,
server_scopes: server.scopes,
app_scopes: client.scopes,
grant_type: grant_type
)
end
def grant_type
response_type == "code" ? AUTHORIZATION_CODE : IMPLICIT
end
def validate_redirect_uri
return false if redirect_uri.blank?
Helpers::URIChecker.valid_for_authorization?(
redirect_uri,
client.redirect_uri
)
end
def validate_code_challenge_method
code_challenge.blank? ||
(code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
end
def pre_auth_hash
{
client_id: client.uid,
redirect_uri: redirect_uri,
state: state,
response_type: response_type,
scope: scope,
client_name: client.name,
status: I18n.t("doorkeeper.pre_authorization.status"),
}
end
end
end
end