rodauth-oauth 0.7.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -418
  3. data/README.md +30 -390
  4. data/doc/release_notes/0_0_1.md +3 -0
  5. data/doc/release_notes/0_0_2.md +15 -0
  6. data/doc/release_notes/0_0_3.md +31 -0
  7. data/doc/release_notes/0_0_4.md +36 -0
  8. data/doc/release_notes/0_0_5.md +36 -0
  9. data/doc/release_notes/0_0_6.md +21 -0
  10. data/doc/release_notes/0_1_0.md +44 -0
  11. data/doc/release_notes/0_2_0.md +43 -0
  12. data/doc/release_notes/0_3_0.md +28 -0
  13. data/doc/release_notes/0_4_0.md +18 -0
  14. data/doc/release_notes/0_4_1.md +9 -0
  15. data/doc/release_notes/0_4_2.md +5 -0
  16. data/doc/release_notes/0_4_3.md +3 -0
  17. data/doc/release_notes/0_5_0.md +11 -0
  18. data/doc/release_notes/0_5_1.md +13 -0
  19. data/doc/release_notes/0_6_0.md +9 -0
  20. data/doc/release_notes/0_6_1.md +6 -0
  21. data/doc/release_notes/0_7_0.md +20 -0
  22. data/doc/release_notes/0_7_1.md +10 -0
  23. data/doc/release_notes/0_7_2.md +21 -0
  24. data/doc/release_notes/0_7_3.md +10 -0
  25. data/doc/release_notes/0_7_4.md +5 -0
  26. data/doc/release_notes/0_8_0.md +37 -0
  27. data/doc/release_notes/0_9_0.md +56 -0
  28. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +50 -0
  29. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb +11 -0
  30. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb +20 -0
  31. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +55 -0
  32. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +29 -0
  33. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +39 -0
  34. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +30 -0
  35. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +35 -0
  36. data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +21 -1
  37. data/lib/rodauth/features/oauth.rb +3 -1418
  38. data/lib/rodauth/features/oauth_application_management.rb +225 -0
  39. data/lib/rodauth/features/oauth_assertion_base.rb +96 -0
  40. data/lib/rodauth/features/oauth_authorization_code_grant.rb +252 -0
  41. data/lib/rodauth/features/oauth_authorization_server.rb +0 -0
  42. data/lib/rodauth/features/oauth_base.rb +771 -0
  43. data/lib/rodauth/features/oauth_client_credentials_grant.rb +33 -0
  44. data/lib/rodauth/features/oauth_device_grant.rb +220 -0
  45. data/lib/rodauth/features/oauth_dynamic_client_registration.rb +252 -0
  46. data/lib/rodauth/features/oauth_http_mac.rb +3 -21
  47. data/lib/rodauth/features/oauth_implicit_grant.rb +59 -0
  48. data/lib/rodauth/features/oauth_jwt.rb +276 -100
  49. data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +59 -0
  50. data/lib/rodauth/features/oauth_management_base.rb +68 -0
  51. data/lib/rodauth/features/oauth_pkce.rb +98 -0
  52. data/lib/rodauth/features/oauth_resource_server.rb +21 -0
  53. data/lib/rodauth/features/oauth_saml_bearer_grant.rb +102 -0
  54. data/lib/rodauth/features/oauth_token_introspection.rb +108 -0
  55. data/lib/rodauth/features/oauth_token_management.rb +79 -0
  56. data/lib/rodauth/features/oauth_token_revocation.rb +109 -0
  57. data/lib/rodauth/features/oidc.rb +36 -6
  58. data/lib/rodauth/features/oidc_dynamic_client_registration.rb +147 -0
  59. data/lib/rodauth/oauth/database_extensions.rb +15 -2
  60. data/lib/rodauth/oauth/jwe_extensions.rb +64 -0
  61. data/lib/rodauth/oauth/refinements.rb +48 -0
  62. data/lib/rodauth/oauth/ttl_store.rb +9 -3
  63. data/lib/rodauth/oauth/version.rb +1 -1
  64. data/locales/en.yml +33 -12
  65. data/templates/authorize.str +57 -8
  66. data/templates/client_secret_field.str +2 -2
  67. data/templates/description_field.str +1 -1
  68. data/templates/device_search.str +11 -0
  69. data/templates/device_verification.str +24 -0
  70. data/templates/homepage_url_field.str +2 -2
  71. data/templates/jwks_field.str +4 -0
  72. data/templates/jwt_public_key_field.str +4 -0
  73. data/templates/name_field.str +1 -1
  74. data/templates/new_oauth_application.str +9 -0
  75. data/templates/oauth_application.str +7 -3
  76. data/templates/oauth_application_oauth_tokens.str +52 -0
  77. data/templates/oauth_applications.str +3 -2
  78. data/templates/oauth_tokens.str +10 -11
  79. data/templates/redirect_uri_field.str +2 -2
  80. metadata +84 -4
  81. data/lib/rodauth/features/oauth_saml.rb +0 -104
@@ -0,0 +1,44 @@
1
+ ### 0.1.0 (31/7/2020)
2
+
3
+ #### Features
4
+
5
+ ##### OpenID
6
+
7
+ `rodauth-oauth` now ships with support for [OpenID Connect](https://openid.net/connect/). In order to enable, you have to:
8
+
9
+ ```ruby
10
+ plugin :rodauth do
11
+ enable :oidc
12
+ end
13
+ ```
14
+
15
+ For more info about integrating it, [check the wiki](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/wikis/home#openid-connect-since-v01).
16
+
17
+ It supports omniauth openID integrations out-of-the-box, [check the OpenID example, which integrates with omniauth_openid_connect](https://gitlab.com/honeyryderchuck/rodauth-oauth/-/tree/master/examples).
18
+
19
+ #### Improvements
20
+
21
+ * JWT: `sub` claim now also handles "pairwise" subjects. For that, you have to set the `oauth_jwt_subject_type` option (`"public"` or `"pairwise"`) and `oauth_jwt_subject_secret` (will be used for salting the `sub` when the type is `"pairwise"`).
22
+ * JWT: `auth_time` claim is now supported; if your application uses the `rodauth` feature `:account_expiration`, it'll use the `last_account_login_at` method, otherwise you can set the `last_account_login_at` option:
23
+
24
+ ```ruby
25
+ last_account_login_at do
26
+ convert_timestamp(db[accounts_table].where(account_id_column => account_id).get(:that_column_where_you_keep_the_data))
27
+ end
28
+ ```
29
+ * JWT: `iss` claim now defaults to `authorization_server_url` when not defined;
30
+ * JWT: `aud` claim now defaults to the token application's client ID (`client_id` claim was removed as a result);
31
+
32
+
33
+
34
+ #### Breaking Changes
35
+
36
+ `rodauth-oauth` URLs no longer have the `oauth-` prefix, so make sure you update your integrations accordingly, i.e. where you used to rely on `/oauth-authorize`, you'll have to use `/authorize`.
37
+
38
+ URI schemes for client applications redirect URIs have to be `https`. In order to override this, set the `oauth_valid_uri_schemes` to an array of your expected URI schemes.
39
+
40
+
41
+ #### Bugfixes
42
+
43
+ * Authorization request submission can receive the `scope` as an array of values now, instead of only dealing with receiving a white-space separated list.
44
+ * fixed trailing "/" in the "issuer" value in server metadata (`https://server.com/` -> `https://server.com`).
@@ -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,5 @@
1
+ ### 0.4.2 (24/11/2020)
2
+
3
+ #### Bugfixes
4
+
5
+ * database extensions were being run in resource server mode, when it's not expected that the oauth db tables are around.
@@ -0,0 +1,3 @@
1
+ ### 0.4.3 (09/12/2020)
2
+
3
+ * Introspection requests made to an Authorization Server in "resource server" mode are not correctly encoding the body using the "application/x-www-form-urlencoded" format.
@@ -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,9 @@
1
+ ### 0.6.0 (21/05/2021)
2
+
3
+ ### Improvements
4
+
5
+ * RBS signatures
6
+
7
+ ### Chore
8
+
9
+ * Ruby 3 and Truffleruby are now officially supported and tested in CI.
@@ -0,0 +1,6 @@
1
+ ### 0.6.1 (08/09/2021)
2
+
3
+ #### Bugfixes
4
+
5
+ * Fixed rails view templates escaping.
6
+ * Fixed declaration of authorize template in the generator.
@@ -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,5 @@
1
+ ### 0.7.4 (15/01/2022)
2
+
3
+ #### Bugfixes
4
+
5
+ * including missing erb templates in the package.
@@ -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;
@@ -0,0 +1,56 @@
1
+ ### 0.9.0 (18/04/2022)
2
+
3
+ #### Features
4
+
5
+ ##### Dynamic client registration
6
+
7
+ `rodauth-oauth` now supports the [Oauth Dynamic client registration RFC](https://datatracker.ietf.org/doc/html/rfc7591), via the `oauth_dynamic_client_registration` feature; it also supports [the OpenID variant](https://openid.net/specs/openid-connect-registration-1_0.html), via the `oidc_dynamic_client_registration` feature.
8
+
9
+ With it, you now have the option to enable API-driven client application registration.
10
+
11
+ ##### Client Credentials grant
12
+
13
+ `rodauth-oauth` now supports the [Client Credentials grant](https://tools.ietf.org/html/rfc6749#section-4.4), via the `oauth_client_credentials_grant` feature.
14
+
15
+
16
+ #### Improvements
17
+
18
+ ##### OAuth Applications & Tokens paginated list pages
19
+
20
+ The management dashboards for OAuth Applications & Tokens were loading the full dataset into the HTML view. They'll now only show 20 records by default, and present pagination links to navigate across pages (for the default templates).
21
+
22
+ ##### More Oauth Application properties
23
+
24
+ As a result of implementing "OAuth Dynamic client registration", new functionality is unlocked when the following database columns are set on the oauth applications table:
25
+
26
+ * `token_endpoint_auth_method` - enables oauth application-scoped verification of used client authentication method.
27
+ * `grant_types` - scopes the supported grant types for the given application.
28
+ * `response_type` - scopes the supported response types for the given application.
29
+ * `logo_uri` - stores an image link which can be used to load and display a logo in the authorization form.
30
+ * `tos_uri` - stores a link to the oauth application "Terms of Service" page.
31
+ * `policy_uri` - stores a link to the oauth application "Policy" page.
32
+ * `jwks_uri` - stores a link where to load the oauth application JWKs from.
33
+ * `jwks` - stores the JWKS from the oauth application.
34
+ * `contacts` stores the contacts.
35
+ * `software_id` - stores the software unique identifier.
36
+ * `software_version` - stores the software version for the unique identifier.
37
+ * `subject_type` - stores the subject type used for calculating the JWT `sub` claim for the applicatiion.
38
+ * `request_object_signing_alg` - stores the signing algorithm which request objects coming from the application will be signed with.
39
+ * `request_object_encryption_alg` - stores the encryption algorithm which request objects coming from the application will be encrypted with.
40
+ * `request_object_encryption_enc` - stores the encryption method which request objects coming from the application will be encrypted with.
41
+ * `id_token_signed_response_alg` - stores the signing algorithm which id tokens from the application will be signed with.
42
+ * `id_token_encrypted_response_alg` - stores the encryption algorithm which id tokens from the application will be encrypted with.
43
+ * `id_token_encrypted_response_enc` - stores the encryption method which id tokens from the application will be encrypted with.
44
+ * `userinfo_signed_response_alg` - stores the signing algorithm which JWT-encoded userinfo payloads from the application will be signed with.
45
+ * `userinfo_encrypted_response_alg` - stores the encryption algorithm which JWT-encoded userinfo payloads from the application will be encrypted with.
46
+ * `userinfo_encrypted_response_enc` - stores the encryption method which JWT-encoded userinfo payloads from the application will be encrypted with.
47
+
48
+
49
+ ##### TTL Store has finer grained lock
50
+
51
+ The TTL Store, used for the JWKs cache rotation p.ex., had a lock around the section which would involve the HTTP request for the JWKs, which would block the process for the duration of it. The lock has been removed around that area, and if two requests happen for the same URL, first one wins.
52
+
53
+ #### Deprecations and breaking changes
54
+
55
+ * (`oauth_jwt` plugin) `:oauth_jwt_algorithm` option default is now `"RS256"` (previous one was `"HS256"`, and yes, this an assymetric cryptography move).
56
+ * (`oauth_jwt` plugin) `jws_jwk` option (and all the labels and params) is deprecated.
@@ -0,0 +1,50 @@
1
+ <%= form_tag rodauth.authorize_path, method: :post do %>
2
+ <% if rodauth.oauth_application[rodauth.oauth_applications_logo_uri_column] %>
3
+ <%= image_tag rodauth.oauth_application[rodauth.oauth_applications_logo_uri_column] %>
4
+ <% end %>
5
+ <p class="lead">The application <%= link_to rodauth.oauth_application[rodauth.oauth_applications_name_column], rodauth.oauth_application[rodauth.oauth_applications_homepage_url_column] %> would like to access your data.</p>
6
+
7
+ <div class="list-group">
8
+ <% if rodauth.oauth_application[rodauth.oauth_applications_tos_uri_column] %>
9
+ <%= link_to rodauth.oauth_applications_tos_uri_label, rodauth.oauth_application[rodauth.oauth_applications_tos_uri_column], class: "list-group-item" %>
10
+ <% end %>
11
+ <% if rodauth.oauth_application[rodauth.oauth_applications_policy_uri_column] %>
12
+ <%= link_to rodauth.oauth_applications_policy_uri_label, rodauth.oauth_application[rodauth.oauth_applications_policy_uri_column], class: "list-group-item" %>
13
+ <% end %>
14
+ </div>
15
+
16
+ <% if rodauth.oauth_application[rodauth.oauth_applications_contacts_column] %>
17
+ <div class="list-group">
18
+ <h3 class="display-6"><%= rodauth.oauth_applications_contacts_label %></h3>
19
+ <% rodauth.oauth_application[rodauth.oauth_applications_contacts_column].split(/ +/).each do |contact| %>
20
+ <div class="list-group-item"><%= contact %></div>
21
+ <% end %>
22
+ </div>
23
+ <% end %>
24
+
25
+ <div class="form-group">
26
+ <h1 class="display-6"><%= rodauth.oauth_tokens_scopes_label %></h1>
27
+
28
+ <% rodauth.scopes.each do |scope| %>
29
+ <% is_default = scope == rodauth.oauth_application_default_scope %>
30
+ <div class="form-check">
31
+ <%= check_box_tag "scope[]", scope, is_default, disabled: is_default, id: scope, class: "form-check-input" %>
32
+ <%= label_tag scope, scope, class: "form-check-label" %>
33
+ <%= hidden_field_tag "scope[]", scope if is_default %>
34
+ </div>
35
+ <% end %>
36
+ <%= hidden_field_tag :client_id, params[:client_id] %>
37
+ <% %i[access_type response_type state nonce redirect_uri code_challenge code_challenge_method].each do |oauth_param| %>
38
+ <% if params[oauth_param] %>
39
+ <%= hidden_field_tag oauth_param, params[oauth_param] %>
40
+ <% end %>
41
+ <% end %>
42
+ <% if params[:response_mode] %>
43
+ <%= hidden_field_tag :response_mode, params[:response_mode] %>
44
+ <% end %>
45
+ </div>
46
+ <p class="text-center">
47
+ <%= submit_tag rodauth.oauth_authorize_button, class: "btn btn-outline-primary" %>
48
+ <%= 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" %>
49
+ </p>
50
+ <% 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 %>
@@ -0,0 +1,55 @@
1
+ <h2><%= rodauth.new_oauth_application_page_title %></h2>
2
+ <%= form_tag rodauth.oauth_applications_path, method: :post, class: "form-horizontal" do %>
3
+ <%= rodauth.field_error('scope') %>
4
+ <div class="form-group">
5
+ <%= label_tag "name", rodauth.oauth_applications_name_label %>
6
+ <%= text_field_tag "name", rodauth.param('name'), class: "form-control#{' is-invalid' if rodauth.field_error('name')}" %>
7
+ <%= rodauth.field_error('name') %>
8
+ </div>
9
+ <div class="form-group">
10
+ <%= label_tag "description", rodauth.oauth_applications_description_label %>
11
+ <%= text_field_tag "description", rodauth.param('description'), class: "form-control#{' is-invalid' if rodauth.field_error('description')}" %>
12
+ <%= rodauth.field_error('description') %>
13
+ </div>
14
+ <div class="form-group">
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
+ <%= rodauth.field_error('homepage_url') %>
18
+ </div>
19
+ <div class="form-group">
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
+ <%= rodauth.field_error('redirect_uri') %>
23
+ </div>
24
+ <div class="form-group">
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
+ <%= rodauth.field_error('client_secret') %>
28
+ </div>
29
+ <% if rodauth.features.include?(:oauth_jwt) %>
30
+ <div class="form-group">
31
+ <%= label_tag "jwks", rodauth.oauth_applications_jwks_label %>
32
+ <%= text_field_tag "jwks", rodauth.param('jwks'), id: "jwks", class: "form-control#{' is-invalid' if rodauth.field_error('jwks')}" %>
33
+ <%= rodauth.field_error('jwks') %>
34
+ </div>
35
+ <div class="form-group">
36
+ <%= label_tag "jwks_uri", rodauth.oauth_applications_jwks_uri_label %>
37
+ <%= text_field_tag "jwks_uri", rodauth.param('jwks_uri'), id: "jwks-uri", class: "form-control#{' is-invalid' if rodauth.field_error('jwks_uri')}" %>
38
+ <%= rodauth.field_error('jwks_uri') %>
39
+ </div>
40
+ <div class="form-group">
41
+ <%= label_tag "jwt_public_key", rodauth.oauth_applications_jwt_public_key_label %>
42
+ <%= 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')}" %>
43
+ <%= rodauth.field_error('jwt_public_key') %>
44
+ </div>
45
+ <% end %>
46
+ <% rodauth.oauth_application_scopes.each do |scope| %>
47
+ <div class="form-check">
48
+ <%= check_box_tag "scopes[]", scope, scope == rodauth.oauth_application_default_scope, id: scope, class: "form-check-input" %>
49
+ <%= scope %>
50
+ </div>
51
+ <% end %>
52
+ <div class="form-group">
53
+ <%= submit_tag rodauth.oauth_application_button, class: "btn btn-primary" %>
54
+ </div>
55
+ <% end %>
@@ -0,0 +1,29 @@
1
+ <% oauth_application = rodauth.scope.instance_variable_get(:@oauth_application) %>
2
+ <div>
3
+ <h2><%= oauth_application[rodauth.oauth_applications_name_column] %></h2>
4
+
5
+ <dl>
6
+ <dt><%= rodauth.oauth_applications_description_label %>: </dt>
7
+ <dd><%= oauth_application[rodauth.oauth_applications_description_column] %></dd>
8
+ <dt><%= rodauth.oauth_applications_homepage_url_label %>: </dt>
9
+ <dd><%= oauth_application[rodauth.oauth_applications_homepage_url_column] %></dd>
10
+ <dt><%= rodauth.oauth_applications_client_id_label %>: </dt>
11
+ <dd><%= oauth_application[rodauth.oauth_applications_client_id_column] %></dd>
12
+ <dt><%= rodauth.oauth_applications_redirect_uri_label %>: </dt>
13
+ <dd><%= oauth_application[rodauth.oauth_applications_redirect_uri_column] %></dd>
14
+ <dt><%= rodauth.oauth_applications_scopes_label %>: </dt>
15
+ <dd><%= oauth_application[rodauth.oauth_applications_scopes_column] %></dd>
16
+ <% if rodauth.features.include?(:oauth_jwt) %>
17
+ <% if oauth_application[rodauth.oauth_applications_jwks_column] %>
18
+ <dt><%= rodauth.oauth_applications_jwks_label %>: </dt>
19
+ <dd><%= oauth_application[rodauth.oauth_applications_jwks_column] %></dd>
20
+ <% end %>
21
+ <% if oauth_application[rodauth.oauth_applications_jwks_uri_column] %>
22
+ <dt><%= rodauth.oauth_applications_jwks_uri_label %>: </dt>
23
+ <dd><%= oauth_application[rodauth.oauth_applications_jwks_uri_column] %></dd>
24
+ <% end %>
25
+ <dt><%= rodauth.oauth_applications_jwt_public_key_label %>: </dt>
26
+ <dd><%= oauth_application[rodauth.oauth_applications_jwt_public_key_column] %></dd>
27
+ <% end %>
28
+ </dl>
29
+ </div>
@@ -0,0 +1,39 @@
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 %>
@@ -0,0 +1,30 @@
1
+ <% oauth_applications_ds = rodauth.scope.instance_variable_get(:@oauth_applications) %>
2
+ <% apps_count = oauth_applications_ds.count %>
3
+ <div class="btn-group" role="group" aria-label="Buttons">
4
+ <%= link_to rodauth.new_oauth_application_page_title, "#{rodauth.oauth_applications_path}/new", class: "btn btn-secondary" %>
5
+ </div>
6
+ <% if apps_count.zero? %>
7
+ <p>No oauth applications yet!</p>
8
+ <% else %>
9
+ <table class="table">
10
+ <thead>
11
+ <tr>
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
+ <th scope="col"></th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% oauth_applications_ds.each do |application| %>
20
+ <tr>
21
+ <td><%= application[rodauth.oauth_applications_client_id_column] %></td>
22
+ <td><%= application[rodauth.oauth_applications_name_column] %></td>
23
+ <td><%= application[rodauth.oauth_applications_homepage_url_column] %></td>
24
+ <td><%= link_to "Show", rodauth.oauth_application_path(application[rodauth.oauth_applications_id_column]) %></td>
25
+ </tr>
26
+ <% end %>
27
+ </tbody>
28
+ </table>
29
+ <%= rodauth.oauth_management_pagination_links(oauth_applications_ds) %>
30
+ <% end %>