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.
- checksums.yaml +4 -4
- data/MIGRATION-GUIDE-v1.md +286 -0
- data/README.md +28 -35
- data/doc/release_notes/1_0_0_beta1.md +38 -0
- data/doc/release_notes/1_0_0_beta2.md +34 -0
- data/lib/generators/rodauth/oauth/install_generator.rb +0 -1
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +21 -11
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +1 -1
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +2 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +1 -6
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +0 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb +41 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +2 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_grants.html.erb +37 -0
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +57 -57
- data/lib/rodauth/features/oauth_application_management.rb +61 -74
- data/lib/rodauth/features/oauth_assertion_base.rb +19 -23
- data/lib/rodauth/features/oauth_authorization_code_grant.rb +62 -90
- data/lib/rodauth/features/oauth_authorize_base.rb +115 -22
- data/lib/rodauth/features/oauth_base.rb +397 -315
- data/lib/rodauth/features/oauth_client_credentials_grant.rb +20 -18
- data/lib/rodauth/features/{oauth_device_grant.rb → oauth_device_code_grant.rb} +62 -73
- data/lib/rodauth/features/oauth_dynamic_client_registration.rb +52 -31
- data/lib/rodauth/features/oauth_grant_management.rb +70 -0
- data/lib/rodauth/features/oauth_implicit_grant.rb +29 -27
- data/lib/rodauth/features/oauth_jwt.rb +53 -689
- data/lib/rodauth/features/oauth_jwt_base.rb +458 -0
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +48 -17
- data/lib/rodauth/features/oauth_jwt_jwks.rb +47 -0
- data/lib/rodauth/features/oauth_jwt_secured_authorization_request.rb +116 -0
- data/lib/rodauth/features/oauth_management_base.rb +2 -0
- data/lib/rodauth/features/oauth_pkce.rb +22 -26
- data/lib/rodauth/features/oauth_resource_indicators.rb +33 -25
- data/lib/rodauth/features/oauth_resource_server.rb +59 -0
- data/lib/rodauth/features/oauth_saml_bearer_grant.rb +7 -1
- data/lib/rodauth/features/oauth_token_introspection.rb +76 -46
- data/lib/rodauth/features/oauth_token_revocation.rb +46 -33
- data/lib/rodauth/features/oidc.rb +382 -241
- data/lib/rodauth/features/oidc_dynamic_client_registration.rb +127 -51
- data/lib/rodauth/features/oidc_rp_initiated_logout.rb +115 -0
- data/lib/rodauth/oauth/database_extensions.rb +8 -6
- data/lib/rodauth/oauth/http_extensions.rb +74 -0
- data/lib/rodauth/oauth/railtie.rb +20 -0
- data/lib/rodauth/oauth/ttl_store.rb +2 -0
- data/lib/rodauth/oauth/version.rb +1 -1
- data/lib/rodauth/oauth.rb +29 -1
- data/locales/en.yml +34 -22
- data/locales/pt.yml +34 -22
- data/templates/authorize.str +19 -17
- data/templates/device_search.str +1 -1
- data/templates/device_verification.str +2 -2
- data/templates/jwks_field.str +1 -0
- data/templates/new_oauth_application.str +1 -2
- data/templates/oauth_application.str +2 -2
- data/templates/oauth_application_oauth_grants.str +54 -0
- data/templates/oauth_applications.str +2 -2
- data/templates/oauth_grants.str +52 -0
- metadata +23 -16
- data/lib/generators/rodauth/oauth/templates/app/models/oauth_token.rb +0 -4
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +0 -39
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +0 -35
- data/lib/rodauth/features/oauth.rb +0 -9
- data/lib/rodauth/features/oauth_http_mac.rb +0 -86
- data/lib/rodauth/features/oauth_token_management.rb +0 -81
- data/lib/rodauth/oauth/refinements.rb +0 -48
- data/templates/jwt_public_key_field.str +0 -4
- data/templates/oauth_application_oauth_tokens.str +0 -52
- data/templates/oauth_tokens.str +0 -50
@@ -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
|
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:
|
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
|
-
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
|
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 :
|
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
|
-
|
60
|
-
t.
|
61
|
-
t.
|
62
|
-
|
63
|
-
|
64
|
-
t.
|
65
|
-
t.
|
66
|
-
|
67
|
-
|
68
|
-
t.string :
|
69
|
-
|
70
|
-
#
|
71
|
-
|
72
|
-
t.string :
|
73
|
-
|
74
|
-
|
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 "
|
18
|
+
view "oauth_application_oauth_grants", "Oauth Application Grants", "oauth_application_oauth_grants"
|
17
19
|
|
18
20
|
# Application
|
19
21
|
APPLICATION_REQUIRED_PARAMS = %w[name scopes homepage_url redirect_uri client_secret].freeze
|
@@ -21,12 +23,6 @@ module Rodauth
|
|
21
23
|
|
22
24
|
(APPLICATION_REQUIRED_PARAMS + %w[description client_id]).each do |param|
|
23
25
|
auth_value_method :"oauth_application_#{param}_param", param
|
24
|
-
configuration_module_eval do
|
25
|
-
define_method :"#{param}_label" do
|
26
|
-
warn "#{__method__} is deprecated, switch to oauth_applications_#{__method__}_label"
|
27
|
-
__send__(:"oauth_applications_#{param}_label")
|
28
|
-
end
|
29
|
-
end
|
30
26
|
end
|
31
27
|
|
32
28
|
translatable_method :oauth_applications_name_label, "Name"
|
@@ -41,36 +37,42 @@ module Rodauth
|
|
41
37
|
translatable_method :oauth_applications_redirect_uri_label, "Redirect URI"
|
42
38
|
translatable_method :oauth_applications_client_secret_label, "Client Secret"
|
43
39
|
translatable_method :oauth_applications_client_id_label, "Client ID"
|
40
|
+
|
41
|
+
%w[type token refresh_token expires_in revoked_at].each do |param|
|
42
|
+
translatable_method :"oauth_grants_#{param}_label", param.gsub("_", " ").capitalize
|
43
|
+
end
|
44
|
+
|
44
45
|
button "Register", "oauth_application"
|
45
|
-
button "Revoke", "
|
46
|
+
button "Revoke", "oauth_grant_revoke"
|
46
47
|
|
47
|
-
auth_value_method :
|
48
|
+
auth_value_method :oauth_applications_oauth_grants_path, "oauth-grants"
|
48
49
|
auth_value_method :oauth_applications_route, "oauth-applications"
|
49
50
|
auth_value_method :oauth_applications_per_page, 20
|
50
51
|
auth_value_method :oauth_applications_id_pattern, Integer
|
51
|
-
auth_value_method :
|
52
|
+
auth_value_method :oauth_grants_per_page, 20
|
52
53
|
|
53
54
|
translatable_method :invalid_url_message, "Invalid URL"
|
54
55
|
translatable_method :null_error_message, "is not filled"
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
end
|
57
|
+
translatable_method :oauth_no_applications_text, "No oauth applications yet!"
|
58
|
+
translatable_method :oauth_no_grants_text, "No oauth grants yet!"
|
59
59
|
|
60
|
-
def oauth_applications_url(opts = {})
|
61
|
-
route_url(oauth_applications_route, opts)
|
62
|
-
end
|
63
60
|
auth_value_methods(
|
64
61
|
:oauth_application_path
|
65
62
|
)
|
66
63
|
|
64
|
+
def oauth_applications_path(opts = {})
|
65
|
+
route_path(oauth_applications_route, opts)
|
66
|
+
end
|
67
|
+
|
67
68
|
def oauth_application_path(id)
|
68
69
|
"#{oauth_applications_path}/#{id}"
|
69
70
|
end
|
70
71
|
|
71
72
|
# /oauth-applications routes
|
72
|
-
def
|
73
|
+
def load_oauth_application_management_routes
|
73
74
|
request.on(oauth_applications_route) do
|
75
|
+
check_csrf if check_csrf?
|
74
76
|
require_account
|
75
77
|
|
76
78
|
request.get "new" do
|
@@ -92,57 +94,52 @@ module Rodauth
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
request.on(
|
97
|
+
request.on(oauth_applications_oauth_grants_path) do
|
96
98
|
page = Integer(param_or_nil("page") || 1)
|
97
|
-
per_page = per_page_param(
|
98
|
-
|
99
|
-
.where(
|
100
|
-
.order(Sequel.desc(
|
101
|
-
scope.instance_variable_set(:@
|
102
|
-
request.
|
103
|
-
|
99
|
+
per_page = per_page_param(oauth_grants_per_page)
|
100
|
+
oauth_grants = db[oauth_grants_table]
|
101
|
+
.where(oauth_grants_oauth_application_id_column => id)
|
102
|
+
.order(Sequel.desc(oauth_grants_id_column))
|
103
|
+
scope.instance_variable_set(:@oauth_grants, oauth_grants.paginate(page, per_page))
|
104
|
+
request.is do
|
105
|
+
request.get do
|
106
|
+
oauth_application_oauth_grants_view
|
107
|
+
end
|
104
108
|
end
|
105
109
|
end
|
106
110
|
end
|
107
111
|
|
108
|
-
request.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
oauth_applications_view
|
117
|
-
end
|
112
|
+
request.is do
|
113
|
+
request.get do
|
114
|
+
page = Integer(param_or_nil("page") || 1)
|
115
|
+
per_page = per_page_param(oauth_applications_per_page)
|
116
|
+
scope.instance_variable_set(:@oauth_applications, db[oauth_applications_table]
|
117
|
+
.where(oauth_applications_account_id_column => account_id)
|
118
|
+
.order(Sequel.desc(oauth_applications_id_column))
|
119
|
+
.paginate(page, per_page))
|
118
120
|
|
119
|
-
|
120
|
-
|
121
|
-
validate_oauth_application_params
|
121
|
+
oauth_applications_view
|
122
|
+
end
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
request.post do
|
125
|
+
catch_error do
|
126
|
+
validate_oauth_application_params
|
127
|
+
|
128
|
+
transaction do
|
129
|
+
before_create_oauth_application
|
130
|
+
id = create_oauth_application
|
131
|
+
after_create_oauth_application
|
132
|
+
set_notice_flash create_oauth_application_notice_flash
|
133
|
+
redirect "#{request.path}/#{id}"
|
134
|
+
end
|
129
135
|
end
|
136
|
+
set_error_flash create_oauth_application_error_flash
|
137
|
+
new_oauth_application_view
|
130
138
|
end
|
131
|
-
set_error_flash create_oauth_application_error_flash
|
132
|
-
new_oauth_application_view
|
133
139
|
end
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
137
|
-
def check_csrf?
|
138
|
-
case request.path
|
139
|
-
when oauth_applications_path
|
140
|
-
only_json? ? false : super
|
141
|
-
else
|
142
|
-
super
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
143
|
private
|
147
144
|
|
148
145
|
def oauth_application_params
|
@@ -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
|
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
|
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,
|
176
|
+
set_field_error(key, oauth_invalid_scope_message) unless oauth_application_scopes.include?(scope)
|
180
177
|
end
|
181
178
|
end
|
182
179
|
end
|
@@ -196,28 +193,18 @@ module Rodauth
|
|
196
193
|
redirect_uris = oauth_application_params[oauth_application_redirect_uri_param]
|
197
194
|
redirect_uris = redirect_uris.to_a.reject(&:empty?).join(" ") if redirect_uris.respond_to?(:each)
|
198
195
|
create_params[oauth_applications_redirect_uri_column] = redirect_uris unless redirect_uris.empty?
|
199
|
-
# set client ID/secret pairs
|
200
196
|
|
201
|
-
|
202
|
-
|
203
|
-
secret_hash(oauth_application_params[oauth_application_client_secret_param])
|
197
|
+
# set client ID/secret pairs
|
198
|
+
set_client_secret(create_params, oauth_application_params[oauth_application_client_secret_param])
|
204
199
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
oauth_application_default_scope
|
209
|
-
end
|
200
|
+
if create_params[oauth_applications_scopes_column]
|
201
|
+
create_params[oauth_applications_scopes_column] = create_params[oauth_applications_scopes_column].join(oauth_scope_separator)
|
202
|
+
end
|
210
203
|
|
211
204
|
rescue_from_uniqueness_error do
|
212
205
|
create_params[oauth_applications_client_id_column] = oauth_unique_id_generator
|
213
206
|
db[oauth_applications_table].insert(create_params)
|
214
207
|
end
|
215
208
|
end
|
216
|
-
|
217
|
-
def oauth_server_metadata_body(*)
|
218
|
-
super.tap do |data|
|
219
|
-
data[:registration_endpoint] = oauth_applications_url
|
220
|
-
end
|
221
|
-
end
|
222
209
|
end
|
223
210
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rodauth/oauth
|
3
|
+
require "rodauth/oauth"
|
4
4
|
|
5
5
|
module Rodauth
|
6
6
|
Feature.define(:oauth_assertion_base, :OauthAssertionBase) do
|
7
|
-
using PrefixExtensions
|
8
|
-
|
9
7
|
depends :oauth_base
|
10
8
|
|
11
9
|
auth_value_methods(
|
@@ -17,7 +15,7 @@ module Rodauth
|
|
17
15
|
|
18
16
|
private
|
19
17
|
|
20
|
-
def
|
18
|
+
def validate_token_params
|
21
19
|
return super unless assertion_grant_type?
|
22
20
|
|
23
21
|
redirect_response_error("invalid_grant") unless param_or_nil("assertion")
|
@@ -29,19 +27,16 @@ module Rodauth
|
|
29
27
|
elsif client_assertion_type?
|
30
28
|
@oauth_application = __send__(:"require_oauth_application_from_#{client_assertion_type}_assertion_subject",
|
31
29
|
param("client_assertion"))
|
32
|
-
else
|
33
|
-
return super
|
34
|
-
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
if (client_id = param_or_nil("client_id")) &&
|
32
|
+
client_id != @oauth_application[oauth_applications_client_id_column]
|
33
|
+
# If present, the value of the
|
34
|
+
# "client_id" parameter MUST identify the same client as is
|
35
|
+
# identified by the client assertion.
|
36
|
+
redirect_response_error("invalid_grant")
|
37
|
+
end
|
38
|
+
else
|
39
|
+
super
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
@@ -54,7 +49,7 @@ module Rodauth
|
|
54
49
|
)
|
55
50
|
end
|
56
51
|
|
57
|
-
def
|
52
|
+
def create_token(grant_type)
|
58
53
|
return super unless assertion_grant_type?(grant_type) && supported_grant_type?(grant_type)
|
59
54
|
|
60
55
|
account = __send__(:"account_from_#{assertion_grant_type}_assertion", param("assertion"))
|
@@ -62,19 +57,20 @@ module Rodauth
|
|
62
57
|
redirect_response_error("invalid_grant") unless account
|
63
58
|
|
64
59
|
grant_scopes = if param_or_nil("scope")
|
65
|
-
redirect_response_error("
|
60
|
+
redirect_response_error("invalid_scope") unless check_valid_scopes?
|
66
61
|
scopes
|
67
62
|
else
|
68
63
|
@oauth_application[oauth_applications_scopes_column]
|
69
64
|
end
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
grant_params = {
|
67
|
+
oauth_grants_type_column => grant_type,
|
68
|
+
oauth_grants_account_id_column => account[account_id_column],
|
69
|
+
oauth_grants_oauth_application_id_column => @oauth_application[oauth_applications_id_column],
|
70
|
+
oauth_grants_scopes_column => grant_scopes
|
75
71
|
}
|
76
72
|
|
77
|
-
|
73
|
+
generate_token(grant_params, false)
|
78
74
|
end
|
79
75
|
|
80
76
|
def assertion_grant_type?(grant_type = param("grant_type"))
|