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.
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
@@ -1,6 +1,6 @@
1
1
  <h2>#{rodauth.new_oauth_application_page_title}</h2>
2
2
  <form method="post" action="#{rodauth.oauth_applications_path}" class="rodauth" role="form" id="oauth-application-form">
3
- #{rodauth.csrf_tag}
3
+ #{csrf_tag(rodauth.oauth_applications_path) if respond_to?(:csrf_tag)}
4
4
  #{rodauth.render('name_field')}
5
5
  #{rodauth.render('description_field')}
6
6
  #{rodauth.render('homepage_url_field')}
@@ -10,7 +10,6 @@
10
10
  #{
11
11
  if rodauth.features.include?(:oauth_jwt)
12
12
  <<-HTML
13
- #{rodauth.render('jwt_public_key_field')}
14
13
  #{rodauth.render('jwks_field')}
15
14
  HTML
16
15
  end
@@ -3,7 +3,7 @@
3
3
  #{
4
4
  params = [*rodauth.oauth_application_required_params, "client_id", "client_secret"]
5
5
  if rodauth.features.include?(:oauth_jwt)
6
- params += %w[jwks jwt_public_key]
6
+ params += %w[jwks]
7
7
  end
8
8
  params.map do |param|
9
9
  "<dt class=\"#{param}\">#{rodauth.send(:"oauth_applications_#{param}_label")}: </dt>" +
@@ -11,5 +11,5 @@
11
11
  end.join
12
12
  }
13
13
  </dl>
14
- <a href="#{rodauth.oauth_applications_path}/#{@oauth_application[rodauth.oauth_applications_id_column]}/#{rodauth.oauth_applications_oauth_tokens_path}" class="btn btn-outline-secondary">#{rodauth.oauth_application_oauth_tokens_page_title}</a>
14
+ <a href="#{rodauth.oauth_applications_path}/#{@oauth_application[rodauth.oauth_applications_id_column]}/#{rodauth.oauth_applications_oauth_grants_path}" class="btn btn-outline-secondary">#{rodauth.oauth_application_oauth_grants_page_title}</a>
15
15
  </div>
@@ -0,0 +1,54 @@
1
+ <div id="oauth-grants">
2
+ #{
3
+ if @oauth_grants.count.zero?
4
+ "<p>#{rodauth.oauth_no_grants_text}</p>"
5
+ else
6
+ <<-HTML
7
+ <table class="table">
8
+ <thead>
9
+ <tr>
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_revoked_at_label}</th>
15
+ <th scope="col">#{rodauth.oauth_grants_scopes_label}</th>
16
+ <th scope="col"><span class="badge badge-pill badge-dark">#{@oauth_grants.count}</span>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ #{
21
+ @oauth_grants.map do |oauth_grant|
22
+ <<-HTML
23
+ <tr>
24
+ <td><code class="token">#{oauth_grant[rodauth.oauth_grants_type_column]}</code></td>
25
+ <td><code class="token">#{oauth_grant[rodauth.oauth_grants_token_column]}</code></td>
26
+ <td><code class="token">#{oauth_grant[rodauth.oauth_grants_refresh_token_column]}</code></td>
27
+ <td>#{oauth_grant[rodauth.oauth_grants_expires_in_column]}</td>
28
+ <td>#{oauth_grant[rodauth.oauth_grants_revoked_at_column]}</td>
29
+ <td>#{oauth_grant[rodauth.oauth_grants_scopes_column]}</td>
30
+ <td>
31
+ #{
32
+ if !oauth_grant[rodauth.oauth_grants_revoked_at_column] && !oauth_grant[rodauth.oauth_grants_token_hash_column]
33
+ <<-HTML
34
+ <form method="post" action="#{rodauth.revoke_path}" class="form-horizontal" role="form" id="revoke-form">
35
+ #{csrf_tag(rodauth.revoke_path) if respond_to?(:csrf_tag)}
36
+ #{rodauth.input_field_string("token_type_hint", "revoke-token-type-hint", :value => "access_token", :type=>"hidden")}
37
+ #{rodauth.input_field_string("token", "revoke-token", :value => oauth_grant[rodauth.oauth_grants_token_column], :type=>"hidden")}
38
+ #{rodauth.button(rodauth.oauth_grant_revoke_button)}
39
+ </form>
40
+ HTML
41
+ end
42
+ }
43
+ </td>
44
+ </tr>
45
+ HTML
46
+ end.join
47
+ }
48
+ </tbody>
49
+ </table>
50
+ #{rodauth.oauth_management_pagination_links(@oauth_grants)}
51
+ HTML
52
+ end
53
+ }
54
+ </div>
@@ -2,11 +2,11 @@
2
2
  <a class="btn btn-outline-primary" href="/oauth-applications/new">#{rodauth.new_oauth_application_page_title}</a>
3
3
  #{
4
4
  if @oauth_applications.count.zero?
5
- "<p>No oauth applications yet!</p>"
5
+ "<p>#{rodauth.oauth_no_applications_text}</p>"
6
6
  else
7
7
  "<ul class=\"list-group\">" +
8
8
  @oauth_applications.map do |application|
9
- "<li class=\"list-group-item\"><a href=\"/oauth-applications/#{application[:id]}\">#{application[:name]}</a></li>"
9
+ "<li class=\"list-group-item\"><a href=\"#{rodauth.oauth_application_path(application[rodauth.oauth_applications_id_column])}\">#{application[:name]}</a></li>"
10
10
  end.join +
11
11
  "</ul>"
12
12
  end
@@ -0,0 +1,52 @@
1
+ <div id="oauth-grants">
2
+ #{
3
+ if @oauth_grants.count.zero?
4
+ "<p>#{rodauth.oauth_no_grants_text}</p>"
5
+ else
6
+ <<-HTML
7
+ <table class="table">
8
+ <thead>
9
+ <tr>
10
+ <th scope="col">#{rodauth.oauth_applications_name_label}</th>
11
+ <th scope="col">#{rodauth.oauth_grants_type_label}</th>
12
+ <th scope="col">#{rodauth.oauth_grants_token_label}</th>
13
+ <th scope="col">#{rodauth.oauth_grants_refresh_token_label}</th>
14
+ <th scope="col">#{rodauth.oauth_grants_expires_in_label}</th>
15
+ <th scope="col">#{rodauth.oauth_grants_scopes_label}</th>
16
+ <th scope="col"><span class="badge badge-pill badge-dark">#{@oauth_grants.count}</span>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ #{
21
+ @oauth_grants.map do |oauth_grant|
22
+ <<-HTML
23
+ <tr>
24
+ <td>#{oauth_grant[rodauth.oauth_applications_name_column]}</td>
25
+ <td>#{oauth_grant[rodauth.oauth_grants_type_column]}</td>
26
+ <td><code class="token">#{oauth_grant[rodauth.oauth_grants_token_column]}</code></td>
27
+ <td><code class="token">#{oauth_grant[rodauth.oauth_grants_refresh_token_column]}</code></td>
28
+ <td>#{oauth_grant[rodauth.oauth_grants_expires_in_column]}</td>
29
+ <td>#{oauth_grant[rodauth.oauth_grants_scopes_column]}</td>
30
+ <td>
31
+ #{
32
+ if !oauth_grant[rodauth.oauth_grants_token_hash_column]
33
+ <<-HTML
34
+ <form method="post" action="#{rodauth.oauth_grant_path(oauth_grant[rodauth.oauth_grants_id_column])}" class="form-horizontal" role="form" id="grant-revoke-form">
35
+ #{csrf_tag(rodauth.oauth_grant_path(oauth_grant[rodauth.oauth_grants_id_column])) if respond_to?(:csrf_tag)}
36
+ #{rodauth.button(rodauth.oauth_grant_revoke_button)}
37
+ </form>
38
+ HTML
39
+ end
40
+ }
41
+ </td>
42
+ </tr>
43
+ HTML
44
+ end.join
45
+ }
46
+ </tbody>
47
+ </table>
48
+ #{rodauth.oauth_management_pagination_links(@oauth_grants)}
49
+ HTML
50
+ end
51
+ }
52
+ </div>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth-oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.4
4
+ version: 1.0.0.pre.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-17 00:00:00.000000000 Z
11
+ date: 2022-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rodauth
@@ -32,6 +32,7 @@ extensions: []
32
32
  extra_rdoc_files:
33
33
  - LICENSE.txt
34
34
  - README.md
35
+ - MIGRATION-GUIDE-v1.md
35
36
  - CHANGELOG.md
36
37
  - doc/release_notes/0_0_1.md
37
38
  - doc/release_notes/0_0_2.md
@@ -65,9 +66,11 @@ extra_rdoc_files:
65
66
  - doc/release_notes/0_9_1.md
66
67
  - doc/release_notes/0_9_2.md
67
68
  - doc/release_notes/0_9_3.md
69
+ - doc/release_notes/1_0_0_beta1.md
68
70
  files:
69
71
  - CHANGELOG.md
70
72
  - LICENSE.txt
73
+ - MIGRATION-GUIDE-v1.md
71
74
  - README.md
72
75
  - doc/release_notes/0_0_1.md
73
76
  - doc/release_notes/0_0_2.md
@@ -101,47 +104,49 @@ files:
101
104
  - doc/release_notes/0_9_1.md
102
105
  - doc/release_notes/0_9_2.md
103
106
  - doc/release_notes/0_9_3.md
107
+ - doc/release_notes/1_0_0_beta1.md
104
108
  - lib/generators/rodauth/oauth/install_generator.rb
105
109
  - lib/generators/rodauth/oauth/templates/app/models/oauth_application.rb
106
110
  - lib/generators/rodauth/oauth/templates/app/models/oauth_grant.rb
107
- - lib/generators/rodauth/oauth/templates/app/models/oauth_token.rb
108
111
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb
109
112
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb
110
113
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb
111
114
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb
112
115
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb
113
- - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb
116
+ - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb
114
117
  - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb
115
- - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb
118
+ - lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_grants.html.erb
116
119
  - lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb
117
120
  - lib/generators/rodauth/oauth/views_generator.rb
118
- - lib/rodauth/features/oauth.rb
119
121
  - lib/rodauth/features/oauth_application_management.rb
120
122
  - lib/rodauth/features/oauth_assertion_base.rb
121
123
  - lib/rodauth/features/oauth_authorization_code_grant.rb
122
124
  - lib/rodauth/features/oauth_authorize_base.rb
123
125
  - lib/rodauth/features/oauth_base.rb
124
126
  - lib/rodauth/features/oauth_client_credentials_grant.rb
125
- - lib/rodauth/features/oauth_device_grant.rb
127
+ - lib/rodauth/features/oauth_device_code_grant.rb
126
128
  - lib/rodauth/features/oauth_dynamic_client_registration.rb
127
- - lib/rodauth/features/oauth_http_mac.rb
129
+ - lib/rodauth/features/oauth_grant_management.rb
128
130
  - lib/rodauth/features/oauth_implicit_grant.rb
129
131
  - lib/rodauth/features/oauth_jwt.rb
132
+ - lib/rodauth/features/oauth_jwt_base.rb
130
133
  - lib/rodauth/features/oauth_jwt_bearer_grant.rb
134
+ - lib/rodauth/features/oauth_jwt_jwks.rb
135
+ - lib/rodauth/features/oauth_jwt_secured_authorization_request.rb
131
136
  - lib/rodauth/features/oauth_management_base.rb
132
137
  - lib/rodauth/features/oauth_pkce.rb
133
138
  - lib/rodauth/features/oauth_resource_indicators.rb
139
+ - lib/rodauth/features/oauth_resource_server.rb
134
140
  - lib/rodauth/features/oauth_saml_bearer_grant.rb
135
141
  - lib/rodauth/features/oauth_token_introspection.rb
136
- - lib/rodauth/features/oauth_token_management.rb
137
142
  - lib/rodauth/features/oauth_token_revocation.rb
138
143
  - lib/rodauth/features/oidc.rb
139
144
  - lib/rodauth/features/oidc_dynamic_client_registration.rb
140
145
  - lib/rodauth/oauth.rb
141
146
  - lib/rodauth/oauth/database_extensions.rb
147
+ - lib/rodauth/oauth/http_extensions.rb
142
148
  - lib/rodauth/oauth/jwe_extensions.rb
143
149
  - lib/rodauth/oauth/railtie.rb
144
- - lib/rodauth/oauth/refinements.rb
145
150
  - lib/rodauth/oauth/ttl_store.rb
146
151
  - lib/rodauth/oauth/version.rb
147
152
  - locales/en.yml
@@ -153,13 +158,12 @@ files:
153
158
  - templates/device_verification.str
154
159
  - templates/homepage_url_field.str
155
160
  - templates/jwks_field.str
156
- - templates/jwt_public_key_field.str
157
161
  - templates/name_field.str
158
162
  - templates/new_oauth_application.str
159
163
  - templates/oauth_application.str
160
- - templates/oauth_application_oauth_tokens.str
164
+ - templates/oauth_application_oauth_grants.str
161
165
  - templates/oauth_applications.str
162
- - templates/oauth_tokens.str
166
+ - templates/oauth_grants.str
163
167
  - templates/redirect_uri_field.str
164
168
  - templates/scope_field.str
165
169
  homepage: https://gitlab.com/honeyryderchuck/rodauth-oauth
@@ -180,12 +184,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
184
  requirements:
181
185
  - - ">="
182
186
  - !ruby/object:Gem::Version
183
- version: '0'
187
+ version: 2.5.0
184
188
  required_rubygems_version: !ruby/object:Gem::Requirement
185
189
  requirements:
186
- - - ">="
190
+ - - ">"
187
191
  - !ruby/object:Gem::Version
188
- version: '0'
192
+ version: 1.3.1
189
193
  requirements: []
190
194
  rubygems_version: 3.2.32
191
195
  signing_key:
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class OauthToken < ApplicationRecord
4
- end
@@ -1,39 +0,0 @@
1
- <% oauth_tokens = rodauth.scope.instance_variable_get(:@oauth_tokens) %>
2
- <% tokens_count = oauth_tokens.count %>
3
- <% if tokens_count.zero? %>
4
- <p>No oauth tokens yet!</p>
5
- <% else %>
6
- <table class="table">
7
- <thead>
8
- <tr>
9
- <th scope="col"><=% rodauth.oauth_tokens_token_label %></th>
10
- <th scope="col"><=% rodauth.oauth_tokens_refresh_token_label %></th>
11
- <th scope="col"><=% rodauth.oauth_tokens_expires_in_label %></th>
12
- <th scope="col"><=% rodauth.oauth_tokens_revoked_at_label %></th>
13
- <th scope="col"><=% rodauth.oauth_tokens_scopes_label %></th>
14
- <th scope="col"><span class="badge badge-pill badge-dark"><%= tokens_count %></span>
15
- </tr>
16
- </thead>
17
- <tbody>
18
- <% oauth_tokens.each do |oauth_token| %>
19
- <tr>
20
- <td><code class="token"><%= oauth_token[rodauth.oauth_tokens_token_column] %></code></td>
21
- <td><code class="token"><%= oauth_token[rodauth.oauth_tokens_refresh_token_column] %></code></td>
22
- <td><%= oauth_token[rodauth.oauth_tokens_expires_in_column] %></td>
23
- <td><%= oauth_token[rodauth.oauth_tokens_revoked_at_column] %></td>
24
- <td><%= oauth_token[rodauth.oauth_tokens_scopes_column] %></td>
25
- <td>
26
- <% if !oauth_token[rodauth.oauth_tokens_revoked_at_column] %>
27
- <%= form_tag rodauth.revoke_path, method: :post do %>
28
- <%= hidden_field_tag :token_type_hint, "access_token" %>
29
- <%= hidden_field_tag :token, oauth_token[rodauth.oauth_tokens_token_column] %>
30
- <%= submit_tag rodauth.oauth_token_revoke_button, class: "btn btn-danger" %>
31
- <% end %>
32
- <% end %>
33
- </td>
34
- </tr>
35
- <% end %>
36
- </tbody>
37
- </table>
38
- <%= rodauth.oauth_management_pagination_links(@oauth_tokens) %>
39
- <% end %>
@@ -1,35 +0,0 @@
1
- <% oauth_tokens = rodauth.scope.instance_variable_get(:@oauth_tokens) %>
2
- <% tokens_count = oauth_tokens.count %>
3
- <% if tokens_count.zero? %>
4
- <p>No oauth tokens yet!</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_tokens_token_label %></th>
11
- <th scope="col"><=% rodauth.oauth_tokens_refresh_token_label %></th>
12
- <th scope="col"><=% rodauth.oauth_tokens_expires_in_label %></th>
13
- <th scope="col"><=% rodauth.oauth_tokens_scopes_label %></th>
14
- <th scope="col"><span class="badge badge-pill badge-dark"><%= tokens_count %></span>
15
- </tr>
16
- </thead>
17
- <tbody>
18
- <% oauth_tokens.each do |oauth_token| %>
19
- <tr>
20
- <td><%= oauth_token[rodauth.oauth_applications_name_column] %></td>
21
- <td><code class="token"><%= oauth_token[rodauth.oauth_tokens_token_column] %></code></td>
22
- <td><code class="token"><%= oauth_token[rodauth.oauth_tokens_refresh_token_column] %></code></td>
23
- <td><%= oauth_token[rodauth.oauth_tokens_expires_in_column] %></td>
24
- <td><%= oauth_token[rodauth.oauth_tokens_scopes_column] %></td>
25
- <td>
26
- <%= form_tag rodauth.oauth_token_path(oauth_token[rodauth.oauth_tokens_id_column]), method: :post do %>
27
- <%= submit_tag rodauth.oauth_token_revoke_button, class: "btn btn-danger" %>
28
- <% end %>
29
- </td>
30
- </tr>
31
- <% end %>
32
- </tbody>
33
- </table>
34
- <%= rodauth.oauth_management_pagination_links(oauth_tokens) %>
35
- <% end %>
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rodauth
4
- Feature.define(:oauth, :Oauth) do
5
- depends :oauth_base, :oauth_authorization_code_grant, :oauth_pkce, :oauth_implicit_grant,
6
- :oauth_client_credentials_grant, :oauth_device_grant, :oauth_token_introspection,
7
- :oauth_token_revocation, :oauth_application_management, :oauth_token_management
8
- end
9
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rodauth/oauth/refinements"
4
-
5
- module Rodauth
6
- Feature.define(:oauth_http_mac, :OauthHttpMac) do
7
- using PrefixExtensions
8
-
9
- depends :oauth
10
-
11
- auth_value_method :oauth_token_type, "mac"
12
- auth_value_method :oauth_mac_algorithm, "hmac-sha-256" # hmac-sha-256, hmac-sha-1
13
- auth_value_method :oauth_tokens_mac_key_column, :mac_key
14
-
15
- def authorization_token
16
- return @authorization_token if defined?(@authorization_token)
17
-
18
- @authorization_token = begin
19
- value = request.get_header("HTTP_AUTHORIZATION").to_s
20
-
21
- scheme, token = value.split(/ +/, 2)
22
-
23
- return unless scheme == "MAC"
24
-
25
- mac_attributes = parse_mac_authorization_header_props(token)
26
-
27
- oauth_token = oauth_token_by_token(mac_attributes["id"])
28
-
29
- return unless oauth_token && mac_signature_matches?(oauth_token, mac_attributes)
30
-
31
- oauth_token
32
-
33
- # TODO: set new MAC-KEY for the next request
34
- end
35
- end
36
-
37
- private
38
-
39
- def generate_oauth_token(params = {}, *args)
40
- super({ oauth_tokens_mac_key_column => oauth_unique_id_generator }.merge(params), *args)
41
- end
42
-
43
- def json_access_token_payload(oauth_token)
44
- payload = super
45
-
46
- payload["mac_key"] = oauth_token[oauth_tokens_mac_key_column]
47
- payload["mac_algorithm"] = oauth_mac_algorithm
48
-
49
- payload
50
- end
51
-
52
- def mac_signature_matches?(oauth_token, mac_attributes)
53
- nonce = mac_attributes["nonce"]
54
- uri = URI(request.url)
55
-
56
- request_signature = [
57
- nonce,
58
- request.request_method,
59
- uri.request_uri,
60
- uri.host,
61
- uri.port
62
- ].join("\n") + ("\n" * 3)
63
-
64
- mac_algorithm = case oauth_mac_algorithm
65
- when "hmac-sha-256"
66
- OpenSSL::Digest::SHA256
67
- when "hmac-sha-1"
68
- OpenSSL::Digest::SHA1
69
- else
70
- raise ArgumentError, "Unsupported algorithm"
71
- end
72
-
73
- mac_signature = Base64.strict_encode64 \
74
- OpenSSL::HMAC.digest(mac_algorithm.new, oauth_token[oauth_tokens_mac_key_column], request_signature)
75
-
76
- mac_signature == mac_attributes["mac"]
77
- end
78
-
79
- def parse_mac_authorization_header_props(token)
80
- @mac_authorization_header_props = token.split(/ *, */).each_with_object({}) do |prop, props|
81
- field, value = prop.split(/ *= */, 2)
82
- props[field] = value.delete_prefix("\"").delete_suffix("\"")
83
- end
84
- end
85
- end
86
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rodauth/oauth/refinements"
4
-
5
- module Rodauth
6
- Feature.define(:oauth_token_management, :OauthTokenManagement) do
7
- using RegexpExtensions
8
-
9
- depends :oauth_management_base, :oauth_token_revocation
10
-
11
- view "oauth_tokens", "My Oauth Tokens", "oauth_tokens"
12
-
13
- button "Revoke", "oauth_token_revoke"
14
-
15
- auth_value_method :oauth_tokens_path, "oauth-tokens"
16
-
17
- %w[token refresh_token expires_in revoked_at].each do |param|
18
- translatable_method :"oauth_tokens_#{param}_label", param.gsub("_", " ").capitalize
19
- end
20
-
21
- auth_value_method :oauth_tokens_route, "oauth-tokens"
22
- auth_value_method :oauth_tokens_id_pattern, Integer
23
- auth_value_method :oauth_tokens_per_page, 20
24
-
25
- auth_value_methods(
26
- :oauth_token_path
27
- )
28
-
29
- def oauth_tokens_path(opts = {})
30
- route_path(oauth_tokens_route, opts)
31
- end
32
-
33
- def oauth_tokens_url(opts = {})
34
- route_url(oauth_tokens_route, opts)
35
- end
36
-
37
- def oauth_token_path(id)
38
- "#{oauth_tokens_path}/#{id}"
39
- end
40
-
41
- def oauth_tokens
42
- request.on(oauth_tokens_route) do
43
- require_account
44
-
45
- request.get do
46
- page = Integer(param_or_nil("page") || 1)
47
- per_page = per_page_param(oauth_tokens_per_page)
48
-
49
- scope.instance_variable_set(:@oauth_tokens, db[oauth_tokens_table]
50
- .select(Sequel[oauth_tokens_table].*, Sequel[oauth_applications_table][oauth_applications_name_column])
51
- .join(oauth_applications_table, Sequel[oauth_tokens_table][oauth_tokens_oauth_application_id_column] =>
52
- Sequel[oauth_applications_table][oauth_applications_id_column])
53
- .where(Sequel[oauth_tokens_table][oauth_tokens_account_id_column] => account_id)
54
- .where(oauth_tokens_revoked_at_column => nil)
55
- .order(Sequel.desc(oauth_tokens_id_column))
56
- .paginate(page, per_page))
57
- oauth_tokens_view
58
- end
59
-
60
- request.post(oauth_tokens_id_pattern) do |id|
61
- db[oauth_tokens_table]
62
- .where(oauth_tokens_id_column => id)
63
- .where(oauth_tokens_account_id_column => account_id)
64
- .update(oauth_tokens_revoked_at_column => Sequel::CURRENT_TIMESTAMP)
65
-
66
- set_notice_flash revoke_oauth_token_notice_flash
67
- redirect oauth_tokens_path || "/"
68
- end
69
- end
70
- end
71
-
72
- def check_csrf?
73
- case request.path
74
- when oauth_tokens_path
75
- only_json? ? false : super
76
- else
77
- super
78
- end
79
- end
80
- end
81
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rodauth
4
- module PrefixExtensions
5
- unless String.method_defined?(:delete_prefix)
6
- refine(String) do
7
- def delete_suffix(suffix)
8
- suffix = suffix.to_s
9
- len = suffix.length
10
- return dup unless len.positive? && index(suffix, -len)
11
-
12
- self[0...-len]
13
- end
14
-
15
- def delete_prefix(prefix)
16
- prefix = prefix.to_s
17
- return dup unless rindex(prefix, 0)
18
-
19
- self[prefix.length..-1]
20
- end
21
- end
22
- end
23
-
24
- unless String.method_defined?(:delete_suffix!)
25
- refine(String) do
26
- def delete_suffix!(suffix)
27
- suffix = suffix.to_s
28
- chomp! if frozen?
29
- len = suffix.length
30
- return unless len.positive? && index(suffix, -len)
31
-
32
- self[-len..-1] = ""
33
- self
34
- end
35
- end
36
- end
37
- end
38
-
39
- module RegexpExtensions
40
- unless Regexp.method_defined?(:match?)
41
- refine(Regexp) do
42
- def match?(*args)
43
- !match(*args).nil?
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,4 +0,0 @@
1
- <div class="form-group">
2
- <label for="name">#{rodauth.oauth_applications_jwt_public_key_label}#{rodauth.input_field_label_suffix}</label>
3
- #{rodauth.input_field_string(rodauth.oauth_application_jwt_public_key_param, "jwt_public_key", :type=>"text", :required=>false)}
4
- </div>
@@ -1,52 +0,0 @@
1
- <div id="oauth-tokens">
2
- #{
3
- if @oauth_tokens.count.zero?
4
- "<p>No oauth tokens yet!</p>"
5
- else
6
- <<-HTML
7
- <table class="table">
8
- <thead>
9
- <tr>
10
- <th scope="col">#{rodauth.oauth_tokens_token_label}</th>
11
- <th scope="col">#{rodauth.oauth_tokens_refresh_token_label}</th>
12
- <th scope="col">#{rodauth.oauth_tokens_expires_in_label}</th>
13
- <th scope="col">#{rodauth.oauth_tokens_revoked_at_label}</th>
14
- <th scope="col">#{rodauth.oauth_tokens_scopes_label}</th>
15
- <th scope="col"><span class="badge badge-pill badge-dark">#{@oauth_tokens.count}</span>
16
- </tr>
17
- </thead>
18
- <tbody>
19
- #{
20
- @oauth_tokens.map do |oauth_token|
21
- <<-HTML
22
- <tr>
23
- <td><code class="token">#{oauth_token[rodauth.oauth_tokens_token_column]}</code></td>
24
- <td><code class="token">#{oauth_token[rodauth.oauth_tokens_refresh_token_column]}</code></td>
25
- <td>#{oauth_token[rodauth.oauth_tokens_expires_in_column]}</td>
26
- <td>#{oauth_token[rodauth.oauth_tokens_revoked_at_column]}</td>
27
- <td>#{oauth_token[rodauth.oauth_tokens_scopes_column]}</td>
28
- <td>
29
- #{
30
- if !oauth_token[rodauth.oauth_tokens_revoked_at_column] && !oauth_token[rodauth.oauth_tokens_token_hash_column]
31
- <<-HTML
32
- <form method="post" action="#{rodauth.revoke_path}" class="form-horizontal" role="form" id="revoke-form">
33
- #{csrf_tag(rodauth.revoke_path) if respond_to?(:csrf_tag)}
34
- #{rodauth.input_field_string("token_type_hint", "revoke-token-type-hint", :value => "access_token", :type=>"hidden")}
35
- #{rodauth.input_field_string("token", "revoke-token", :value => oauth_token[rodauth.oauth_tokens_token_column], :type=>"hidden")}
36
- #{rodauth.button(rodauth.oauth_token_revoke_button)}
37
- </form>
38
- HTML
39
- end
40
- }
41
- </td>
42
- </tr>
43
- HTML
44
- end.join
45
- }
46
- </tbody>
47
- </table>
48
- #{rodauth.oauth_management_pagination_links(@oauth_tokens)}
49
- HTML
50
- end
51
- }
52
- </div>