rodauth-oauth 0.10.4 → 1.0.0.pre.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/MIGRATION-GUIDE-v1.md +286 -0
  3. data/README.md +28 -35
  4. data/doc/release_notes/1_0_0_beta1.md +38 -0
  5. data/doc/release_notes/1_0_0_beta2.md +34 -0
  6. data/lib/generators/rodauth/oauth/install_generator.rb +0 -1
  7. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +21 -11
  8. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +1 -1
  9. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +2 -2
  10. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +1 -6
  11. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +0 -2
  12. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb +41 -0
  13. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +2 -2
  14. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_grants.html.erb +37 -0
  15. data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +57 -57
  16. data/lib/rodauth/features/oauth_application_management.rb +61 -74
  17. data/lib/rodauth/features/oauth_assertion_base.rb +19 -23
  18. data/lib/rodauth/features/oauth_authorization_code_grant.rb +62 -90
  19. data/lib/rodauth/features/oauth_authorize_base.rb +115 -22
  20. data/lib/rodauth/features/oauth_base.rb +397 -315
  21. data/lib/rodauth/features/oauth_client_credentials_grant.rb +20 -18
  22. data/lib/rodauth/features/{oauth_device_grant.rb → oauth_device_code_grant.rb} +62 -73
  23. data/lib/rodauth/features/oauth_dynamic_client_registration.rb +52 -31
  24. data/lib/rodauth/features/oauth_grant_management.rb +70 -0
  25. data/lib/rodauth/features/oauth_implicit_grant.rb +29 -27
  26. data/lib/rodauth/features/oauth_jwt.rb +53 -689
  27. data/lib/rodauth/features/oauth_jwt_base.rb +458 -0
  28. data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +48 -17
  29. data/lib/rodauth/features/oauth_jwt_jwks.rb +47 -0
  30. data/lib/rodauth/features/oauth_jwt_secured_authorization_request.rb +116 -0
  31. data/lib/rodauth/features/oauth_management_base.rb +2 -0
  32. data/lib/rodauth/features/oauth_pkce.rb +22 -26
  33. data/lib/rodauth/features/oauth_resource_indicators.rb +33 -25
  34. data/lib/rodauth/features/oauth_resource_server.rb +59 -0
  35. data/lib/rodauth/features/oauth_saml_bearer_grant.rb +7 -1
  36. data/lib/rodauth/features/oauth_token_introspection.rb +76 -46
  37. data/lib/rodauth/features/oauth_token_revocation.rb +46 -33
  38. data/lib/rodauth/features/oidc.rb +382 -241
  39. data/lib/rodauth/features/oidc_dynamic_client_registration.rb +127 -51
  40. data/lib/rodauth/features/oidc_rp_initiated_logout.rb +115 -0
  41. data/lib/rodauth/oauth/database_extensions.rb +8 -6
  42. data/lib/rodauth/oauth/http_extensions.rb +74 -0
  43. data/lib/rodauth/oauth/railtie.rb +20 -0
  44. data/lib/rodauth/oauth/ttl_store.rb +2 -0
  45. data/lib/rodauth/oauth/version.rb +1 -1
  46. data/lib/rodauth/oauth.rb +29 -1
  47. data/locales/en.yml +34 -22
  48. data/locales/pt.yml +34 -22
  49. data/templates/authorize.str +19 -17
  50. data/templates/device_search.str +1 -1
  51. data/templates/device_verification.str +2 -2
  52. data/templates/jwks_field.str +1 -0
  53. data/templates/new_oauth_application.str +1 -2
  54. data/templates/oauth_application.str +2 -2
  55. data/templates/oauth_application_oauth_grants.str +54 -0
  56. data/templates/oauth_applications.str +2 -2
  57. data/templates/oauth_grants.str +52 -0
  58. metadata +23 -16
  59. data/lib/generators/rodauth/oauth/templates/app/models/oauth_token.rb +0 -4
  60. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +0 -39
  61. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +0 -35
  62. data/lib/rodauth/features/oauth.rb +0 -9
  63. data/lib/rodauth/features/oauth_http_mac.rb +0 -86
  64. data/lib/rodauth/features/oauth_token_management.rb +0 -81
  65. data/lib/rodauth/oauth/refinements.rb +0 -48
  66. data/templates/jwt_public_key_field.str +0 -4
  67. data/templates/oauth_application_oauth_tokens.str +0 -52
  68. data/templates/oauth_tokens.str +0 -50
@@ -0,0 +1,41 @@
1
+ <% oauth_grants = rodauth.scope.instance_variable_get(:@oauth_grants) %>
2
+ <% grants_count = oauth_grants.count %>
3
+ <% if grants_count.zero? %>
4
+ <p><%= rodauth.oauth_no_grants_text %></p>
5
+ <% else %>
6
+ <table class="table">
7
+ <thead>
8
+ <tr>
9
+ <th scope="col"><=% rodauth.oauth_grants_type_label %></th>
10
+ <th scope="col"><=% rodauth.oauth_grants_token_label %></th>
11
+ <th scope="col"><=% rodauth.oauth_grants_refresh_token_label %></th>
12
+ <th scope="col"><=% rodauth.oauth_grants_expires_in_label %></th>
13
+ <th scope="col"><=% rodauth.oauth_grants_revoked_at_label %></th>
14
+ <th scope="col"><=% rodauth.oauth_grants_scopes_label %></th>
15
+ <th scope="col"><span class="badge badge-pill badge-dark"><%= grants_count %></span>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% oauth_grants.each do |oauth_grant| %>
20
+ <tr>
21
+ <td><%= oauth_grant[rodauth.oauth_grants_type_column] %></td>
22
+ <td><code class="token"><%= oauth_grant[rodauth.oauth_grants_token_column] %></code></td>
23
+ <td><code class="token"><%= oauth_grant[rodauth.oauth_grants_refresh_token_column] %></code></td>
24
+ <td><%= oauth_grant[rodauth.oauth_grants_expires_in_column] %></td>
25
+ <td><%= oauth_grant[rodauth.oauth_grants_revoked_at_column] %></td>
26
+ <td><%= oauth_grant[rodauth.oauth_grants_scopes_column] %></td>
27
+ <td>
28
+ <% if !oauth_grant[rodauth.oauth_grants_revoked_at_column] %>
29
+ <%= form_tag rodauth.revoke_path, method: :post do %>
30
+ <%= hidden_field_tag :token_type_hint, "access_token" %>
31
+ <%= hidden_field_tag :token, oauth_grant[rodauth.oauth_grants_token_column] %>
32
+ <%= submit_tag rodauth.oauth_grant_revoke_button, class: "btn btn-danger" %>
33
+ <% end %>
34
+ <% end %>
35
+ </td>
36
+ </tr>
37
+ <% end %>
38
+ </tbody>
39
+ </table>
40
+ <%= rodauth.oauth_management_pagination_links(@oauth_grants) %>
41
+ <% end %>
@@ -4,7 +4,7 @@
4
4
  <%= link_to rodauth.new_oauth_application_page_title, "#{rodauth.oauth_applications_path}/new", class: "btn btn-secondary" %>
5
5
  </div>
6
6
  <% if apps_count.zero? %>
7
- <p>No oauth applications yet!</p>
7
+ <p><%= rodauth.oauth_no_applications_text %></p>
8
8
  <% else %>
9
9
  <table class="table">
10
10
  <thead>
@@ -26,5 +26,5 @@
26
26
  <% end %>
27
27
  </tbody>
28
28
  </table>
29
- <%= rodauth.oauth_management_pagination_links(oauth_applications_ds) %>
29
+ <%= rodauth.oauth_management_pagination_links(oauth_applications_ds).html_safe %>
30
30
  <% end %>
@@ -0,0 +1,37 @@
1
+ <% oauth_grants = rodauth.scope.instance_variable_get(:@oauth_grants) %>
2
+ <% grants_count = oauth_grants.count %>
3
+ <% if grants_count.zero? %>
4
+ <p><%= rodauth.oauth_no_grants_text %></p>
5
+ <% else %>
6
+ <table class="table">
7
+ <thead>
8
+ <tr>
9
+ <th scope="col"><=% rodauth.oauth_applications_name_label %></th>
10
+ <th scope="col"><=% rodauth.oauth_grants_type_label %></th>
11
+ <th scope="col"><=% rodauth.oauth_grants_token_label %></th>
12
+ <th scope="col"><=% rodauth.oauth_grants_refresh_token_label %></th>
13
+ <th scope="col"><=% rodauth.oauth_grants_expires_in_label %></th>
14
+ <th scope="col"><=% rodauth.oauth_grants_scopes_label %></th>
15
+ <th scope="col"><span class="badge badge-pill badge-dark"><%= grants_count %></span>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% oauth_grants.each do |oauth_grant| %>
20
+ <tr>
21
+ <td><%= oauth_grant[rodauth.oauth_applications_name_column] %></td>
22
+ <td><%= oauth_grant[rodauth.oauth_grants_type_column] %></td>
23
+ <td><code class="token"><%= oauth_grant[rodauth.oauth_grants_token_column] %></code></td>
24
+ <td><code class="token"><%= oauth_grant[rodauth.oauth_grants_refresh_token_column] %></code></td>
25
+ <td><%= oauth_grant[rodauth.oauth_grants_expires_in_column] %></td>
26
+ <td><%= oauth_grant[rodauth.oauth_grants_scopes_column] %></td>
27
+ <td>
28
+ <%= form_tag rodauth.oauth_grant_path(oauth_grant[rodauth.oauth_grants_id_column]), method: :post do %>
29
+ <%= submit_tag rodauth.oauth_grant_revoke_button, class: "btn btn-danger" %>
30
+ <% end %>
31
+ </td>
32
+ </tr>
33
+ <% end %>
34
+ </tbody>
35
+ </table>
36
+ <%= rodauth.oauth_management_pagination_links(oauth_grants) %>
37
+ <% end %>
@@ -5,29 +5,48 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
5
5
  t.foreign_key :accounts, column: :account_id
6
6
  t.string :name, null: false
7
7
  t.string :description, null: true
8
- t.string :homepage_url, null: false
8
+ t.string :homepage_url, null: true
9
9
  t.string :redirect_uri, null: false
10
10
  t.string :client_id, null: false, index: { unique: true }
11
11
  t.string :client_secret, null: false, index: { unique: true }
12
12
  t.string :scopes, null: false
13
13
  t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
14
- # extra params
15
- # t.string :token_endpoint_auth_method, null: true
16
- # t.string :grant_types, null: true
17
- # t.string :response_types, null: true
18
- # t.string :client_uri, null: true
19
- # t.string :logo_uri, null: true
20
- # t.string :tos_uri, null: true
21
- # t.string :policy_uri, null: true
22
- # t.string :jwks_uri, null: true
23
- # t.string :jwks, null: true
24
- # t.string :contacts, null: true
25
- # t.string :software_id, null: true
26
- # t.string :software_version, null: true
27
- # JWT/OIDC per application signing verification
28
- # t.text :jwt_public_key, null: true
29
- # RP-initiated logout
30
- # t.string :post_logout_redirect_uri, null: false
14
+
15
+ # :oauth_dynamic_client_configuration enabled, extra optional params
16
+ t.string :token_endpoint_auth_method, null: true
17
+ t.string :grant_types, null: true
18
+ t.string :response_types, null: true
19
+ t.string :client_uri, null: true
20
+ t.string :logo_uri, null: true
21
+ t.string :tos_uri, null: true
22
+ t.string :policy_uri, null: true
23
+ t.string :jwks_uri, null: true
24
+ t.string :jwks, null: true
25
+ t.string :contacts, null: true
26
+ t.string :software_id, null: true
27
+ t.string :software_version, null: true
28
+
29
+ # :oidc_dynamic_client_configuration enabled, extra optional params
30
+ t.string :sector_identifier_uri, null: true
31
+ t.string :application_type, null: true
32
+
33
+ # :oidc enabled
34
+ t.string :subject_type, null: true
35
+ t.string :id_token_signed_response_alg, null: true
36
+ t.string :id_token_encrypted_response_alg, null: true
37
+ t.string :id_token_encrypted_response_enc, null: true
38
+ t.string :userinfo_signed_response_alg, null: true
39
+ t.string :userinfo_encrypted_response_alg, null: true
40
+ t.string :userinfo_encrypted_response_enc, null: true
41
+
42
+ # :oauth_jwt_secured_authorization_request
43
+ t.string :request_object_signing_alg, null: true
44
+ t.string :request_object_encryption_alg, null: true
45
+ t.string :request_object_encryption_enc, null: true
46
+ t.string :request_uris, null: true
47
+
48
+ # :oidc_rp_initiated_logout enabled
49
+ t.string :post_logout_redirect_uris, null: false
31
50
  end
32
51
 
33
52
  create_table :oauth_grants do |t|
@@ -35,53 +54,34 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
35
54
  t.foreign_key :accounts, column: :account_id
36
55
  t.integer :oauth_application_id
37
56
  t.foreign_key :oauth_applications, column: :oauth_application_id
38
- t.string :code, null: false
57
+ t.string :type, null: true
58
+ t.string :code, null: true
39
59
  t.index(%i[oauth_application_id code], unique: true)
60
+ t.string :token, unique: true
61
+ t.string :refresh_token, unique: true
40
62
  t.datetime :expires_in, null: false
41
63
  t.string :redirect_uri
42
64
  t.datetime :revoked_at
43
65
  t.string :scopes, null: false
44
66
  t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
45
- # for using access_types
46
67
  t.string :access_type, null: false, default: "offline"
47
- # uncomment to enable PKCE
48
- # t.string :code_challenge
49
- # t.string :code_challenge_method
50
- # uncomment to use OIDC nonce
51
- # t.string :nonce
52
- # device code grant
53
- # t.string :user_code, null: true, unique: true
54
- # t.datetime :last_polled_at, null: true
55
- # when using :oauth_resource_indicators feature
56
- # t.string :resource
57
- end
58
68
 
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
- # uncomment to use OIDC nonce
81
- # t.string :nonce
82
- # t.datetime :auth_time
83
- # when using :oauth_resource_indicators feature
84
- # t.string :resource
69
+ # :oauth_pkce enabled
70
+ t.string :code_challenge
71
+ t.string :code_challenge_method
72
+
73
+ # :oauth_device_code_grant enabled
74
+ t.string :user_code, null: true, unique: true
75
+ t.datetime :last_polled_at, null: true
76
+
77
+ # :resource_indicators enabled
78
+ t.string :resource
79
+
80
+ # :oidc enabled
81
+ t.string :nonce
82
+ t.string :acr
83
+ t.string :claims_locales
84
+ t.string :claims
85
85
  end
86
86
  end
87
87
  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
@@ -168,15 +165,15 @@ module Rodauth
168
165
  value.each do |uri|
169
166
  next if uri.empty?
170
167
 
171
- set_field_error(key, invalid_url_message) unless check_valid_uri?(uri)
168
+ set_field_error(key, invalid_url_message) unless check_valid_no_fragment_uri?(uri)
172
169
  end
173
170
  else
174
- set_field_error(key, invalid_url_message) unless check_valid_uri?(value)
171
+ set_field_error(key, invalid_url_message) unless check_valid_no_fragment_uri?(value)
175
172
  end
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"))