rodauth-oauth 0.10.4 → 1.0.0.pre.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIGRATION-GUIDE-v1.md +286 -0
- data/README.md +22 -30
- data/doc/release_notes/1_0_0_beta1.md +38 -0
- data/lib/generators/rodauth/oauth/install_generator.rb +0 -1
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +4 -6
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +1 -1
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +2 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +1 -6
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +0 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb +41 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +2 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_grants.html.erb +37 -0
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +18 -29
- data/lib/rodauth/features/oauth_application_management.rb +59 -72
- data/lib/rodauth/features/oauth_assertion_base.rb +19 -23
- data/lib/rodauth/features/oauth_authorization_code_grant.rb +35 -88
- data/lib/rodauth/features/oauth_authorize_base.rb +103 -20
- data/lib/rodauth/features/oauth_base.rb +365 -302
- data/lib/rodauth/features/oauth_client_credentials_grant.rb +20 -18
- data/lib/rodauth/features/{oauth_device_grant.rb → oauth_device_code_grant.rb} +62 -73
- data/lib/rodauth/features/oauth_dynamic_client_registration.rb +46 -28
- data/lib/rodauth/features/oauth_grant_management.rb +70 -0
- data/lib/rodauth/features/oauth_implicit_grant.rb +25 -24
- data/lib/rodauth/features/oauth_jwt.rb +52 -688
- data/lib/rodauth/features/oauth_jwt_base.rb +435 -0
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +45 -17
- data/lib/rodauth/features/oauth_jwt_jwks.rb +47 -0
- data/lib/rodauth/features/oauth_jwt_secured_authorization_request.rb +62 -0
- data/lib/rodauth/features/oauth_management_base.rb +2 -0
- data/lib/rodauth/features/oauth_pkce.rb +22 -26
- data/lib/rodauth/features/oauth_resource_indicators.rb +33 -21
- data/lib/rodauth/features/oauth_resource_server.rb +59 -0
- data/lib/rodauth/features/oauth_saml_bearer_grant.rb +5 -1
- data/lib/rodauth/features/oauth_token_introspection.rb +76 -46
- data/lib/rodauth/features/oauth_token_revocation.rb +46 -33
- data/lib/rodauth/features/oidc.rb +188 -95
- data/lib/rodauth/features/oidc_dynamic_client_registration.rb +89 -53
- data/lib/rodauth/oauth/database_extensions.rb +8 -6
- data/lib/rodauth/oauth/http_extensions.rb +61 -0
- data/lib/rodauth/oauth/railtie.rb +20 -0
- data/lib/rodauth/oauth/version.rb +1 -1
- data/lib/rodauth/oauth.rb +29 -1
- data/locales/en.yml +32 -22
- data/locales/pt.yml +32 -22
- data/templates/authorize.str +19 -24
- data/templates/device_search.str +1 -1
- data/templates/device_verification.str +2 -2
- data/templates/jwks_field.str +1 -0
- data/templates/new_oauth_application.str +1 -2
- data/templates/oauth_application.str +2 -2
- data/templates/oauth_application_oauth_grants.str +54 -0
- data/templates/oauth_applications.str +2 -2
- data/templates/oauth_grants.str +52 -0
- metadata +20 -16
- data/lib/generators/rodauth/oauth/templates/app/models/oauth_token.rb +0 -4
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +0 -39
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +0 -35
- data/lib/rodauth/features/oauth.rb +0 -9
- data/lib/rodauth/features/oauth_http_mac.rb +0 -86
- data/lib/rodauth/features/oauth_token_management.rb +0 -81
- data/lib/rodauth/oauth/refinements.rb +0 -48
- data/templates/jwt_public_key_field.str +0 -4
- data/templates/oauth_application_oauth_tokens.str +0 -52
- data/templates/oauth_tokens.str +0 -50
@@ -24,6 +24,19 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
24
24
|
# t.string :contacts, null: true
|
25
25
|
# t.string :software_id, null: true
|
26
26
|
# t.string :software_version, null: true
|
27
|
+
# oidc extra params
|
28
|
+
# t.string :sector_identifier_uri, null: true
|
29
|
+
# t.string :application_type, null: true
|
30
|
+
# t.string :subject_type, null: true
|
31
|
+
# t.string :id_token_signed_response_alg, null: true
|
32
|
+
# t.string :id_token_encrypted_response_alg, null: true
|
33
|
+
# t.string :id_token_encrypted_response_enc, null: true
|
34
|
+
# t.string :userinfo_signed_response_alg, null: true
|
35
|
+
# t.string :userinfo_encrypted_response_alg, null: true
|
36
|
+
# t.string :userinfo_encrypted_response_enc, null: true
|
37
|
+
# t.string :request_object_signing_alg, null: true
|
38
|
+
# t.string :request_object_encryption_alg, null: true
|
39
|
+
# t.string :request_object_encryption_enc, null: true
|
27
40
|
# JWT/OIDC per application signing verification
|
28
41
|
# t.text :jwt_public_key, null: true
|
29
42
|
# RP-initiated logout
|
@@ -35,8 +48,11 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
35
48
|
t.foreign_key :accounts, column: :account_id
|
36
49
|
t.integer :oauth_application_id
|
37
50
|
t.foreign_key :oauth_applications, column: :oauth_application_id
|
38
|
-
t.string :
|
51
|
+
t.string :type, null: true
|
52
|
+
t.string :code, null: true
|
39
53
|
t.index(%i[oauth_application_id code], unique: true)
|
54
|
+
t.string :token, unique: true
|
55
|
+
t.string :refresh_token, unique: true
|
40
56
|
t.datetime :expires_in, null: false
|
41
57
|
t.string :redirect_uri
|
42
58
|
t.datetime :revoked_at
|
@@ -47,41 +63,14 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
47
63
|
# uncomment to enable PKCE
|
48
64
|
# t.string :code_challenge
|
49
65
|
# t.string :code_challenge_method
|
50
|
-
# uncomment to use OIDC nonce
|
51
|
-
# t.string :nonce
|
52
66
|
# device code grant
|
53
67
|
# t.string :user_code, null: true, unique: true
|
54
68
|
# t.datetime :last_polled_at, null: true
|
55
69
|
# when using :oauth_resource_indicators feature
|
56
70
|
# t.string :resource
|
57
|
-
end
|
58
|
-
|
59
|
-
create_table :oauth_tokens do |t|
|
60
|
-
t.integer :account_id
|
61
|
-
t.foreign_key :accounts, column: :account_id
|
62
|
-
t.integer :oauth_grant_id
|
63
|
-
t.foreign_key :oauth_grants, column: :oauth_grant_id
|
64
|
-
t.integer :oauth_token_id
|
65
|
-
t.foreign_key :oauth_tokens, column: :oauth_token_id
|
66
|
-
t.integer :oauth_application_id
|
67
|
-
t.foreign_key :oauth_applications, column: :oauth_application_id
|
68
|
-
t.string :token, null: false, token: true, unique: true
|
69
|
-
# uncomment if setting oauth_tokens_token_hash_column
|
70
|
-
# and delete the token column
|
71
|
-
# t.string :token_hash, token: true, unique: true
|
72
|
-
t.string :refresh_token, unique: true
|
73
|
-
# uncomment if setting oauth_tokens_refresh_token_hash_column
|
74
|
-
# and delete the refresh_token column
|
75
|
-
# t.string :refresh_token_hash, token: true, unique: true
|
76
|
-
t.datetime :expires_in, null: false
|
77
|
-
t.datetime :revoked_at
|
78
|
-
t.string :scopes, null: false
|
79
|
-
t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
80
71
|
# uncomment to use OIDC nonce
|
81
72
|
# t.string :nonce
|
82
|
-
# t.
|
83
|
-
# when using :oauth_resource_indicators feature
|
84
|
-
# t.string :resource
|
73
|
+
# t.string :acr
|
85
74
|
end
|
86
75
|
end
|
87
76
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rodauth/oauth"
|
4
|
+
|
3
5
|
module Rodauth
|
4
6
|
Feature.define(:oauth_application_management, :OauthApplicationManagement) do
|
5
|
-
depends :oauth_management_base
|
7
|
+
depends :oauth_management_base, :oauth_token_revocation
|
6
8
|
|
7
9
|
before "create_oauth_application"
|
8
10
|
after "create_oauth_application"
|
@@ -13,7 +15,7 @@ module Rodauth
|
|
13
15
|
view "oauth_applications", "Oauth Applications", "oauth_applications"
|
14
16
|
view "oauth_application", "Oauth Application", "oauth_application"
|
15
17
|
view "new_oauth_application", "New Oauth Application", "new_oauth_application"
|
16
|
-
view "
|
18
|
+
view "oauth_application_oauth_grants", "Oauth Application Grants", "oauth_application_oauth_grants"
|
17
19
|
|
18
20
|
# Application
|
19
21
|
APPLICATION_REQUIRED_PARAMS = %w[name scopes homepage_url redirect_uri client_secret].freeze
|
@@ -21,12 +23,6 @@ module Rodauth
|
|
21
23
|
|
22
24
|
(APPLICATION_REQUIRED_PARAMS + %w[description client_id]).each do |param|
|
23
25
|
auth_value_method :"oauth_application_#{param}_param", param
|
24
|
-
configuration_module_eval do
|
25
|
-
define_method :"#{param}_label" do
|
26
|
-
warn "#{__method__} is deprecated, switch to oauth_applications_#{__method__}_label"
|
27
|
-
__send__(:"oauth_applications_#{param}_label")
|
28
|
-
end
|
29
|
-
end
|
30
26
|
end
|
31
27
|
|
32
28
|
translatable_method :oauth_applications_name_label, "Name"
|
@@ -41,36 +37,42 @@ module Rodauth
|
|
41
37
|
translatable_method :oauth_applications_redirect_uri_label, "Redirect URI"
|
42
38
|
translatable_method :oauth_applications_client_secret_label, "Client Secret"
|
43
39
|
translatable_method :oauth_applications_client_id_label, "Client ID"
|
40
|
+
|
41
|
+
%w[type token refresh_token expires_in revoked_at].each do |param|
|
42
|
+
translatable_method :"oauth_grants_#{param}_label", param.gsub("_", " ").capitalize
|
43
|
+
end
|
44
|
+
|
44
45
|
button "Register", "oauth_application"
|
45
|
-
button "Revoke", "
|
46
|
+
button "Revoke", "oauth_grant_revoke"
|
46
47
|
|
47
|
-
auth_value_method :
|
48
|
+
auth_value_method :oauth_applications_oauth_grants_path, "oauth-grants"
|
48
49
|
auth_value_method :oauth_applications_route, "oauth-applications"
|
49
50
|
auth_value_method :oauth_applications_per_page, 20
|
50
51
|
auth_value_method :oauth_applications_id_pattern, Integer
|
51
|
-
auth_value_method :
|
52
|
+
auth_value_method :oauth_grants_per_page, 20
|
52
53
|
|
53
54
|
translatable_method :invalid_url_message, "Invalid URL"
|
54
55
|
translatable_method :null_error_message, "is not filled"
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
end
|
57
|
+
translatable_method :oauth_no_applications_text, "No oauth applications yet!"
|
58
|
+
translatable_method :oauth_no_grants_text, "No oauth grants yet!"
|
59
59
|
|
60
|
-
def oauth_applications_url(opts = {})
|
61
|
-
route_url(oauth_applications_route, opts)
|
62
|
-
end
|
63
60
|
auth_value_methods(
|
64
61
|
:oauth_application_path
|
65
62
|
)
|
66
63
|
|
64
|
+
def oauth_applications_path(opts = {})
|
65
|
+
route_path(oauth_applications_route, opts)
|
66
|
+
end
|
67
|
+
|
67
68
|
def oauth_application_path(id)
|
68
69
|
"#{oauth_applications_path}/#{id}"
|
69
70
|
end
|
70
71
|
|
71
72
|
# /oauth-applications routes
|
72
|
-
def
|
73
|
+
def load_oauth_application_management_routes
|
73
74
|
request.on(oauth_applications_route) do
|
75
|
+
check_csrf if check_csrf?
|
74
76
|
require_account
|
75
77
|
|
76
78
|
request.get "new" do
|
@@ -92,57 +94,52 @@ module Rodauth
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
request.on(
|
97
|
+
request.on(oauth_applications_oauth_grants_path) do
|
96
98
|
page = Integer(param_or_nil("page") || 1)
|
97
|
-
per_page = per_page_param(
|
98
|
-
|
99
|
-
.where(
|
100
|
-
.order(Sequel.desc(
|
101
|
-
scope.instance_variable_set(:@
|
102
|
-
request.
|
103
|
-
|
99
|
+
per_page = per_page_param(oauth_grants_per_page)
|
100
|
+
oauth_grants = db[oauth_grants_table]
|
101
|
+
.where(oauth_grants_oauth_application_id_column => id)
|
102
|
+
.order(Sequel.desc(oauth_grants_id_column))
|
103
|
+
scope.instance_variable_set(:@oauth_grants, oauth_grants.paginate(page, per_page))
|
104
|
+
request.is do
|
105
|
+
request.get do
|
106
|
+
oauth_application_oauth_grants_view
|
107
|
+
end
|
104
108
|
end
|
105
109
|
end
|
106
110
|
end
|
107
111
|
|
108
|
-
request.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
oauth_applications_view
|
117
|
-
end
|
112
|
+
request.is do
|
113
|
+
request.get do
|
114
|
+
page = Integer(param_or_nil("page") || 1)
|
115
|
+
per_page = per_page_param(oauth_applications_per_page)
|
116
|
+
scope.instance_variable_set(:@oauth_applications, db[oauth_applications_table]
|
117
|
+
.where(oauth_applications_account_id_column => account_id)
|
118
|
+
.order(Sequel.desc(oauth_applications_id_column))
|
119
|
+
.paginate(page, per_page))
|
118
120
|
|
119
|
-
|
120
|
-
|
121
|
-
validate_oauth_application_params
|
121
|
+
oauth_applications_view
|
122
|
+
end
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
request.post do
|
125
|
+
catch_error do
|
126
|
+
validate_oauth_application_params
|
127
|
+
|
128
|
+
transaction do
|
129
|
+
before_create_oauth_application
|
130
|
+
id = create_oauth_application
|
131
|
+
after_create_oauth_application
|
132
|
+
set_notice_flash create_oauth_application_notice_flash
|
133
|
+
redirect "#{request.path}/#{id}"
|
134
|
+
end
|
129
135
|
end
|
136
|
+
set_error_flash create_oauth_application_error_flash
|
137
|
+
new_oauth_application_view
|
130
138
|
end
|
131
|
-
set_error_flash create_oauth_application_error_flash
|
132
|
-
new_oauth_application_view
|
133
139
|
end
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
137
|
-
def check_csrf?
|
138
|
-
case request.path
|
139
|
-
when oauth_applications_path
|
140
|
-
only_json? ? false : super
|
141
|
-
else
|
142
|
-
super
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
143
|
private
|
147
144
|
|
148
145
|
def oauth_application_params
|
@@ -176,7 +173,7 @@ module Rodauth
|
|
176
173
|
elsif key == oauth_application_scopes_param
|
177
174
|
|
178
175
|
value.each do |scope|
|
179
|
-
set_field_error(key,
|
176
|
+
set_field_error(key, oauth_invalid_scope_message) unless oauth_application_scopes.include?(scope)
|
180
177
|
end
|
181
178
|
end
|
182
179
|
end
|
@@ -196,28 +193,18 @@ module Rodauth
|
|
196
193
|
redirect_uris = oauth_application_params[oauth_application_redirect_uri_param]
|
197
194
|
redirect_uris = redirect_uris.to_a.reject(&:empty?).join(" ") if redirect_uris.respond_to?(:each)
|
198
195
|
create_params[oauth_applications_redirect_uri_column] = redirect_uris unless redirect_uris.empty?
|
199
|
-
# set client ID/secret pairs
|
200
196
|
|
201
|
-
|
202
|
-
|
203
|
-
secret_hash(oauth_application_params[oauth_application_client_secret_param])
|
197
|
+
# set client ID/secret pairs
|
198
|
+
set_client_secret(create_params, oauth_application_params[oauth_application_client_secret_param])
|
204
199
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
oauth_application_default_scope
|
209
|
-
end
|
200
|
+
if create_params[oauth_applications_scopes_column]
|
201
|
+
create_params[oauth_applications_scopes_column] = create_params[oauth_applications_scopes_column].join(oauth_scope_separator)
|
202
|
+
end
|
210
203
|
|
211
204
|
rescue_from_uniqueness_error do
|
212
205
|
create_params[oauth_applications_client_id_column] = oauth_unique_id_generator
|
213
206
|
db[oauth_applications_table].insert(create_params)
|
214
207
|
end
|
215
208
|
end
|
216
|
-
|
217
|
-
def oauth_server_metadata_body(*)
|
218
|
-
super.tap do |data|
|
219
|
-
data[:registration_endpoint] = oauth_applications_url
|
220
|
-
end
|
221
|
-
end
|
222
209
|
end
|
223
210
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rodauth/oauth
|
3
|
+
require "rodauth/oauth"
|
4
4
|
|
5
5
|
module Rodauth
|
6
6
|
Feature.define(:oauth_assertion_base, :OauthAssertionBase) do
|
7
|
-
using PrefixExtensions
|
8
|
-
|
9
7
|
depends :oauth_base
|
10
8
|
|
11
9
|
auth_value_methods(
|
@@ -17,7 +15,7 @@ module Rodauth
|
|
17
15
|
|
18
16
|
private
|
19
17
|
|
20
|
-
def
|
18
|
+
def validate_token_params
|
21
19
|
return super unless assertion_grant_type?
|
22
20
|
|
23
21
|
redirect_response_error("invalid_grant") unless param_or_nil("assertion")
|
@@ -29,19 +27,16 @@ module Rodauth
|
|
29
27
|
elsif client_assertion_type?
|
30
28
|
@oauth_application = __send__(:"require_oauth_application_from_#{client_assertion_type}_assertion_subject",
|
31
29
|
param("client_assertion"))
|
32
|
-
else
|
33
|
-
return super
|
34
|
-
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
if (client_id = param_or_nil("client_id")) &&
|
32
|
+
client_id != @oauth_application[oauth_applications_client_id_column]
|
33
|
+
# If present, the value of the
|
34
|
+
# "client_id" parameter MUST identify the same client as is
|
35
|
+
# identified by the client assertion.
|
36
|
+
redirect_response_error("invalid_grant")
|
37
|
+
end
|
38
|
+
else
|
39
|
+
super
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
@@ -54,7 +49,7 @@ module Rodauth
|
|
54
49
|
)
|
55
50
|
end
|
56
51
|
|
57
|
-
def
|
52
|
+
def create_token(grant_type)
|
58
53
|
return super unless assertion_grant_type?(grant_type) && supported_grant_type?(grant_type)
|
59
54
|
|
60
55
|
account = __send__(:"account_from_#{assertion_grant_type}_assertion", param("assertion"))
|
@@ -62,19 +57,20 @@ module Rodauth
|
|
62
57
|
redirect_response_error("invalid_grant") unless account
|
63
58
|
|
64
59
|
grant_scopes = if param_or_nil("scope")
|
65
|
-
redirect_response_error("
|
60
|
+
redirect_response_error("invalid_scope") unless check_valid_scopes?
|
66
61
|
scopes
|
67
62
|
else
|
68
63
|
@oauth_application[oauth_applications_scopes_column]
|
69
64
|
end
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
grant_params = {
|
67
|
+
oauth_grants_type_column => grant_type,
|
68
|
+
oauth_grants_account_id_column => account[account_id_column],
|
69
|
+
oauth_grants_oauth_application_id_column => @oauth_application[oauth_applications_id_column],
|
70
|
+
oauth_grants_scopes_column => grant_scopes
|
75
71
|
}
|
76
72
|
|
77
|
-
|
73
|
+
generate_token(grant_params, false)
|
78
74
|
end
|
79
75
|
|
80
76
|
def assertion_grant_type?(grant_type = param("grant_type"))
|
@@ -1,67 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rodauth/oauth"
|
4
|
+
|
3
5
|
module Rodauth
|
4
6
|
Feature.define(:oauth_authorization_code_grant, :OauthAuthorizationCodeGrant) do
|
5
7
|
depends :oauth_authorize_base
|
6
8
|
|
7
|
-
auth_value_method :
|
9
|
+
auth_value_method :oauth_response_mode, "form_post"
|
10
|
+
|
11
|
+
def oauth_grant_types_supported
|
12
|
+
super | %w[authorization_code]
|
13
|
+
end
|
14
|
+
|
15
|
+
def oauth_response_types_supported
|
16
|
+
super | %w[code]
|
17
|
+
end
|
18
|
+
|
19
|
+
def oauth_response_modes_supported
|
20
|
+
super | %w[query form_post]
|
21
|
+
end
|
8
22
|
|
9
23
|
private
|
10
24
|
|
11
25
|
def validate_authorize_params
|
12
26
|
super
|
13
27
|
|
14
|
-
|
28
|
+
return unless (response_mode = param_or_nil("response_mode")) && !oauth_response_modes_supported.include?(response_mode)
|
15
29
|
|
16
|
-
redirect_response_error("invalid_request")
|
17
|
-
|
18
|
-
try_approval_prompt if use_oauth_access_type? && request.get?
|
30
|
+
redirect_response_error("invalid_request")
|
19
31
|
end
|
20
32
|
|
21
|
-
def
|
33
|
+
def validate_token_params
|
22
34
|
redirect_response_error("invalid_request") if param_or_nil("grant_type") == "authorization_code" && !param_or_nil("code")
|
23
35
|
super
|
24
36
|
end
|
25
37
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
return unless approval_prompt && approval_prompt == "auto"
|
30
|
-
|
31
|
-
return if db[oauth_grants_table].where(
|
32
|
-
oauth_grants_account_id_column => account_id,
|
33
|
-
oauth_grants_oauth_application_id_column => oauth_application[oauth_applications_id_column],
|
34
|
-
oauth_grants_redirect_uri_column => redirect_uri,
|
35
|
-
oauth_grants_scopes_column => scopes.join(oauth_scope_separator),
|
36
|
-
oauth_grants_access_type_column => "online"
|
37
|
-
).count.zero?
|
38
|
-
|
39
|
-
# if there's a previous oauth grant for the params combo, it means that this user has approved before.
|
40
|
-
request.env["REQUEST_METHOD"] = "POST"
|
41
|
-
end
|
38
|
+
def do_authorize(response_params = {}, response_mode = param_or_nil("response_mode"))
|
39
|
+
response_mode ||= oauth_response_mode
|
42
40
|
|
43
|
-
|
44
|
-
# Access Type flow
|
45
|
-
if use_oauth_access_type? && (access_type = param_or_nil("access_type"))
|
46
|
-
create_params[oauth_grants_access_type_column] = access_type
|
47
|
-
end
|
41
|
+
redirect_response_error("invalid_request") unless response_mode.nil? || supported_response_mode?(response_mode)
|
48
42
|
|
49
|
-
|
50
|
-
end
|
43
|
+
response_type = param_or_nil("response_type")
|
51
44
|
|
52
|
-
|
53
|
-
case param("response_type")
|
45
|
+
redirect_response_error("invalid_request") unless response_type.nil? || supported_response_type?(response_type)
|
54
46
|
|
55
|
-
|
56
|
-
|
57
|
-
response_params.replace(_do_authorize_code)
|
58
|
-
when "none"
|
59
|
-
response_mode ||= "none"
|
60
|
-
when "", nil
|
47
|
+
case response_type
|
48
|
+
when "code", nil
|
61
49
|
response_mode ||= oauth_response_mode
|
62
50
|
response_params.replace(_do_authorize_code)
|
63
|
-
else
|
64
|
-
return super if response_params.empty?
|
65
51
|
end
|
66
52
|
|
67
53
|
response_params["state"] = param("state") if param_or_nil("state")
|
@@ -70,11 +56,11 @@ module Rodauth
|
|
70
56
|
end
|
71
57
|
|
72
58
|
def _do_authorize_code
|
73
|
-
create_params = {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
59
|
+
create_params = {
|
60
|
+
oauth_grants_type_column => "authorization_code",
|
61
|
+
oauth_grants_account_id_column => account_id
|
62
|
+
}
|
63
|
+
|
78
64
|
{ "code" => create_oauth_grant(create_params) }
|
79
65
|
end
|
80
66
|
|
@@ -102,53 +88,20 @@ module Rodauth
|
|
102
88
|
</body>
|
103
89
|
</html>
|
104
90
|
FORM
|
105
|
-
when "none"
|
106
|
-
redirect(redirect_url.to_s)
|
107
|
-
else
|
108
|
-
super
|
109
91
|
end
|
110
92
|
end
|
111
93
|
|
112
|
-
def
|
94
|
+
def create_token(grant_type)
|
113
95
|
return super unless supported_grant_type?(grant_type, "authorization_code")
|
114
96
|
|
115
|
-
|
116
|
-
|
97
|
+
grant_params = {
|
98
|
+
oauth_grants_type_column => grant_type,
|
117
99
|
oauth_grants_code_column => param("code"),
|
118
100
|
oauth_grants_redirect_uri_column => param("redirect_uri"),
|
119
|
-
oauth_grants_oauth_application_id_column => oauth_application[oauth_applications_id_column]
|
120
|
-
oauth_grants_revoked_at_column => nil
|
121
|
-
).where(Sequel[oauth_grants_expires_in_column] >= Sequel::CURRENT_TIMESTAMP)
|
122
|
-
.for_update
|
123
|
-
.first
|
124
|
-
|
125
|
-
redirect_response_error("invalid_grant") unless oauth_grant
|
126
|
-
|
127
|
-
create_params = {
|
128
|
-
oauth_tokens_account_id_column => oauth_grant[oauth_grants_account_id_column],
|
129
|
-
oauth_tokens_oauth_application_id_column => oauth_grant[oauth_grants_oauth_application_id_column],
|
130
|
-
oauth_tokens_oauth_grant_id_column => oauth_grant[oauth_grants_id_column],
|
131
|
-
oauth_tokens_scopes_column => oauth_grant[oauth_grants_scopes_column]
|
101
|
+
oauth_grants_oauth_application_id_column => oauth_application[oauth_applications_id_column]
|
132
102
|
}
|
133
|
-
create_oauth_token_from_authorization_code(oauth_grant, create_params, !use_oauth_access_type?)
|
134
|
-
end
|
135
|
-
|
136
|
-
ACCESS_TYPES = %w[offline online].freeze
|
137
|
-
|
138
|
-
def check_valid_access_type?
|
139
|
-
return true unless use_oauth_access_type?
|
140
103
|
|
141
|
-
|
142
|
-
!access_type || ACCESS_TYPES.include?(access_type)
|
143
|
-
end
|
144
|
-
|
145
|
-
APPROVAL_PROMPTS = %w[force auto].freeze
|
146
|
-
|
147
|
-
def check_valid_approval_prompt?
|
148
|
-
return true unless use_oauth_access_type?
|
149
|
-
|
150
|
-
approval_prompt = param_or_nil("approval_prompt")
|
151
|
-
!approval_prompt || APPROVAL_PROMPTS.include?(approval_prompt)
|
104
|
+
create_token_from_authorization_code(grant_params)
|
152
105
|
end
|
153
106
|
|
154
107
|
def check_valid_response_type?
|
@@ -160,12 +113,6 @@ module Rodauth
|
|
160
113
|
def oauth_server_metadata_body(*)
|
161
114
|
super.tap do |data|
|
162
115
|
data[:authorization_endpoint] = authorize_url
|
163
|
-
data[:response_types_supported] << "code"
|
164
|
-
|
165
|
-
data[:response_modes_supported] << "query"
|
166
|
-
data[:response_modes_supported] << "form_post"
|
167
|
-
|
168
|
-
data[:grant_types_supported] << "authorization_code"
|
169
116
|
end
|
170
117
|
end
|
171
118
|
end
|