rodauth-oauth 0.7.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -424
- data/README.md +26 -389
- data/doc/release_notes/0_0_1.md +3 -0
- data/doc/release_notes/0_0_2.md +15 -0
- data/doc/release_notes/0_0_3.md +31 -0
- data/doc/release_notes/0_0_4.md +36 -0
- data/doc/release_notes/0_0_5.md +36 -0
- data/doc/release_notes/0_0_6.md +21 -0
- data/doc/release_notes/0_1_0.md +44 -0
- data/doc/release_notes/0_2_0.md +43 -0
- data/doc/release_notes/0_3_0.md +28 -0
- data/doc/release_notes/0_4_0.md +18 -0
- data/doc/release_notes/0_4_1.md +9 -0
- data/doc/release_notes/0_4_2.md +5 -0
- data/doc/release_notes/0_4_3.md +3 -0
- data/doc/release_notes/0_5_0.md +11 -0
- data/doc/release_notes/0_5_1.md +13 -0
- data/doc/release_notes/0_6_0.md +9 -0
- data/doc/release_notes/0_6_1.md +6 -0
- data/doc/release_notes/0_7_0.md +20 -0
- data/doc/release_notes/0_7_1.md +10 -0
- data/doc/release_notes/0_7_2.md +21 -0
- data/doc/release_notes/0_7_3.md +10 -0
- data/doc/release_notes/0_7_4.md +5 -0
- data/doc/release_notes/0_8_0.md +37 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +3 -3
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +11 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +20 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +22 -10
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +11 -5
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +38 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +5 -5
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +11 -15
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +9 -1
- data/lib/rodauth/features/oauth.rb +3 -1418
- data/lib/rodauth/features/oauth_application_management.rb +209 -0
- data/lib/rodauth/features/oauth_assertion_base.rb +96 -0
- data/lib/rodauth/features/oauth_authorization_code_grant.rb +249 -0
- data/lib/rodauth/features/oauth_authorization_server.rb +0 -0
- data/lib/rodauth/features/oauth_base.rb +735 -0
- data/lib/rodauth/features/oauth_device_grant.rb +221 -0
- data/lib/rodauth/features/oauth_http_mac.rb +3 -21
- data/lib/rodauth/features/oauth_implicit_grant.rb +59 -0
- data/lib/rodauth/features/oauth_jwt.rb +37 -60
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +59 -0
- data/lib/rodauth/features/oauth_pkce.rb +98 -0
- data/lib/rodauth/features/oauth_resource_server.rb +21 -0
- data/lib/rodauth/features/oauth_saml_bearer_grant.rb +102 -0
- data/lib/rodauth/features/oauth_token_introspection.rb +108 -0
- data/lib/rodauth/features/oauth_token_management.rb +77 -0
- data/lib/rodauth/features/oauth_token_revocation.rb +109 -0
- data/lib/rodauth/features/oidc.rb +4 -3
- data/lib/rodauth/oauth/database_extensions.rb +15 -2
- data/lib/rodauth/oauth/refinements.rb +48 -0
- data/lib/rodauth/oauth/version.rb +1 -1
- data/locales/en.yml +28 -12
- data/templates/authorize.str +7 -7
- data/templates/client_secret_field.str +2 -2
- data/templates/description_field.str +1 -1
- data/templates/device_search.str +11 -0
- data/templates/device_verification.str +24 -0
- data/templates/homepage_url_field.str +2 -2
- data/templates/jws_jwk_field.str +4 -0
- data/templates/jwt_public_key_field.str +4 -0
- data/templates/name_field.str +1 -1
- data/templates/new_oauth_application.str +9 -0
- data/templates/oauth_application.str +7 -3
- data/templates/oauth_application_oauth_tokens.str +51 -0
- data/templates/oauth_applications.str +2 -2
- data/templates/oauth_tokens.str +9 -11
- data/templates/redirect_uri_field.str +2 -2
- metadata +71 -3
- data/lib/rodauth/features/oauth_saml.rb +0 -104
@@ -0,0 +1,43 @@
|
|
1
|
+
### 0.2.0 (9/9/2020)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
##### SAML Assertion Grant Type
|
6
|
+
|
7
|
+
`rodauth-auth` now supports using a SAML Assertion to request for an Access token.In order to enable, you have to:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
plugin :rodauth do
|
11
|
+
enable :oauth_saml
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
For more info about integrating it, [check the wiki](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/SAML-Assertion-Access-Tokens).
|
16
|
+
|
17
|
+
##### Supporting rotating keys
|
18
|
+
|
19
|
+
At some point, you'll want to replace the pkeys and algorithm used to generate and verify the JWT access tokens, but you want to keep validating previously-distributed JWT tokens, at least until they expire. Now you can, via two new options, `oauth_jwt_legacy_public_key` and `oauth_jwt_legacy_algorithm`, which will be declared in the JWKs URI and used to verify access tokens.
|
20
|
+
|
21
|
+
|
22
|
+
##### Reuse access tokens
|
23
|
+
|
24
|
+
If the `oauth_reuse_access_token` is set, if there's already an existing valid access token, any new grant for the same application / account / scope will keep the same access token. This can be helpful in scenarios where one wants the same access token distributed across devices.
|
25
|
+
|
26
|
+
##### require_authorizable_account
|
27
|
+
|
28
|
+
The method used to verify access to the authorize flow is called `require_authorizable_account`. By default, it checks if a user is logged in by using rodauth's own `require_account`. This is the method you'd want to redefine in order to augment these requirements, i.e. request 2fa authentication.
|
29
|
+
|
30
|
+
#### Improvements
|
31
|
+
|
32
|
+
Expired and revoked access tokens end up generating a lot of garbage, which will have to be periodically cleaned up. You can mitigate this now by setting a uniqueness index for a group of columns, i.e. if you set a uniqueness index for the `oauth_application_id/account_id/scopes` column, `rodauth-oauth` will transparently reuse the same db entry to store the new access token. If setting some other type of uniqueness index, make sure to update the option `oauth_tokens_unique_columns` (the array of columns from the uniqueness index).
|
33
|
+
|
34
|
+
#### Bugfixes
|
35
|
+
|
36
|
+
Calling `before_*_route` callbacks appropriately.
|
37
|
+
|
38
|
+
Fixed some mishandling of HTTP headers when in in resource-server mode.
|
39
|
+
|
40
|
+
#### Chore
|
41
|
+
|
42
|
+
* 97.7% test coverage;
|
43
|
+
* `rodauth-oauth` CI tests run against sqlite, postgresql and mysql.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
### 0.3.0 (8/10/2020)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* `oauth_refresh_token_protection_policy` is a new option, which can be used to set a protection policy around usage of refresh tokens. By default it's `none`, for backwards-compatibility. However, when set to `rotation`, refresh tokens will be "use-once", i.e. a token refresh request will generate a new refresh token. Also, refresh token requests performed with already-used refresh tokens will be interpreted as a security breach, i.e. all tokens linked to the compromised refresh token will be revoked.
|
6
|
+
|
7
|
+
#### Improvements
|
8
|
+
|
9
|
+
|
10
|
+
* Support for the OIDC authorize [`prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html) (sectionn 3.1.2.1). It supports the `none`, `login` and `consent` out-of-the-box, while providing support for `select-account` when paired with [rodauth-select-account, a rodauth feature to handle multiple accounts in the same session](https://gitlab.com/honeyryderchuck/rodauth-select-account).
|
11
|
+
|
12
|
+
* Refresh Tokens are now expirable. The refresh token expiration period is governed by the `oauth_refresh_token_expires_in` option (default: 1 year), and is the period for which a refresh token can be used after its respective access token expired.
|
13
|
+
|
14
|
+
#### Bugfixes
|
15
|
+
|
16
|
+
* Default Templates now being packaged, as a way to provide a default experience to the OAuth journeys.
|
17
|
+
|
18
|
+
* fixing metadata urls when plugin loaded with a prefix path (@ianks)
|
19
|
+
|
20
|
+
* All date/time-based calculations, such as determining an expiration date, or checking if a token has expired, are now performed using database arithmetic operations, using sequel's `date_arithmetic` plugin. This will eliminate subtle bugs, such as when the database timezone is different than the application OS timezone.
|
21
|
+
|
22
|
+
* OIDC configuration endpoint is now stricter, eliminating JSON metadata inherited from the Oauth metadata endpoint. (@ianks)
|
23
|
+
|
24
|
+
#### Chore
|
25
|
+
|
26
|
+
Use `rodauth.convert_timestamp` in the templates, whenever dates are displayed.
|
27
|
+
|
28
|
+
Set HTTP Cache headers for metadata responses, such as `/.well-known/oauth-authorization-server` and `/.well-known/openid-configuration`, so they can be stored at the edge. The cache will be valid for 1 day (this value isn't set by an option yet).
|
@@ -0,0 +1,18 @@
|
|
1
|
+
### 0.4.0 (13/11/2020)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* A new method, `get_additional_param(account, claim)`, is now exposed; this method will be called whenever non-OIDC scopes are requested in the emission of the ID token.
|
6
|
+
|
7
|
+
* The `form_post` response is now supported, either by passing the `response_mode=form_post` request param in the authorization URL, or by setting `oauth_response_mode "form_post"` option. This improves the overall security of an Authorization server even more, as authorization codes are sent to client applications via a POST request to the redirect URI.
|
8
|
+
|
9
|
+
|
10
|
+
#### Improvements
|
11
|
+
|
12
|
+
* For the OIDC `address` scope, proper claims are now emitted as per the standard, i.e. the "formatted", "street_address", "locality", "region", "postal_code", "country". These will be the ones referenced in the `get_oidc_param` method.
|
13
|
+
|
14
|
+
#### Bugfixes
|
15
|
+
|
16
|
+
* The rails templates were missing declarations from a few params, which made some of the flows (the PKCE for example) not work out-of-the box;
|
17
|
+
* rails tests were silently not running in CI;
|
18
|
+
* The CI suite was revamped, so that all Oauth tests would be run under rails as well. All versions from rails equal or above 5.0 are now targeted;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
### 0.4.1 (24/11/2020)
|
2
|
+
|
3
|
+
#### Improvements
|
4
|
+
|
5
|
+
When in "Resource Server" mode, calling `rodauth.authorization_token` will now return an hash of the JSON payload that the Authorization Server responds, and which was already previously used to authorize access to protected resources.
|
6
|
+
|
7
|
+
#### Bugfixes
|
8
|
+
|
9
|
+
* An error occurred if the client passed an empty authorization header (`Authorization: ` or `Authorization: Bearer `), causing an unexpected error; It now responds with the proper `401 Unauthorized` status code.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
### 0.5.0 (08/02/2021)
|
2
|
+
|
3
|
+
#### RP-Initiated Logout
|
4
|
+
|
5
|
+
The `:oidc` plugin can now do [RP-Initiated Logout](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/RP-Initiated-Logout). It's disabled by default, so read the docs to learn how to enable it.
|
6
|
+
|
7
|
+
#### Security
|
8
|
+
|
9
|
+
The `:oauth_jwt` (and by association, `:oidc`) plugin(s) verifies the claims of used JWT tokens. This is a **very important security fix**, as without it, there is no protection against replay attacks and other types of misuse of the JWT token.
|
10
|
+
|
11
|
+
A new auth method, `generate_jti(claims)`, was [added to the list of oauth_jwt plugin options](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/JWT-Access-Tokens#rodauth-options). By default, it'll hash the `aud` and `iat` claims together, but you can overwrite how this is done.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
### 0.5.1 (19/03/2021)
|
2
|
+
|
3
|
+
#### Improvements
|
4
|
+
|
5
|
+
* Changing "Callback URL" to "Redirect URL" in default templates;
|
6
|
+
|
7
|
+
#### Bugfixes
|
8
|
+
|
9
|
+
* (rails integration) Fixed templates location;
|
10
|
+
* (rails integration) Fixed migration name from generator;
|
11
|
+
* (rails integration) fixed links, html tags, styling and unassigned variables from a few view templates;
|
12
|
+
* `oauth_application_path` is now compliant with prefixes and other url helpers, while now having a `oauth_application_url` counterpart;
|
13
|
+
* (rails integration) skipping csrf checks for "/userinfo" request (OIDC)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
### 0.7.0 (02/12/2021)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* Internationalization (i18n) support by hooking on [rodauth-i18n](https://github.com/janko/rodauth-i18n).
|
6
|
+
* Sets all text using `translatable_method`.
|
7
|
+
* Provides english translations for all `rodauth-oauth` related user facing text.
|
8
|
+
|
9
|
+
#### Improvements
|
10
|
+
|
11
|
+
* Enable CORS requests for OpenID configuration endpoint (@ianks)
|
12
|
+
* Introspect endpoint now exposes the `exp` token property (@gmanley)
|
13
|
+
|
14
|
+
#### Bugfixes
|
15
|
+
|
16
|
+
* on rotation policy, although the first refresh token was invalidated, a new one wasn't being provided. This change allows a new refresh token to be generated and exposed in the response (@gmanley)
|
17
|
+
|
18
|
+
#### Chore
|
19
|
+
|
20
|
+
Setting `rodauth` minimal supported version to `2.0.0`.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
### 0.7.1 (05/12/2021)
|
2
|
+
|
3
|
+
#### Improvements
|
4
|
+
|
5
|
+
* Adapted the `rodauth-i18n` configuration to comply with the guidelines for `v0.2.0` (which is the defacto minimmal supported version).
|
6
|
+
|
7
|
+
#### Bugfixes
|
8
|
+
|
9
|
+
* `convert_timestamp` was removed from the templates, as it's private API.
|
10
|
+
* Several missing or wrong URLs in templates fixed (authorize form was wrongly processing scopes when none was selected).
|
@@ -0,0 +1,21 @@
|
|
1
|
+
### 0.7.2 (14/12/2021)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* Revoking tokens from the OAuth Application management interface (@muellerj)
|
6
|
+
|
7
|
+
Token revocation was only possible when using the client ID and Secret, to aid "logout" functionality from client applications. Although the admin interface (available via `r.oauth_applications`) displayed a "Revoke" button alongside tokens in the list page, this was not working. The RFC does allow for the use case of application administrators being able to manually revoke tokens (as a result of client support, for example), so this functionality was enabled (only for the oauth application owner, for now).
|
8
|
+
|
9
|
+
#### Bugfixes
|
10
|
+
|
11
|
+
Default scope usage related bugfixes:
|
12
|
+
|
13
|
+
* Improved default scope conversion to avoid nested arrays (@muellerj);
|
14
|
+
* Authorize form shows a disabled checkbox and POST's no scope when default scope is to be used (@muellerj);
|
15
|
+
* example default scope fixed for example authorization server (should be string) (@muellerj);
|
16
|
+
* several param fixes in view templates (@muellerj);
|
17
|
+
|
18
|
+
OAuth Applications Management fixes:
|
19
|
+
|
20
|
+
* Access to OAuth Application page is now restricted to app owner;
|
21
|
+
* OAuth Applications page now lists the **only** the applications owned by the logged in user;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
## 0.7.3 (14/01/2022)
|
2
|
+
|
3
|
+
#### Bugfixes
|
4
|
+
|
5
|
+
* fixed generator declarations and views generator, in orderto copy templates and rewrite paths accordingly.
|
6
|
+
* update view templates to not use "%%".
|
7
|
+
|
8
|
+
#### Chore
|
9
|
+
|
10
|
+
* `rodauth` is now declared as a dependency, with minimum version set `2.0`.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
### 0.8.0 (12/03/2022)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* Device code grant
|
6
|
+
|
7
|
+
`rodauth-oauth` now supports the [Device code grant RFC](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/Device-Grant), via the `oauth_device_grant` feature.
|
8
|
+
|
9
|
+
* OAuth Tokens Management
|
10
|
+
|
11
|
+
An OAuth Tokens Management Dashboard is now provided (via `r.oauth_tokens` call to enable the routes). It allows the logged in account to list and revoke OAuth Tokens which have been issued for its resources.
|
12
|
+
|
13
|
+
* Assertion Framework (+ SAML and JWT Bearer Grant)
|
14
|
+
|
15
|
+
A new plugin, `oauth_assertion_base`, was introduced to provide a baseline for implementing custom Bearer Assertion as per the [OAuth Client Assertion Framework RFC](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/Client-Assertion-Framework). This in turn was used to refactor and reintroduce the [oauth_saml_bearer_grant](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/SAML-Bearer-Assertions) and the [oauth_jwt_bearer_grant](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/JWT-Bearer-Assertions) features, which implement the respective and most recent version of the assertion RFCs.
|
16
|
+
|
17
|
+
(as a result, `oauth_saml` was removed, which implemented a very old draft version of the SAML Bearer spec).
|
18
|
+
|
19
|
+
#### Improvements
|
20
|
+
|
21
|
+
The OAuth functionality was refactored from 1 big feature, into several features:
|
22
|
+
|
23
|
+
* `oauth_base`
|
24
|
+
* `oauth_authorization_code_grant`
|
25
|
+
* `oauth_implicit_grant`
|
26
|
+
* `oauth_device_grant`
|
27
|
+
* `oauth_token_introspection`
|
28
|
+
* `oauth_token_revocation`
|
29
|
+
* `oauth_application_management`
|
30
|
+
* `oauth_token_management`
|
31
|
+
* `oauth_pkce`
|
32
|
+
|
33
|
+
They're still loaded together via the `oauth` feature for backwards compatibility. This will change in a major version.
|
34
|
+
|
35
|
+
#### Bugfixes
|
36
|
+
|
37
|
+
* `oauth_jwt` integration with the `json-jwt` gem does proper claims validation now;
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<p class="lead">The application <%= rodauth.oauth_application[rodauth.oauth_applications_name_column] %> would like to access your data.</p>
|
3
3
|
|
4
4
|
<div class="form-group">
|
5
|
-
<h1 class="display-6"><%= rodauth.
|
5
|
+
<h1 class="display-6"><%= rodauth.oauth_tokens_scopes_label %></h1>
|
6
6
|
|
7
7
|
<% rodauth.scopes.each do |scope| %>
|
8
8
|
<% is_default = scope == rodauth.oauth_application_default_scope %>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<% end %>
|
24
24
|
</div>
|
25
25
|
<p class="text-center">
|
26
|
-
<%= submit_tag
|
27
|
-
<%= link_to
|
26
|
+
<%= submit_tag rodauth.oauth_authorize_button, class: "btn btn-outline-primary" %>
|
27
|
+
<%= link_to rodauth.oauth_cancel_button, "#{rodauth.redirect_uri}?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request#{"&state=\#{rodauth.state}" if params[:state] }", class: "btn btn-outline-danger" %>
|
28
28
|
</p>
|
29
29
|
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= form_tag rodauth.device_path, method: :get, class: "form-horizontal", id: "device-search-form" do %>
|
2
|
+
<p class="lead">Insert the user code from the device you'd like to authorize.</p>
|
3
|
+
|
4
|
+
<div class="form-group">
|
5
|
+
<%= label_tag "user_code", rodauth.oauth_grant_user_code_label %>
|
6
|
+
<%= text_field_tag "user_code", rodauth.param_or_nil(rodauth.oauth_grant_user_code_param), class: "form-control#{' is-invalid' if rodauth.field_error('user_code')}" %>
|
7
|
+
</div>
|
8
|
+
<p class="text-center">
|
9
|
+
<%= submit_tag rodauth.oauth_device_search_button, class: "btn btn-outline-primary" %>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<% oauth_grant = rodauth.scope.instance_variable_get(:@oauth_grant) %>
|
2
|
+
<%= form_tag rodauth.device_path, method: :post, class: "form-horizontal", id: "device-verification-form" do %>
|
3
|
+
<p class="lead">The device with user code <%= oauth_grant[rodauth.oauth_grants_user_code_column] %> would like to access your data.</p>
|
4
|
+
|
5
|
+
<div class="form-group">
|
6
|
+
<h1 class="display-6"><%= rodauth.oauth_tokens_scopes_label %></h1>
|
7
|
+
|
8
|
+
<ul class="list-group">
|
9
|
+
<% oauth_grant[rodauth.oauth_grants_scopes_column].split(rodauth.oauth_scope_separator).each do |scope| %>
|
10
|
+
<li class="list-group-item"><%= scope %></li>
|
11
|
+
<% end %>
|
12
|
+
</ul>
|
13
|
+
</div>
|
14
|
+
<%= hidden_field_tag :user_code, rodauth.param("user_code") %>
|
15
|
+
|
16
|
+
<p class="text-center">
|
17
|
+
<%= submit_tag rodauth.oauth_device_verification_button, class: "btn btn-outline-primary" %>
|
18
|
+
<%= link_to rodauth.oauth_cancel_button, "#{rodauth.device_path}?error=access_denied", class: "btn btn-outline-danger" %>
|
19
|
+
</p>
|
20
|
+
<% end %>
|
data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb
CHANGED
@@ -1,31 +1,43 @@
|
|
1
|
+
<h2><%= rodauth.new_oauth_application_page_title %></h2>
|
1
2
|
<%= form_tag rodauth.oauth_applications_path, method: :post, class: "form-horizontal" do %>
|
2
|
-
<h2>Register Oauth Application</h2>
|
3
3
|
<%= rodauth.field_error('scope') %>
|
4
4
|
<div class="form-group">
|
5
|
-
<%= label_tag "name",
|
5
|
+
<%= label_tag "name", rodauth.oauth_applications_name_label %>
|
6
6
|
<%= text_field_tag "name", rodauth.param('name'), class: "form-control#{' is-invalid' if rodauth.field_error('name')}" %>
|
7
7
|
<%= rodauth.field_error('name') %>
|
8
8
|
</div>
|
9
9
|
<div class="form-group">
|
10
|
-
<%= label_tag "description",
|
10
|
+
<%= label_tag "description", rodauth.oauth_applications_description_label %>
|
11
11
|
<%= text_field_tag "description", rodauth.param('description'), class: "form-control#{' is-invalid' if rodauth.field_error('description')}" %>
|
12
12
|
<%= rodauth.field_error('description') %>
|
13
13
|
</div>
|
14
14
|
<div class="form-group">
|
15
|
-
<%= label_tag "homepage_url",
|
16
|
-
<%= text_field_tag "homepage_url", rodauth.param('homepage_url'), class: "form-control#{' is-invalid' if rodauth.field_error('homepage_url')}" %>
|
15
|
+
<%= label_tag "homepage_url", rodauth.oauth_applications_homepage_url_label %>
|
16
|
+
<%= text_field_tag "homepage_url", rodauth.param('homepage_url'), id: "homepage-url", class: "form-control#{' is-invalid' if rodauth.field_error('homepage_url')}" %>
|
17
17
|
<%= rodauth.field_error('homepage_url') %>
|
18
18
|
</div>
|
19
19
|
<div class="form-group">
|
20
|
-
<%= label_tag "redirect_uri",
|
21
|
-
<%= text_field_tag "redirect_uri", rodauth.param('redirect_uri'), class: "form-control#{' is-invalid' if rodauth.field_error('redirect_uri')}" %>
|
20
|
+
<%= label_tag "redirect_uri", rodauth.oauth_applications_redirect_uri_label %>
|
21
|
+
<%= text_field_tag "redirect_uri", rodauth.param('redirect_uri'), id: "redirect-uri", class: "form-control#{' is-invalid' if rodauth.field_error('redirect_uri')}" %>
|
22
22
|
<%= rodauth.field_error('redirect_uri') %>
|
23
23
|
</div>
|
24
24
|
<div class="form-group">
|
25
|
-
<%= label_tag "client_secret",
|
26
|
-
<%= text_field_tag "client_secret", rodauth.param('client_secret'), class: "form-control#{' is-invalid' if rodauth.field_error('client_secret')}" %>
|
25
|
+
<%= label_tag "client_secret", rodauth.oauth_applications_client_secret_label %>
|
26
|
+
<%= text_field_tag "client_secret", rodauth.param('client_secret'), id: "client-secret", class: "form-control#{' is-invalid' if rodauth.field_error('client_secret')}" %>
|
27
27
|
<%= rodauth.field_error('client_secret') %>
|
28
28
|
</div>
|
29
|
+
<% if rodauth.features.include?(:oauth_jwt) %>
|
30
|
+
<div class="form-group">
|
31
|
+
<%= label_tag "jws_jwk", rodauth.oauth_applications_jws_jwk_label %>
|
32
|
+
<%= text_field_tag "jws_jwk", rodauth.param('jws_jwk'), id: "jws-jwk", class: "form-control#{' is-invalid' if rodauth.field_error('jws_jwk')}" %>
|
33
|
+
<%= rodauth.field_error('jws_jwk') %>
|
34
|
+
</div>
|
35
|
+
<div class="form-group">
|
36
|
+
<%= label_tag "jwt_public_key", rodauth.oauth_applications_jwt_public_key_label %>
|
37
|
+
<%= text_field_tag "jwt_public_key", rodauth.param('jwt_public_key'), id: "jwt-public-key", class: "form-control#{' is-invalid' if rodauth.field_error('jwt_public_key')}" %>
|
38
|
+
<%= rodauth.field_error('jwt_public_key') %>
|
39
|
+
</div>
|
40
|
+
<% end %>
|
29
41
|
<% rodauth.oauth_application_scopes.each do |scope| %>
|
30
42
|
<div class="form-check">
|
31
43
|
<%= check_box_tag "scopes[]", scope, scope == rodauth.oauth_application_default_scope, id: scope, class: "form-check-input" %>
|
@@ -33,6 +45,6 @@
|
|
33
45
|
</div>
|
34
46
|
<% end %>
|
35
47
|
<div class="form-group">
|
36
|
-
<%= submit_tag
|
48
|
+
<%= submit_tag rodauth.oauth_application_button, class: "btn btn-primary" %>
|
37
49
|
</div>
|
38
50
|
<% end %>
|
@@ -3,15 +3,21 @@
|
|
3
3
|
<h2><%= oauth_application[rodauth.oauth_applications_name_column] %></h2>
|
4
4
|
|
5
5
|
<dl>
|
6
|
-
<dt
|
6
|
+
<dt><%= rodauth.oauth_applications_description_label %>: </dt>
|
7
7
|
<dd><%= oauth_application[rodauth.oauth_applications_description_column] %></dd>
|
8
|
-
<dt
|
8
|
+
<dt><%= rodauth.oauth_applications_homepage_url_label %>: </dt>
|
9
9
|
<dd><%= oauth_application[rodauth.oauth_applications_homepage_url_column] %></dd>
|
10
|
-
<dt
|
10
|
+
<dt><%= rodauth.oauth_applications_client_id_label %>: </dt>
|
11
11
|
<dd><%= oauth_application[rodauth.oauth_applications_client_id_column] %></dd>
|
12
|
-
<dt
|
12
|
+
<dt><%= rodauth.oauth_applications_redirect_uri_label %>: </dt>
|
13
13
|
<dd><%= oauth_application[rodauth.oauth_applications_redirect_uri_column] %></dd>
|
14
|
-
<dt
|
14
|
+
<dt><%= rodauth.oauth_applications_scopes_label %>: </dt>
|
15
15
|
<dd><%= oauth_application[rodauth.oauth_applications_scopes_column] %></dd>
|
16
|
+
<% if rodauth.features.include?(:oauth_jwt) %>
|
17
|
+
<dt><%= rodauth.oauth_applications_jws_jwk_label %>: </dt>
|
18
|
+
<dd><%= oauth_application[rodauth.oauth_applications_jws_jwk_column] %></dd>
|
19
|
+
<dt><%= rodauth.oauth_applications_jwt_public_key_label %>: </dt>
|
20
|
+
<dd><%= oauth_application[rodauth.oauth_applications_jwt_public_key_column] %></dd>
|
21
|
+
<% end %>
|
16
22
|
</dl>
|
17
23
|
</div>
|
@@ -0,0 +1,38 @@
|
|
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
|
+
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% oauth_applications_ds = rodauth.scope.instance_variable_get(:@oauth_applications) %>
|
2
2
|
<% apps_count = oauth_applications_ds.count %>
|
3
3
|
<div class="btn-group" role="group" aria-label="Buttons">
|
4
|
-
<%= link_to
|
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
7
|
<p>No oauth applications yet!</p>
|
@@ -9,9 +9,9 @@
|
|
9
9
|
<table class="table">
|
10
10
|
<thead>
|
11
11
|
<tr>
|
12
|
-
<th scope="col"
|
13
|
-
<th scope="col"
|
14
|
-
<th scope="col"
|
12
|
+
<th scope="col"><%= rodauth.oauth_application_client_id_label %> (<%= apps_count %>)</th>
|
13
|
+
<th scope="col"><%= rodauth.oauth_application_name_label %></th>
|
14
|
+
<th scope="col"><%= rodauth.oauth_application_homepage_url_label %></th>
|
15
15
|
<th scope="col"></th>
|
16
16
|
</tr>
|
17
17
|
</thead>
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<td><%= application[rodauth.oauth_applications_client_id_column] %></td>
|
22
22
|
<td><%= application[rodauth.oauth_applications_name_column] %></td>
|
23
23
|
<td><%= application[rodauth.oauth_applications_homepage_url_column] %></td>
|
24
|
-
<td><%= link_to "Show",
|
24
|
+
<td><%= link_to "Show", rodauth.oauth_application_path(application[rodauth.oauth_applications_id_column]) %></td>
|
25
25
|
</tr>
|
26
26
|
<% end %>
|
27
27
|
</tbody>
|
@@ -1,34 +1,30 @@
|
|
1
|
-
<%
|
2
|
-
<% tokens_count =
|
1
|
+
<% oauth_tokens = rodauth.scope.instance_variable_get(:@oauth_tokens) %>
|
2
|
+
<% tokens_count = oauth_tokens.count %>
|
3
3
|
<% if tokens_count.zero? %>
|
4
4
|
<p>No oauth tokens yet!</p>
|
5
5
|
<% else %>
|
6
6
|
<table class="table">
|
7
7
|
<thead>
|
8
8
|
<tr>
|
9
|
-
<th scope="col"
|
10
|
-
<th scope="col"
|
11
|
-
<th scope="col"
|
12
|
-
<th scope="col"
|
13
|
-
<th scope="col"
|
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
14
|
<th scope="col"><span class="badge badge-pill badge-dark"><%= tokens_count %></span>
|
15
15
|
</tr>
|
16
16
|
</thead>
|
17
17
|
<tbody>
|
18
|
-
<%
|
18
|
+
<% oauth_tokens.each do |oauth_token| %>
|
19
19
|
<tr>
|
20
|
+
<td><%= oauth_token[rodauth.oauth_applications_name_column] %></td>
|
20
21
|
<td><code class="token"><%= oauth_token[rodauth.oauth_tokens_token_column] %></code></td>
|
21
22
|
<td><code class="token"><%= oauth_token[rodauth.oauth_tokens_refresh_token_column] %></code></td>
|
22
23
|
<td><%= oauth_token[rodauth.oauth_tokens_expires_in_column] %></td>
|
23
|
-
<td><%= oauth_token[rodauth.oauth_tokens_revoked_at_column] %></td>
|
24
24
|
<td><%= oauth_token[rodauth.oauth_tokens_scopes_column] %></td>
|
25
25
|
<td>
|
26
|
-
|
27
|
-
<%=
|
28
|
-
<%= hidden_field_tag :token_type_hint, "access_token" %>
|
29
|
-
<%= hidden_field_tag :token, oauth_token[rodauth.oauth_tokens_token_column] %>
|
30
|
-
<%= submit_tag "Revoke", class: "btn btn-danger" %>
|
31
|
-
<% end %>
|
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" %>
|
32
28
|
<% end %>
|
33
29
|
</td>
|
34
30
|
</tr>
|
@@ -11,6 +11,11 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
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
|
+
# JWT/OIDC per application signing verification
|
15
|
+
# t.text :jwt_public_key, null: true
|
16
|
+
# t.text :jws_jwk, null: true
|
17
|
+
# RP-initiated logout
|
18
|
+
# t.string :post_logout_redirect_uri, null: false
|
14
19
|
end
|
15
20
|
|
16
21
|
create_table :oauth_grants do |t|
|
@@ -19,6 +24,7 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
19
24
|
t.integer :oauth_application_id
|
20
25
|
t.foreign_key :oauth_applications, column: :oauth_application_id
|
21
26
|
t.string :code, null: false
|
27
|
+
t.index(%i[oauth_application_id code], unique: true)
|
22
28
|
t.datetime :expires_in, null: false
|
23
29
|
t.string :redirect_uri
|
24
30
|
t.datetime :revoked_at
|
@@ -31,7 +37,9 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
31
37
|
# t.string :code_challenge_method
|
32
38
|
# uncomment to use OIDC nonce
|
33
39
|
# t.string :nonce
|
34
|
-
|
40
|
+
# device code grant
|
41
|
+
# t.string :user_code, null: true, unique: true
|
42
|
+
# t.datetime :last_polled_at, null: true
|
35
43
|
end
|
36
44
|
|
37
45
|
create_table :oauth_tokens do |t|
|