rodauth-oauth 0.10.4 → 1.0.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/MIGRATION-GUIDE-v1.md +286 -0
  3. data/README.md +22 -30
  4. data/doc/release_notes/1_0_0_beta1.md +38 -0
  5. data/lib/generators/rodauth/oauth/install_generator.rb +0 -1
  6. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +4 -6
  7. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +1 -1
  8. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +2 -2
  9. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +1 -6
  10. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +0 -2
  11. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb +41 -0
  12. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +2 -2
  13. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_grants.html.erb +37 -0
  14. data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +18 -29
  15. data/lib/rodauth/features/oauth_application_management.rb +59 -72
  16. data/lib/rodauth/features/oauth_assertion_base.rb +19 -23
  17. data/lib/rodauth/features/oauth_authorization_code_grant.rb +35 -88
  18. data/lib/rodauth/features/oauth_authorize_base.rb +103 -20
  19. data/lib/rodauth/features/oauth_base.rb +365 -302
  20. data/lib/rodauth/features/oauth_client_credentials_grant.rb +20 -18
  21. data/lib/rodauth/features/{oauth_device_grant.rb → oauth_device_code_grant.rb} +62 -73
  22. data/lib/rodauth/features/oauth_dynamic_client_registration.rb +46 -28
  23. data/lib/rodauth/features/oauth_grant_management.rb +70 -0
  24. data/lib/rodauth/features/oauth_implicit_grant.rb +25 -24
  25. data/lib/rodauth/features/oauth_jwt.rb +52 -688
  26. data/lib/rodauth/features/oauth_jwt_base.rb +435 -0
  27. data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +45 -17
  28. data/lib/rodauth/features/oauth_jwt_jwks.rb +47 -0
  29. data/lib/rodauth/features/oauth_jwt_secured_authorization_request.rb +62 -0
  30. data/lib/rodauth/features/oauth_management_base.rb +2 -0
  31. data/lib/rodauth/features/oauth_pkce.rb +22 -26
  32. data/lib/rodauth/features/oauth_resource_indicators.rb +33 -21
  33. data/lib/rodauth/features/oauth_resource_server.rb +59 -0
  34. data/lib/rodauth/features/oauth_saml_bearer_grant.rb +5 -1
  35. data/lib/rodauth/features/oauth_token_introspection.rb +76 -46
  36. data/lib/rodauth/features/oauth_token_revocation.rb +46 -33
  37. data/lib/rodauth/features/oidc.rb +188 -95
  38. data/lib/rodauth/features/oidc_dynamic_client_registration.rb +89 -53
  39. data/lib/rodauth/oauth/database_extensions.rb +8 -6
  40. data/lib/rodauth/oauth/http_extensions.rb +61 -0
  41. data/lib/rodauth/oauth/railtie.rb +20 -0
  42. data/lib/rodauth/oauth/version.rb +1 -1
  43. data/lib/rodauth/oauth.rb +29 -1
  44. data/locales/en.yml +32 -22
  45. data/locales/pt.yml +32 -22
  46. data/templates/authorize.str +19 -24
  47. data/templates/device_search.str +1 -1
  48. data/templates/device_verification.str +2 -2
  49. data/templates/jwks_field.str +1 -0
  50. data/templates/new_oauth_application.str +1 -2
  51. data/templates/oauth_application.str +2 -2
  52. data/templates/oauth_application_oauth_grants.str +54 -0
  53. data/templates/oauth_applications.str +2 -2
  54. data/templates/oauth_grants.str +52 -0
  55. metadata +20 -16
  56. data/lib/generators/rodauth/oauth/templates/app/models/oauth_token.rb +0 -4
  57. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +0 -39
  58. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +0 -35
  59. data/lib/rodauth/features/oauth.rb +0 -9
  60. data/lib/rodauth/features/oauth_http_mac.rb +0 -86
  61. data/lib/rodauth/features/oauth_token_management.rb +0 -81
  62. data/lib/rodauth/oauth/refinements.rb +0 -48
  63. data/templates/jwt_public_key_field.str +0 -4
  64. data/templates/oauth_application_oauth_tokens.str +0 -52
  65. 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 :code, null: false
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.datetime :auth_time
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 "oauth_application_oauth_tokens", "Oauth Application Tokens", "oauth_application_oauth_tokens"
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", "oauth_token_revoke"
46
+ button "Revoke", "oauth_grant_revoke"
46
47
 
47
- auth_value_method :oauth_applications_oauth_tokens_path, "oauth-tokens"
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 :oauth_tokens_per_page, 20
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
- def oauth_applications_path(opts = {})
57
- route_path(oauth_applications_route, opts)
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 oauth_applications
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(oauth_applications_oauth_tokens_path) do
97
+ request.on(oauth_applications_oauth_grants_path) do
96
98
  page = Integer(param_or_nil("page") || 1)
97
- per_page = per_page_param(oauth_tokens_per_page)
98
- oauth_tokens = db[oauth_tokens_table]
99
- .where(oauth_tokens_oauth_application_id_column => id)
100
- .order(Sequel.desc(oauth_tokens_id_column))
101
- scope.instance_variable_set(:@oauth_tokens, oauth_tokens.paginate(page, per_page))
102
- request.get do
103
- oauth_application_oauth_tokens_view
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.get do
109
- page = Integer(param_or_nil("page") || 1)
110
- per_page = per_page_param(oauth_applications_per_page)
111
- scope.instance_variable_set(:@oauth_applications, db[oauth_applications_table]
112
- .where(oauth_applications_account_id_column => account_id)
113
- .order(Sequel.desc(oauth_applications_id_column))
114
- .paginate(page, per_page))
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
- request.post do
120
- catch_error do
121
- validate_oauth_application_params
121
+ oauth_applications_view
122
+ end
122
123
 
123
- transaction do
124
- before_create_oauth_application
125
- id = create_oauth_application
126
- after_create_oauth_application
127
- set_notice_flash create_oauth_application_notice_flash
128
- redirect "#{request.path}/#{id}"
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, invalid_scope_message) unless oauth_application_scopes.include?(scope)
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
- create_params.merge! \
202
- oauth_applications_client_secret_column => \
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
- create_params[oauth_applications_scopes_column] = if create_params[oauth_applications_scopes_column]
206
- create_params[oauth_applications_scopes_column].join(oauth_scope_separator)
207
- else
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/refinements"
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 validate_oauth_token_params
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
- redirect_response_error("invalid_grant") unless @oauth_application
37
-
38
- if client_assertion_type? &&
39
- (client_id = param_or_nil("client_id")) &&
40
- client_id != @oauth_application[oauth_applications_client_id_column]
41
- # If present, the value of the
42
- # "client_id" parameter MUST identify the same client as is
43
- # identified by the client assertion.
44
- redirect_response_error("invalid_grant")
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 create_oauth_token(grant_type)
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("invalid_grant") unless check_valid_scopes?
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
- create_params = {
72
- oauth_tokens_account_id_column => account[account_id_column],
73
- oauth_tokens_oauth_application_id_column => @oauth_application[oauth_applications_id_column],
74
- oauth_tokens_scopes_column => grant_scopes
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
- generate_oauth_token(create_params, false)
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 :use_oauth_access_type?, true
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
- redirect_response_error("invalid_request") unless check_valid_access_type? && check_valid_approval_prompt?
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") if (response_mode = param_or_nil("response_mode")) && response_mode != "form_post"
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 validate_oauth_token_params
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 try_approval_prompt
27
- approval_prompt = param_or_nil("approval_prompt")
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
- def create_oauth_grant(create_params = {})
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
- super
50
- end
43
+ response_type = param_or_nil("response_type")
51
44
 
52
- def do_authorize(response_params = {}, response_mode = param_or_nil("response_mode"))
53
- case param("response_type")
45
+ redirect_response_error("invalid_request") unless response_type.nil? || supported_response_type?(response_type)
54
46
 
55
- when "code"
56
- response_mode ||= "query"
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 = { oauth_grants_account_id_column => account_id }
74
- # Access Type flow
75
- if use_oauth_access_type? && (access_type = param_or_nil("access_type"))
76
- create_params[oauth_grants_access_type_column] = access_type
77
- end
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 create_oauth_token(grant_type)
94
+ def create_token(grant_type)
113
95
  return super unless supported_grant_type?(grant_type, "authorization_code")
114
96
 
115
- # fetch oauth grant
116
- oauth_grant = db[oauth_grants_table].where(
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
- access_type = param_or_nil("access_type")
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