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
@@ -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>