-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
authorizations_controller.rb
139 lines (117 loc) · 3.29 KB
/
authorizations_controller.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# frozen_string_literal: true
module Doorkeeper
class AuthorizationsController < Doorkeeper::ApplicationController
before_action :authenticate_resource_owner!
def new
if pre_auth.authorizable?
render_success
else
render_error
end
end
def create
redirect_or_render authorize_response
end
def destroy
redirect_or_render authorization.deny
end
private
def render_success
if skip_authorization? || matching_token?
redirect_or_render(authorize_response)
elsif Doorkeeper.configuration.api_only
render json: pre_auth
else
render :new
end
end
def render_error
if Doorkeeper.configuration.api_only
render json: pre_auth.error_response.body,
status: :bad_request
else
render :error
end
end
# Active access token issued for the same client and resource owner with
# the same set of the scopes exists?
def matching_token?
Doorkeeper.config.access_token_model.matching_token_for(
pre_auth.client,
current_resource_owner,
pre_auth.scopes,
)
end
def redirect_or_render(auth)
if auth.redirectable?
if Doorkeeper.configuration.api_only
if pre_auth.form_post_response?
render(
json: { status: :post, redirect_uri: pre_auth.redirect_uri, body: auth.body },
status: auth.status,
)
else
render(
json: { status: :redirect, redirect_uri: auth.redirect_uri },
status: auth.status,
)
end
elsif pre_auth.form_post_response?
render :form_post
else
redirect_to auth.redirect_uri, allow_other_host: true
end
else
render json: auth.body, status: auth.status
end
end
def pre_auth
@pre_auth ||= OAuth::PreAuthorization.new(
Doorkeeper.configuration,
pre_auth_params,
current_resource_owner,
)
end
def pre_auth_params
params.slice(*pre_auth_param_fields).permit(*pre_auth_param_fields)
end
def pre_auth_param_fields
%i[
client_id
code_challenge
code_challenge_method
response_type
response_mode
redirect_uri
scope
state
]
end
def authorization
@authorization ||= strategy.request
end
def strategy
@strategy ||= server.authorization_request(pre_auth.response_type)
end
def authorize_response
@authorize_response ||= begin
return pre_auth.error_response unless pre_auth.authorizable?
context = build_context(pre_auth: pre_auth)
before_successful_authorization(context)
auth = strategy.authorize
context = build_context(auth: auth)
after_successful_authorization(context)
auth
end
end
def build_context(**attributes)
Doorkeeper::OAuth::Hooks::Context.new(**attributes)
end
def before_successful_authorization(context = nil)
Doorkeeper.config.before_successful_authorization.call(self, context)
end
def after_successful_authorization(context)
Doorkeeper.config.after_successful_authorization.call(self, context)
end
end
end