oauth2 2.0.18 → 2.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +32 -5
- data/CITATION.cff +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/CONTRIBUTING.md +0 -0
- data/FUNDING.md +0 -0
- data/IRP.md +0 -0
- data/LICENSE.txt +1 -1
- data/OIDC.md +0 -0
- data/README.md +119 -82
- data/REEK +2 -0
- data/RUBOCOP.md +0 -0
- data/SECURITY.md +1 -1
- data/THREAT_MODEL.md +10 -1
- data/lib/oauth2/access_token.rb +11 -14
- data/lib/oauth2/authenticator.rb +9 -7
- data/lib/oauth2/client.rb +10 -2
- data/lib/oauth2/error.rb +2 -0
- data/lib/oauth2/filtered_attributes.rb +10 -49
- data/lib/oauth2/response.rb +14 -12
- data/lib/oauth2/strategy/assertion.rb +0 -0
- data/lib/oauth2/strategy/auth_code.rb +0 -0
- data/lib/oauth2/strategy/base.rb +0 -0
- data/lib/oauth2/strategy/client_credentials.rb +0 -0
- data/lib/oauth2/strategy/implicit.rb +0 -0
- data/lib/oauth2/strategy/password.rb +0 -0
- data/lib/oauth2/version.rb +1 -1
- data/lib/oauth2.rb +39 -17
- data/sig/oauth2/access_token.rbs +0 -0
- data/sig/oauth2/authenticator.rbs +0 -0
- data/sig/oauth2/client.rbs +0 -0
- data/sig/oauth2/error.rbs +0 -0
- data/sig/oauth2/filtered_attributes.rbs +6 -1
- data/sig/oauth2/response.rbs +0 -0
- data/sig/oauth2/sanitized_logger.rbs +32 -0
- data/sig/oauth2/strategy.rbs +0 -0
- data/sig/oauth2/thing_filter.rbs +10 -0
- data/sig/oauth2/version.rbs +0 -0
- data/sig/oauth2.rbs +0 -0
- data.tar.gz.sig +0 -0
- metadata +35 -13
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97a922901552727c225711855a88d45f56ad167b063ecb87477ac62db76e95e2
|
|
4
|
+
data.tar.gz: 6c31edbef7059f4644c46c273959c4c6e08f522d99306e94207bce8e82b10dc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a7ba7628e83cfc87d88bdcd1531256f85d5c053640444e76defda2c796b4d57c8c31aeee16784fc4d5c60c78ddeae5e99c44e91091c8fbd6927d6225101e60a
|
|
7
|
+
data.tar.gz: 206901137a350739ba8957bc65a2bf5ed3be2e85c7d2e03346320386b5901ed6178a359bbfb3a610d98c54bce4eda2cb8bffd657a87c2e567e80333cefc0d896
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,35 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [2.0.19] - 2026-05-15
|
|
34
|
+
|
|
35
|
+
- TAG: [v2.0.19][2.0.19t]
|
|
36
|
+
- COVERAGE: 100.00% -- 515/515 lines in 14 files
|
|
37
|
+
- BRANCH COVERAGE: 100.00% -- 174/174 branches in 14 files
|
|
38
|
+
- 89.11% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- [gh!707][gh!707] Add `OAuth2.config[:filtered_label]` to configure the placeholder used for filtered sensitive values in inspected objects and debug logging output by @pboling
|
|
43
|
+
- [gh!707][gh!707] Add `OAuth2.config[:filtered_debug_keys]` to configure which key names have their values redacted from debug logging output by @pboling
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- [gh!707][gh!707] Make inspect-time and debug-log filters snapshot their configuration at initialization time rather than tracking later config changes by @pboling
|
|
48
|
+
- [gh!714][gh!714]Refactor sensitive-value filtering to use `auth-sanitizer` while preserving `OAuth2::FilteredAttributes` as a permanent API alias by @pboling
|
|
49
|
+
|
|
50
|
+
### Removed
|
|
51
|
+
|
|
52
|
+
- Remove the internal `OAuth2::ThingFilter` and `OAuth2::SanitizedLogger` implementations now provided by `auth-sanitizer` by @pboling
|
|
53
|
+
|
|
54
|
+
### Security
|
|
55
|
+
|
|
56
|
+
- [gh!707][gh!707] Redact sensitive values from debug logging output, including Authorization headers and common token/secret fields in headers, query strings, form bodies, and JSON payloads by @pboling
|
|
57
|
+
- NOTE: debug logging has always been, and remains, opt-in. It is turned off by default.
|
|
58
|
+
|
|
59
|
+
[gh!707]: https://github.com/ruby-oauth/oauth2/pull/707
|
|
60
|
+
[gh!714]: https://github.com/ruby-oauth/oauth2/pull/714
|
|
61
|
+
|
|
33
62
|
## [2.0.18] - 2025-11-08
|
|
34
63
|
|
|
35
64
|
- TAG: [v2.0.18][2.0.18t]
|
|
@@ -54,8 +83,6 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
54
83
|
- [gh!690][gh!690], [gh!691][gh!691], [gh!692][gh!692] - Add yard-fence
|
|
55
84
|
- handle braces within code fences in markdown properly by @pboling
|
|
56
85
|
|
|
57
|
-
### Security
|
|
58
|
-
|
|
59
86
|
[gh!683]: https://github.com/ruby-oauth/oauth2/pull/683
|
|
60
87
|
[gh!684]: https://github.com/ruby-oauth/oauth2/pull/684
|
|
61
88
|
[gh!685]: https://github.com/ruby-oauth/oauth2/pull/685
|
|
@@ -196,8 +223,6 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
196
223
|
|
|
197
224
|
- [gh!660][gh!660] - Links in README (including link to HEAD documentation) by @pboling
|
|
198
225
|
|
|
199
|
-
### Security
|
|
200
|
-
|
|
201
226
|
[gh!660]: https://github.com/ruby-oauth/oauth2/pull/660
|
|
202
227
|
[gh!657]: https://github.com/ruby-oauth/oauth2/pull/657
|
|
203
228
|
[gh!656]: https://github.com/ruby-oauth/oauth2/pull/656
|
|
@@ -738,7 +763,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
738
763
|
|
|
739
764
|
[gemfiles/readme]: gemfiles/README.md
|
|
740
765
|
|
|
741
|
-
[Unreleased]: https://github.com/ruby-oauth/oauth2/compare/v2.0.
|
|
766
|
+
[Unreleased]: https://github.com/ruby-oauth/oauth2/compare/v2.0.19...HEAD
|
|
767
|
+
[2.0.19]: https://github.com/ruby-oauth/oauth2/compare/v2.0.18...v2.0.19
|
|
768
|
+
[2.0.19t]: https://github.com/ruby-oauth/oauth2/releases/tag/v2.0.19
|
|
742
769
|
[2.0.18]: https://github.com/ruby-oauth/oauth2/compare/v2.0.17...v2.0.18
|
|
743
770
|
[2.0.18t]: https://github.com/ruby-oauth/oauth2/releases/tag/v2.0.18
|
|
744
771
|
[2.0.17]: https://github.com/ruby-oauth/oauth2/compare/v2.0.16...v2.0.17
|
data/CITATION.cff
CHANGED
|
File without changes
|
data/CODE_OF_CONDUCT.md
CHANGED
|
File without changes
|
data/CONTRIBUTING.md
CHANGED
|
File without changes
|
data/FUNDING.md
CHANGED
|
File without changes
|
data/IRP.md
CHANGED
|
File without changes
|
data/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2017-
|
|
3
|
+
Copyright (c) 2017-2026 Peter H. Boling, of Galtzo.com, and oauth2 contributors
|
|
4
4
|
Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
data/OIDC.md
CHANGED
|
File without changes
|
data/README.md
CHANGED
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
| 📍 NOTE |
|
|
2
|
-
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
3
|
-
| RubyGems (the [GitHub org][rubygems-org], not the website) [suffered][draper-security] a [hostile takeover][ellen-takeover] in September 2025. |
|
|
4
|
-
| Ultimately [4 maintainers][simi-removed] were [hard removed][martin-removed] and a reason has been given for only 1 of those, while 2 others resigned in protest. |
|
|
5
|
-
| It is a [complicated story][draper-takeover] which is difficult to [parse quickly][draper-lies]. |
|
|
6
|
-
| I'm adding notes like this to gems because I [don't condone theft][draper-theft] of repositories or gems from their rightful owners. |
|
|
7
|
-
| If a similar theft happened with my repos/gems, I'd hope some would stand up for me. |
|
|
8
|
-
| Disenfranchised former-maintainers have started [gem.coop][gem-coop]. |
|
|
9
|
-
| Once available I will publish there exclusively; unless RubyCentral makes amends with the community. |
|
|
10
|
-
| The ["Technology for Humans: Joel Draper"][reinteractive-podcast] podcast episode by [reinteractive][reinteractive] is the most cogent summary I'm aware of. |
|
|
11
|
-
| See [here][gem-naming], [here][gem-coop] and [here][martin-ann] for more info on what comes next. |
|
|
12
|
-
| What I'm doing: A (WIP) proposal for [bundler/gem scopes][gem-scopes], and a (WIP) proposal for a federated [gem server][gem-server]. |
|
|
13
|
-
|
|
14
|
-
[rubygems-org]: https://github.com/rubygems/
|
|
15
|
-
[draper-security]: https://joel.drapper.me/p/ruby-central-security-measures/
|
|
16
|
-
[draper-takeover]: https://joel.drapper.me/p/ruby-central-takeover/
|
|
17
|
-
[ellen-takeover]: https://pup-e.com/blog/goodbye-rubygems/
|
|
18
|
-
[simi-removed]: https://www.reddit.com/r/ruby/s/gOk42POCaV
|
|
19
|
-
[martin-removed]: https://bsky.app/profile/martinemde.com/post/3m3occezxxs2q
|
|
20
|
-
[draper-lies]: https://joel.drapper.me/p/ruby-central-fact-check/
|
|
21
|
-
[draper-theft]: https://joel.drapper.me/p/ruby-central/
|
|
22
|
-
[reinteractive]: https://reinteractive.com/ruby-on-rails
|
|
23
|
-
[gem-coop]: https://gem.coop
|
|
24
|
-
[gem-naming]: https://github.com/gem-coop/gem.coop/issues/12
|
|
25
|
-
[martin-ann]: https://martinemde.com/2025/10/05/announcing-gem-coop.html
|
|
26
|
-
[gem-scopes]: https://github.com/galtzo-floss/bundle-namespace
|
|
27
|
-
[gem-server]: https://github.com/galtzo-floss/gem-server
|
|
28
|
-
[reinteractive-podcast]: https://youtu.be/_H4qbtC5qzU?si=BvuBU90R2wAqD2E6
|
|
29
|
-
|
|
30
1
|
[![Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0][🖼️galtzo-i]][🖼️galtzo-discord] [![ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5][🖼️ruby-lang-i]][🖼️ruby-lang] [![oauth2 Logo by Chris Messina, CC BY-SA 3.0][🖼️oauth2-i]][🖼️oauth2]
|
|
31
2
|
|
|
32
3
|
[🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
|
|
@@ -38,9 +9,7 @@
|
|
|
38
9
|
|
|
39
10
|
# 🔐 OAuth 2.0 Authorization Framework
|
|
40
11
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
[![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
|
|
12
|
+
[![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
|
|
44
13
|
|
|
45
14
|
`if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
|
|
46
15
|
|
|
@@ -50,13 +19,20 @@
|
|
|
50
19
|
|
|
51
20
|
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
|
|
52
21
|
|
|
22
|
+
<details>
|
|
23
|
+
<summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
|
|
24
|
+
|
|
25
|
+
I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
|
|
26
|
+
|
|
27
|
+
</details>
|
|
28
|
+
|
|
53
29
|
## 🌻 Synopsis
|
|
54
30
|
|
|
55
31
|
OAuth 2.0 is the industry-standard protocol for authorization.
|
|
56
|
-
OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications,
|
|
57
|
-
desktop applications, mobile phones, and living room devices.
|
|
58
32
|
This is a RubyGem for implementing OAuth 2.0 clients (not servers) in Ruby applications.
|
|
59
33
|
|
|
34
|
+
⭐️ including OAuth 2.1 draft spec & OpenID Connect (OIDC)
|
|
35
|
+
|
|
60
36
|
### Quick Examples
|
|
61
37
|
|
|
62
38
|
<details markdown="1">
|
|
@@ -75,13 +51,14 @@ curl --request POST \
|
|
|
75
51
|
NOTE: In the ruby version below, certain params are passed to the `get_token` call, instead of the client creation.
|
|
76
52
|
|
|
77
53
|
```ruby
|
|
78
|
-
OAuth2::Client.new(
|
|
54
|
+
client = OAuth2::Client.new(
|
|
79
55
|
"REDMOND_CLIENT_ID", # client_id
|
|
80
56
|
"REDMOND_CLIENT_SECRET", # client_secret
|
|
81
57
|
auth_scheme: :request_body, # Other modes are supported: :basic_auth, :tls_client_auth, :private_key_jwt
|
|
82
58
|
token_url: "oauth2/token", # relative path, except with leading `/`, then absolute path
|
|
83
59
|
site: "https://login.microsoftonline.com/REDMOND_REDACTED",
|
|
84
|
-
)
|
|
60
|
+
)
|
|
61
|
+
client.
|
|
85
62
|
client_credentials. # There are many other types to choose from!
|
|
86
63
|
get_token(resource: "REDMOND_RESOURCE_UUID")
|
|
87
64
|
```
|
|
@@ -344,33 +321,44 @@ See [SECURITY.md][🔐security] and [IRP.md][🔐irp].
|
|
|
344
321
|
|
|
345
322
|
## ⚙️ Configuration
|
|
346
323
|
|
|
347
|
-
|
|
324
|
+
Global settings for the library:
|
|
348
325
|
|
|
349
326
|
```ruby
|
|
350
327
|
OAuth2.configure do |config|
|
|
351
|
-
# Turn on a warning like:
|
|
352
|
-
# OAuth2::AccessToken.from_hash: `hash` contained more than one 'token' key
|
|
353
328
|
config.silence_extra_tokens_warning = false # default: true
|
|
354
|
-
#
|
|
355
|
-
config.silence_no_tokens_warning = false # default: true,
|
|
329
|
+
config.silence_no_tokens_warning = false # default: true
|
|
356
330
|
end
|
|
357
331
|
```
|
|
358
332
|
|
|
359
|
-
|
|
360
|
-
Some OAuth 2.0 standards legitimately have multiple tokens.
|
|
361
|
-
You may need to subclass `OAuth2::AccessToken`, or write your own custom alternative to it, and pass it in.
|
|
362
|
-
Specify your custom class with the `access_token_class` option.
|
|
333
|
+
Filtering-related settings:
|
|
363
334
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
335
|
+
```ruby
|
|
336
|
+
OAuth2.configure do |config|
|
|
337
|
+
config.filtered_label = "[REDACTED]" # default: "[FILTERED]"
|
|
338
|
+
config.filtered_debug_keys += ["client_assertion"]
|
|
339
|
+
end
|
|
340
|
+
```
|
|
367
341
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
342
|
+
- `filtered_label` controls the placeholder used when sensitive values are filtered from inspected objects and debug logging output.
|
|
343
|
+
- `filtered_debug_keys` controls which key names have their values redacted from debug logging output when `OAUTH_DEBUG=true`.
|
|
344
|
+
- Debug logging remains opt-in and should still be used cautiously in production environments.
|
|
371
345
|
|
|
372
346
|
## 🔧 Basic Usage
|
|
373
347
|
|
|
348
|
+
### Client Initialization Options
|
|
349
|
+
|
|
350
|
+
`OAuth2::Client.new` accepts several options:
|
|
351
|
+
|
|
352
|
+
- `:site`: The base URL for the OAuth 2.0 provider.
|
|
353
|
+
- `:authorize_url`: The authorization endpoint (default: `"oauth/authorize"`).
|
|
354
|
+
- `:token_url`: The token endpoint (default: `"oauth/token"`).
|
|
355
|
+
- `:auth_scheme`: The authentication scheme (`:basic_auth`, `:request_body`, `:tls_client_auth`, `:private_key_jwt`). Default is `:basic_auth`.
|
|
356
|
+
- `:connection_opts`: Options for the underlying Faraday connection (timeouts, proxy, etc.).
|
|
357
|
+
- `:raise_errors`: Whether to raise `OAuth2::Error` on 400+ responses (default: `true`).
|
|
358
|
+
|
|
359
|
+
<details markdown="1">
|
|
360
|
+
<summary><em>authorize_url</em> and <em>token_url</em></summary>
|
|
361
|
+
|
|
374
362
|
### `authorize_url` and `token_url` are on site root (Just Works!)
|
|
375
363
|
|
|
376
364
|
```ruby
|
|
@@ -416,6 +404,25 @@ client.class.name
|
|
|
416
404
|
# => OAuth2::Client
|
|
417
405
|
```
|
|
418
406
|
|
|
407
|
+
</details>
|
|
408
|
+
|
|
409
|
+
### Advanced Initializers
|
|
410
|
+
|
|
411
|
+
```ruby
|
|
412
|
+
client = OAuth2::Client.new(id, secret, site: site) do |faraday|
|
|
413
|
+
faraday.request(:url_encoded)
|
|
414
|
+
faraday.adapter(:net_http_persistent)
|
|
415
|
+
end
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### AccessToken Features
|
|
419
|
+
|
|
420
|
+
Instances of `OAuth2::AccessToken` handle request signing and token expiration.
|
|
421
|
+
|
|
422
|
+
- **Snake Case & Indifferent Access**: `response.parsed` returns a `SnakyHash` allowing access via string/symbol and snake_case keys even if the provider returns CamelCase.
|
|
423
|
+
- **Auto-Refresh**: You can manually check `token.expired?` and call `token.refresh`.
|
|
424
|
+
- **Serialization**: Persist tokens using `token.to_hash` and restore via `OAuth2::AccessToken.from_hash(client, hash)`.
|
|
425
|
+
|
|
419
426
|
### snake_case and indifferent access in Response#parsed
|
|
420
427
|
|
|
421
428
|
```ruby
|
|
@@ -553,6 +560,13 @@ ENV["OAUTH_DEBUG"] = "true"
|
|
|
553
560
|
By default, debug output will go to `$stdout`. This can be overridden when
|
|
554
561
|
initializing your OAuth2::Client.
|
|
555
562
|
|
|
563
|
+
Sensitive values are filtered from debug logging output using:
|
|
564
|
+
|
|
565
|
+
- `OAuth2.config[:filtered_label]`
|
|
566
|
+
- `OAuth2.config[:filtered_debug_keys]`
|
|
567
|
+
|
|
568
|
+
Debug logging remains opt-in and should still be used cautiously in production environments.
|
|
569
|
+
|
|
556
570
|
```ruby
|
|
557
571
|
require "oauth2"
|
|
558
572
|
client = OAuth2::Client.new(
|
|
@@ -565,15 +579,30 @@ client = OAuth2::Client.new(
|
|
|
565
579
|
|
|
566
580
|
</details>
|
|
567
581
|
|
|
582
|
+
### Request Target Trust Boundaries
|
|
583
|
+
|
|
584
|
+
This gem supports request flows that can involve absolute URLs in addition to relative paths.
|
|
585
|
+
That flexibility can expand trust boundaries when a token-bearing client is asked to send requests
|
|
586
|
+
to caller-provided targets.
|
|
587
|
+
|
|
588
|
+
Practical guidance:
|
|
589
|
+
|
|
590
|
+
- prefer relative paths where practical
|
|
591
|
+
- do not pass untrusted absolute URLs into token-bearing clients
|
|
592
|
+
- validate or allowlist request targets at the application layer today if your deployment has strict trust-boundary requirements
|
|
593
|
+
|
|
594
|
+
This release line does not yet enforce same-host or allowlist request policy automatically.
|
|
595
|
+
If stricter outbound request controls are needed, they should currently be implemented by the calling application.
|
|
596
|
+
|
|
568
597
|
### OAuth2::Response
|
|
569
598
|
|
|
570
599
|
The `AccessToken` methods `#get`, `#post`, `#put` and `#delete` and the generic `#request`
|
|
571
|
-
will return an instance of the
|
|
600
|
+
will return an instance of the `OAuth2::Response` class.
|
|
572
601
|
|
|
573
602
|
This instance contains a `#parsed` method that will parse the response body and
|
|
574
603
|
return a Hash-like [`SnakyHash::StringKeyed`](https://gitlab.com/ruby-oauth/snaky_hash/-/blob/main/lib/snaky_hash/string_keyed.rb) if the `Content-Type` is `application/x-www-form-urlencoded` or if
|
|
575
|
-
the body is a JSON object.
|
|
576
|
-
array.
|
|
604
|
+
the body is a JSON object. It will return an Array if the body is a JSON
|
|
605
|
+
array. Otherwise, it will return the original body string.
|
|
577
606
|
|
|
578
607
|
The original response body, headers, and status can be accessed via their
|
|
579
608
|
respective methods.
|
|
@@ -615,16 +644,22 @@ Response instance will contain the `OAuth2::Error` instance.
|
|
|
615
644
|
|
|
616
645
|
### Authorization Grants
|
|
617
646
|
|
|
618
|
-
|
|
647
|
+
Currently, the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
|
|
648
|
+
authentication grant types have helper strategy classes that simplify client
|
|
649
|
+
use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
|
|
650
|
+
[`#implicit`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/implicit.rb),
|
|
651
|
+
[`#password`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/password.rb),
|
|
652
|
+
[`#client_credentials`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/client_credentials.rb), and
|
|
653
|
+
[`#assertion`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
|
|
654
|
+
|
|
655
|
+
#### OAuth 2.1 (draft) Note:
|
|
619
656
|
|
|
620
|
-
- PKCE is required for all OAuth clients using the authorization code flow (especially public clients). Implement PKCE in your app when required by your provider. See RFC 7636 and RFC 8252.
|
|
621
|
-
-
|
|
622
|
-
-
|
|
623
|
-
- Bearer tokens in the query string are omitted due to security risks; prefer Authorization header usage.
|
|
624
|
-
- Refresh tokens for public clients must either be sender-constrained (e.g., DPoP/MTLS) or one-time use.
|
|
625
|
-
- The definitions of public and confidential clients are simplified to refer only to whether the client has credentials.
|
|
657
|
+
- **PKCE** is required for all OAuth clients using the authorization code flow (especially public clients). Implement PKCE in your app when required by your provider. See RFC 7636 and RFC 8252.
|
|
658
|
+
- **Implicit grant** (response_type=token) and **Resource Owner Password Credentials grant** are omitted from OAuth 2.1; they remain here for OAuth 2.0 compatibility but should be avoided for new apps.
|
|
659
|
+
- **Redirect URIs** must be compared using exact string matching by the Authorization Server.
|
|
626
660
|
|
|
627
|
-
|
|
661
|
+
<details markdown="1">
|
|
662
|
+
<summary>OAuth 2.1 (draft) References</summary>
|
|
628
663
|
|
|
629
664
|
- OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
|
|
630
665
|
- Aaron Parecki: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
|
|
@@ -633,13 +668,7 @@ References:
|
|
|
633
668
|
- Video: https://www.youtube.com/watch?v=g_aVPdwBTfw
|
|
634
669
|
- Differences overview: https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1/
|
|
635
670
|
|
|
636
|
-
|
|
637
|
-
authentication grant types have helper strategy classes that simplify client
|
|
638
|
-
use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
|
|
639
|
-
[`#implicit`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/implicit.rb),
|
|
640
|
-
[`#password`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/password.rb),
|
|
641
|
-
[`#client_credentials`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/client_credentials.rb), and
|
|
642
|
-
[`#assertion`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
|
|
671
|
+
</details>
|
|
643
672
|
|
|
644
673
|
These aren't full examples, but demonstrative of the differences between usage for each strategy.
|
|
645
674
|
|
|
@@ -774,7 +803,7 @@ Notes:
|
|
|
774
803
|
|
|
775
804
|
</details>
|
|
776
805
|
|
|
777
|
-
###
|
|
806
|
+
### Verb‑dependent Token Mode
|
|
778
807
|
|
|
779
808
|
Providers like Instagram require the access token to be sent differently depending on the HTTP verb:
|
|
780
809
|
|
|
@@ -783,6 +812,14 @@ Providers like Instagram require the access token to be sent differently dependi
|
|
|
783
812
|
|
|
784
813
|
Since v2.0.15, you can configure an AccessToken with a verb‑dependent mode. The gem will choose how to send the token based on the request method.
|
|
785
814
|
|
|
815
|
+
Tips:
|
|
816
|
+
|
|
817
|
+
- Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for `GET` requests.
|
|
818
|
+
- If you need a custom rule, you can pass a `Proc` for `mode`, e.g. `mode: ->(verb) { verb == :get ? :query : :header }`.
|
|
819
|
+
|
|
820
|
+
<details markdown="1">
|
|
821
|
+
<summary>Instagram API Example</summary>
|
|
822
|
+
|
|
786
823
|
Example: exchanging and refreshing long‑lived Instagram tokens, and making API calls
|
|
787
824
|
|
|
788
825
|
```ruby
|
|
@@ -841,10 +878,7 @@ me = long_lived.get("/me", params: {fields: "id,username"}).parsed
|
|
|
841
878
|
# long_lived.post("/me/media", body: {image_url: "https://...", caption: "hello"})
|
|
842
879
|
```
|
|
843
880
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
- Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for `GET` requests.
|
|
847
|
-
- If you need a custom rule, you can pass a `Proc` for `mode`, e.g. `mode: ->(verb) { verb == :get ? :query : :header }`.
|
|
881
|
+
</details>
|
|
848
882
|
|
|
849
883
|
### Refresh Tokens
|
|
850
884
|
|
|
@@ -1085,11 +1119,12 @@ access = client.get_token({
|
|
|
1085
1119
|
})
|
|
1086
1120
|
```
|
|
1087
1121
|
|
|
1088
|
-
### OpenID Connect (OIDC)
|
|
1122
|
+
### OpenID Connect (OIDC)
|
|
1089
1123
|
|
|
1090
|
-
- If the token response includes an `id_token` (a JWT), this gem surfaces it
|
|
1091
|
-
-
|
|
1092
|
-
-
|
|
1124
|
+
- If the token response includes an `id_token` (a JWT), this gem surfaces it in `token.params['id_token']`.
|
|
1125
|
+
- **Note**: This gem does **not** validate the signature of the `id_token`. You must use a JWT library (like the `jwt` [gem](https://github.com/jwt/ruby-jwt)) and your provider's JWKs to verify it.
|
|
1126
|
+
- For `private_key_jwt` client authentication, provide `auth_scheme: :private_key_jwt` and ensure your key configuration matches the provider requirements.
|
|
1127
|
+
- See [OIDC.md](OIDC.md) for a more complete OIDC overview and examples.
|
|
1093
1128
|
|
|
1094
1129
|
### Debugging
|
|
1095
1130
|
|
|
@@ -1139,6 +1174,10 @@ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day
|
|
|
1139
1174
|
|
|
1140
1175
|
<!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
|
|
1141
1176
|
No sponsors yet. Be the first!
|
|
1177
|
+
|
|
1178
|
+
### Open Collective for Donors
|
|
1179
|
+
|
|
1180
|
+
[Bill Woika](https://opencollective.com/bill-woika)
|
|
1142
1181
|
<!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
|
|
1143
1182
|
|
|
1144
1183
|
[kettle-readme-backers]: https://github.com/ruby-oauth/oauth2/blob/main/exe/kettle-readme-backers
|
|
@@ -1257,7 +1296,7 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
|
|
|
1257
1296
|
|
|
1258
1297
|
<ul>
|
|
1259
1298
|
<li>
|
|
1260
|
-
Copyright (c) 2017 –
|
|
1299
|
+
Copyright (c) 2017 – 2026 Peter H. Boling, of
|
|
1261
1300
|
<a href="https://discord.gg/3qme4XHNKN">
|
|
1262
1301
|
Galtzo.com
|
|
1263
1302
|
<picture>
|
|
@@ -1384,8 +1423,6 @@ Thanks for RTFM. ☺️
|
|
|
1384
1423
|
[📜gh-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
|
|
1385
1424
|
[👽dl-rank]: https://bestgems.org/gems/oauth2
|
|
1386
1425
|
[👽dl-ranki]: https://img.shields.io/gem/rd/oauth2.svg
|
|
1387
|
-
[👽oss-help]: https://www.codetriage.com/ruby-oauth/oauth2
|
|
1388
|
-
[👽oss-helpi]: https://www.codetriage.com/ruby-oauth/oauth2/badges/users.svg
|
|
1389
1426
|
[👽version]: https://bestgems.org/gems/oauth2
|
|
1390
1427
|
[👽versioni]: https://img.shields.io/gem/v/oauth2.svg
|
|
1391
1428
|
[🏀qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/oauth2
|
|
@@ -1477,7 +1514,7 @@ Thanks for RTFM. ☺️
|
|
|
1477
1514
|
[📌gitmoji]: https://gitmoji.dev
|
|
1478
1515
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
1479
1516
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
1480
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.
|
|
1517
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.515-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
1481
1518
|
[🔐security]: SECURITY.md
|
|
1482
1519
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
1483
1520
|
[🔐irp]: IRP.md
|
data/RUBOCOP.md
CHANGED
|
File without changes
|
data/SECURITY.md
CHANGED
|
@@ -12,7 +12,7 @@ To report a security vulnerability, please use the
|
|
|
12
12
|
[Tidelift security contact](https://tidelift.com/security).
|
|
13
13
|
Tidelift will coordinate the fix and disclosure.
|
|
14
14
|
|
|
15
|
-
More detailed explanation of the process is in [IRP.md][IRP]
|
|
15
|
+
More detailed explanation of the process is in [IRP.md][IRP].
|
|
16
16
|
|
|
17
17
|
## Additional Support
|
|
18
18
|
|
data/THREAT_MODEL.md
CHANGED
|
@@ -63,7 +63,16 @@ This document outlines the threat model for the `oauth2` Ruby gem, which impleme
|
|
|
63
63
|
- Validate and sanitize all inputs
|
|
64
64
|
- Use parameterized queries and safe APIs
|
|
65
65
|
|
|
66
|
-
### 5.7
|
|
66
|
+
### 5.7 Request-Target Trust Boundary Expansion
|
|
67
|
+
- **Threat:** Applications may pass untrusted or insufficiently validated absolute URLs into request paths that can carry OAuth credentials or authenticated state.
|
|
68
|
+
- **Risk:** This can expand trust boundaries, contributing to token leakage, authenticated requests to unintended hosts, or SSRF-like pivoting in the surrounding application.
|
|
69
|
+
- **Mitigations:**
|
|
70
|
+
- Prefer relative paths where practical
|
|
71
|
+
- Do not pass untrusted absolute URLs into token-bearing clients
|
|
72
|
+
- Validate or allowlist outbound request targets at the application layer
|
|
73
|
+
- Treat request-target validation as a separate concern from log redaction and token storage
|
|
74
|
+
|
|
75
|
+
### 5.8 Insufficient Logging and Monitoring
|
|
67
76
|
- **Threat:** Attacks go undetected
|
|
68
77
|
- **Mitigations:**
|
|
69
78
|
- Log security-relevant events (without sensitive data)
|
data/lib/oauth2/access_token.rb
CHANGED
|
@@ -57,26 +57,23 @@ module OAuth2
|
|
|
57
57
|
def from_hash(client, hash)
|
|
58
58
|
fresh = hash.dup
|
|
59
59
|
# If token_name is present, then use that key name
|
|
60
|
-
key
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
extra_tokens_warning(supported_keys, t_key)
|
|
70
|
-
t_key
|
|
71
|
-
end
|
|
60
|
+
if fresh.key?(:token_name)
|
|
61
|
+
t_key = fresh[:token_name]
|
|
62
|
+
no_tokens_warning(fresh, t_key)
|
|
63
|
+
else
|
|
64
|
+
# Otherwise, if one of the supported default keys is present, use whichever has precedence
|
|
65
|
+
supported_keys = TOKEN_KEY_LOOKUP & fresh.keys
|
|
66
|
+
t_key = supported_keys[0]
|
|
67
|
+
extra_tokens_warning(supported_keys, t_key)
|
|
68
|
+
end
|
|
72
69
|
# :nocov:
|
|
73
70
|
# TODO: Get rid of this branching logic when dropping Hashie < v3.2
|
|
74
71
|
token = if !defined?(Hashie::VERSION) # i.e. <= "1.1.0"; the first Hashie to ship with a VERSION constant
|
|
75
72
|
warn("snaky_hash and oauth2 will drop support for Hashie v0 in the next major version. Please upgrade to a modern Hashie.")
|
|
76
73
|
# There is a bug in Hashie v0, which is accounts for.
|
|
77
|
-
fresh.delete(
|
|
74
|
+
fresh.delete(t_key) || fresh[t_key] || ""
|
|
78
75
|
else
|
|
79
|
-
fresh.delete(
|
|
76
|
+
fresh.delete(t_key) || ""
|
|
80
77
|
end
|
|
81
78
|
# :nocov:
|
|
82
79
|
new(client, token, fresh)
|
data/lib/oauth2/authenticator.rb
CHANGED
|
@@ -51,13 +51,15 @@ module OAuth2
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
class << self
|
|
55
|
+
# Encodes a Basic Authorization header value for the provided credentials.
|
|
56
|
+
#
|
|
57
|
+
# @param [String] user The client identifier
|
|
58
|
+
# @param [String] password The client secret
|
|
59
|
+
# @return [String] The value to use for the Authorization header
|
|
60
|
+
def encode_basic_auth(user, password)
|
|
61
|
+
"Basic #{Base64.strict_encode64("#{user}:#{password}")}"
|
|
62
|
+
end
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
private
|
data/lib/oauth2/client.rb
CHANGED
|
@@ -42,7 +42,7 @@ module OAuth2
|
|
|
42
42
|
# @option options [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday
|
|
43
43
|
# @option options [Boolean] :raise_errors (true) whether to raise an OAuth2::Error on responses with 400+ status codes
|
|
44
44
|
# @option options [Integer] :max_redirects (5) maximum number of redirects to follow
|
|
45
|
-
# @option options [Logger] :logger (::Logger.new($stdout)) Logger instance for HTTP request/response output; requires OAUTH_DEBUG to be true
|
|
45
|
+
# @option options [Logger] :logger (::Logger.new($stdout)) Logger instance for HTTP request/response output; requires OAUTH_DEBUG to be true. When debug logging is enabled, sensitive values are filtered using {Auth::Sanitizer::SanitizedLogger} initialized from `OAuth2.config[:filtered_label]` and the key names in `OAuth2.config[:filtered_debug_keys]`.
|
|
46
46
|
# @option options [Class] :access_token_class (AccessToken) class to use for access tokens; you can subclass OAuth2::AccessToken, @version 2.0+
|
|
47
47
|
# @option options [Hash] :ssl SSL options for Faraday
|
|
48
48
|
#
|
|
@@ -563,7 +563,15 @@ module OAuth2
|
|
|
563
563
|
end
|
|
564
564
|
|
|
565
565
|
def oauth_debug_logging(builder)
|
|
566
|
-
builder.response(
|
|
566
|
+
builder.response(
|
|
567
|
+
:logger,
|
|
568
|
+
Auth::Sanitizer::SanitizedLogger.new(
|
|
569
|
+
options[:logger],
|
|
570
|
+
filtered_keys: OAuth2.config[:filtered_debug_keys],
|
|
571
|
+
label: OAuth2.config[:filtered_label],
|
|
572
|
+
),
|
|
573
|
+
bodies: true,
|
|
574
|
+
) if OAuth2::OAUTH_DEBUG
|
|
567
575
|
end
|
|
568
576
|
end
|
|
569
577
|
end
|
data/lib/oauth2/error.rb
CHANGED
|
@@ -17,6 +17,8 @@ module OAuth2
|
|
|
17
17
|
# @param [OAuth2::Response, Hash, Object] response A Response or error payload
|
|
18
18
|
def initialize(response)
|
|
19
19
|
@response = response
|
|
20
|
+
@code = nil
|
|
21
|
+
@description = nil
|
|
20
22
|
if response.respond_to?(:parsed)
|
|
21
23
|
if response.parsed.is_a?(Hash)
|
|
22
24
|
@code = response.parsed["error"]
|
|
@@ -1,52 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module OAuth2
|
|
2
|
-
#
|
|
4
|
+
# Permanent alias for {Auth::Sanitizer::FilteredAttributes}.
|
|
3
5
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# @param [Class] base The including class
|
|
12
|
-
# @return [void]
|
|
13
|
-
def self.included(base)
|
|
14
|
-
base.extend(ClassMethods)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Class-level helpers for configuring filtered attributes.
|
|
18
|
-
module ClassMethods
|
|
19
|
-
# Declare attributes that should be redacted in inspect output.
|
|
20
|
-
#
|
|
21
|
-
# @param [Array<Symbol, String>] attributes One or more attribute names
|
|
22
|
-
# @return [void]
|
|
23
|
-
def filtered_attributes(*attributes)
|
|
24
|
-
@filtered_attribute_names = attributes.map(&:to_sym)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# The configured attribute names to filter.
|
|
28
|
-
#
|
|
29
|
-
# @return [Array<Symbol>]
|
|
30
|
-
def filtered_attribute_names
|
|
31
|
-
@filtered_attribute_names || []
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Custom inspect that redacts configured attributes.
|
|
36
|
-
#
|
|
37
|
-
# @return [String]
|
|
38
|
-
def inspect
|
|
39
|
-
filtered_attribute_names = self.class.filtered_attribute_names
|
|
40
|
-
return super if filtered_attribute_names.empty?
|
|
41
|
-
|
|
42
|
-
inspected_vars = instance_variables.map do |var|
|
|
43
|
-
if filtered_attribute_names.any? { |filtered_var| var.to_s.include?(filtered_var.to_s) }
|
|
44
|
-
"#{var}=[FILTERED]"
|
|
45
|
-
else
|
|
46
|
-
"#{var}=#{instance_variable_get(var).inspect}"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
"#<#{self.class}:#{object_id} #{inspected_vars.join(", ")}>"
|
|
50
|
-
end
|
|
51
|
-
end
|
|
6
|
+
# This constant is intentionally kept in the `OAuth2` namespace because it
|
|
7
|
+
# was part of the public API before the implementation was extracted into the
|
|
8
|
+
# `auth-sanitizer` gem. It will **not** be deprecated or removed.
|
|
9
|
+
#
|
|
10
|
+
# New code that does not need the `OAuth2::` namespace can use
|
|
11
|
+
# {Auth::Sanitizer::FilteredAttributes} directly.
|
|
12
|
+
FilteredAttributes = Auth::Sanitizer::FilteredAttributes
|
|
52
13
|
end
|
data/lib/oauth2/response.rb
CHANGED
|
@@ -43,18 +43,20 @@ module OAuth2
|
|
|
43
43
|
"text/plain" => :text,
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
key
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
class << self
|
|
47
|
+
# Adds a new content type parser.
|
|
48
|
+
#
|
|
49
|
+
# @param [Symbol] key A descriptive symbol key such as :json or :query
|
|
50
|
+
# @param [Array<String>, String] mime_types One or more mime types to which this parser applies
|
|
51
|
+
# @yield [String] Block that will be called to parse the response body
|
|
52
|
+
# @yieldparam [String] body The response body to parse
|
|
53
|
+
# @return [void]
|
|
54
|
+
def register_parser(key, mime_types, &block)
|
|
55
|
+
key = key.to_sym
|
|
56
|
+
@@parsers[key] = block
|
|
57
|
+
Array(mime_types).each do |mime_type|
|
|
58
|
+
@@content_types[mime_type] = key
|
|
59
|
+
end
|
|
58
60
|
end
|
|
59
61
|
end
|
|
60
62
|
|
|
File without changes
|
|
File without changes
|
data/lib/oauth2/strategy/base.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/oauth2/version.rb
CHANGED
data/lib/oauth2.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# includes modules from stdlib
|
|
4
|
-
require "cgi"
|
|
4
|
+
require "cgi/escape"
|
|
5
5
|
require "time"
|
|
6
6
|
|
|
7
7
|
# third party gems
|
|
8
|
+
require "auth/sanitizer"
|
|
8
9
|
require "snaky_hash"
|
|
9
10
|
require "version_gem"
|
|
10
11
|
|
|
@@ -43,38 +44,59 @@ module OAuth2
|
|
|
43
44
|
# config[:silence_no_tokens_warning] = false
|
|
44
45
|
# end
|
|
45
46
|
#
|
|
47
|
+
# @example Customize filtered output markers and debug-log value filtering by key name
|
|
48
|
+
# OAuth2.configure do |config|
|
|
49
|
+
# config[:filtered_label] = "[REDACTED]"
|
|
50
|
+
# config[:filtered_debug_keys] += ["client_assertion"]
|
|
51
|
+
# end
|
|
52
|
+
#
|
|
53
|
+
# Existing objects and logger wrappers snapshot filtering configuration during
|
|
54
|
+
# initialization. Changing these config values later affects only newly
|
|
55
|
+
# initialized objects and debug loggers.
|
|
56
|
+
#
|
|
46
57
|
# @return [SnakyHash::SymbolKeyed] A mutable Hash-like config with symbol keys
|
|
47
58
|
DEFAULT_CONFIG = SnakyHash::SymbolKeyed.new(
|
|
48
59
|
silence_extra_tokens_warning: true,
|
|
49
60
|
silence_no_tokens_warning: true,
|
|
61
|
+
filtered_label: "[FILTERED]",
|
|
62
|
+
filtered_debug_keys: %w[
|
|
63
|
+
access_token
|
|
64
|
+
refresh_token
|
|
65
|
+
id_token
|
|
66
|
+
client_secret
|
|
67
|
+
assertion
|
|
68
|
+
code_verifier
|
|
69
|
+
token
|
|
70
|
+
],
|
|
50
71
|
)
|
|
51
72
|
|
|
52
73
|
# The current runtime configuration for the library.
|
|
53
74
|
#
|
|
54
75
|
# @return [SnakyHash::SymbolKeyed]
|
|
55
|
-
|
|
76
|
+
CONFIG = DEFAULT_CONFIG.dup
|
|
56
77
|
|
|
57
78
|
class << self
|
|
58
|
-
|
|
79
|
+
def config
|
|
80
|
+
CONFIG
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Configure global library behavior.
|
|
59
84
|
#
|
|
60
|
-
#
|
|
85
|
+
# Yields the mutable configuration object so callers can update settings.
|
|
61
86
|
#
|
|
62
|
-
# @
|
|
63
|
-
|
|
87
|
+
# @yieldparam [SnakyHash::SymbolKeyed] config the configuration object
|
|
88
|
+
# @return [void]
|
|
89
|
+
def configure
|
|
90
|
+
yield config
|
|
91
|
+
end
|
|
64
92
|
end
|
|
65
|
-
|
|
66
|
-
# Configure global library behavior.
|
|
67
|
-
#
|
|
68
|
-
# Yields the mutable configuration object so callers can update settings.
|
|
69
|
-
#
|
|
70
|
-
# @yieldparam [SnakyHash::SymbolKeyed] config the configuration object
|
|
71
|
-
# @return [void]
|
|
72
|
-
def configure
|
|
73
|
-
yield @config
|
|
74
|
-
end
|
|
75
|
-
module_function :configure
|
|
76
93
|
end
|
|
77
94
|
|
|
95
|
+
# Wire Auth::Sanitizer's label provider to read from OAuth2.config so that
|
|
96
|
+
# FilteredAttributes-bearing objects and Auth::Sanitizer::SanitizedLogger instances
|
|
97
|
+
# pick up OAuth2.config[:filtered_label] at their initialization time.
|
|
98
|
+
Auth::Sanitizer.filtered_label_provider = -> { OAuth2.config[:filtered_label] }
|
|
99
|
+
|
|
78
100
|
# Extend OAuth2::Version with VersionGem helpers to provide semantic version helpers.
|
|
79
101
|
OAuth2::Version.class_eval do
|
|
80
102
|
extend VersionGem::Basic
|
data/sig/oauth2/access_token.rbs
CHANGED
|
File without changes
|
|
File without changes
|
data/sig/oauth2/client.rbs
CHANGED
|
File without changes
|
data/sig/oauth2/error.rbs
CHANGED
|
File without changes
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
module OAuth2
|
|
2
2
|
module FilteredAttributes
|
|
3
|
+
module InitializerMethods
|
|
4
|
+
def initialize: (*untyped args) { () -> untyped } -> untyped
|
|
5
|
+
end
|
|
6
|
+
|
|
3
7
|
def self.included: (untyped) -> untyped
|
|
4
|
-
def filtered_attributes: (*String) -> void
|
|
8
|
+
def filtered_attributes: (*(String | Symbol)) -> void
|
|
9
|
+
def thing_filter: () -> OAuth2::ThingFilter
|
|
5
10
|
end
|
|
6
11
|
end
|
data/sig/oauth2/response.rbs
CHANGED
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module OAuth2
|
|
2
|
+
class SanitizedLogger
|
|
3
|
+
def initialize: (untyped logger) -> void
|
|
4
|
+
|
|
5
|
+
def add: (untyped severity, ?untyped message, ?untyped progname) { () -> untyped } -> untyped
|
|
6
|
+
def <<: (String message) -> untyped
|
|
7
|
+
def debug: (?untyped progname) { () -> untyped } -> untyped
|
|
8
|
+
def info: (?untyped progname) { () -> untyped } -> untyped
|
|
9
|
+
def warn: (?untyped progname) { () -> untyped } -> untyped
|
|
10
|
+
def error: (?untyped progname) { () -> untyped } -> untyped
|
|
11
|
+
def fatal: (?untyped progname) { () -> untyped } -> untyped
|
|
12
|
+
def unknown: (?untyped progname) { () -> untyped } -> untyped
|
|
13
|
+
def close: () -> void
|
|
14
|
+
def formatter: () -> untyped
|
|
15
|
+
def formatter=: (untyped formatter) -> void
|
|
16
|
+
def level: () -> untyped
|
|
17
|
+
def level=: (untyped level) -> void
|
|
18
|
+
def progname: () -> untyped
|
|
19
|
+
def progname=: (untyped progname) -> void
|
|
20
|
+
def respond_to_missing?: (Symbol method_name, ?bool include_private) -> bool
|
|
21
|
+
def method_missing: (Symbol method_name, *untyped args) { () -> untyped } -> untyped
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def log: (Symbol level, ?untyped progname) { () -> untyped } -> untyped
|
|
26
|
+
def sanitize: (untyped message) -> untyped
|
|
27
|
+
def thing_filter: () -> OAuth2::ThingFilter
|
|
28
|
+
def sanitize_authorization_header: (String message) -> String
|
|
29
|
+
def sanitize_json_pairs: (String message) -> String
|
|
30
|
+
def sanitize_form_and_query_pairs: (String message) -> String
|
|
31
|
+
end
|
|
32
|
+
end
|
data/sig/oauth2/strategy.rbs
CHANGED
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module OAuth2
|
|
2
|
+
class ThingFilter
|
|
3
|
+
attr_reader things: Array[String]
|
|
4
|
+
attr_reader label: String
|
|
5
|
+
|
|
6
|
+
def initialize: (Enumerable[untyped] things, label: String) -> void
|
|
7
|
+
def filtered?: (untyped thing_name) -> bool
|
|
8
|
+
def pattern_source: () -> String
|
|
9
|
+
end
|
|
10
|
+
end
|
data/sig/oauth2/version.rbs
CHANGED
|
File without changes
|
data/sig/oauth2.rbs
CHANGED
|
File without changes
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: oauth2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Boling
|
|
@@ -39,6 +39,20 @@ cert_chain:
|
|
|
39
39
|
-----END CERTIFICATE-----
|
|
40
40
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
41
41
|
dependencies:
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: auth-sanitizer
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - "~>"
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0.1'
|
|
49
|
+
type: :runtime
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - "~>"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0.1'
|
|
42
56
|
- !ruby/object:Gem::Dependency
|
|
43
57
|
name: faraday
|
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -227,14 +241,14 @@ dependencies:
|
|
|
227
241
|
requirements:
|
|
228
242
|
- - "~>"
|
|
229
243
|
- !ruby/object:Gem::Version
|
|
230
|
-
version: '
|
|
244
|
+
version: '2.0'
|
|
231
245
|
type: :development
|
|
232
246
|
prerelease: false
|
|
233
247
|
version_requirements: !ruby/object:Gem::Requirement
|
|
234
248
|
requirements:
|
|
235
249
|
- - "~>"
|
|
236
250
|
- !ruby/object:Gem::Version
|
|
237
|
-
version: '
|
|
251
|
+
version: '2.0'
|
|
238
252
|
- !ruby/object:Gem::Dependency
|
|
239
253
|
name: bundler-audit
|
|
240
254
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -290,6 +304,9 @@ dependencies:
|
|
|
290
304
|
- - "~>"
|
|
291
305
|
- !ruby/object:Gem::Version
|
|
292
306
|
version: '3.0'
|
|
307
|
+
- - ">="
|
|
308
|
+
- !ruby/object:Gem::Version
|
|
309
|
+
version: 3.0.6
|
|
293
310
|
type: :development
|
|
294
311
|
prerelease: false
|
|
295
312
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -297,6 +314,9 @@ dependencies:
|
|
|
297
314
|
- - "~>"
|
|
298
315
|
- !ruby/object:Gem::Version
|
|
299
316
|
version: '3.0'
|
|
317
|
+
- - ">="
|
|
318
|
+
- !ruby/object:Gem::Version
|
|
319
|
+
version: 3.0.6
|
|
300
320
|
- !ruby/object:Gem::Dependency
|
|
301
321
|
name: kettle-test
|
|
302
322
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -306,7 +326,7 @@ dependencies:
|
|
|
306
326
|
version: '1.0'
|
|
307
327
|
- - ">="
|
|
308
328
|
- !ruby/object:Gem::Version
|
|
309
|
-
version: 1.0.
|
|
329
|
+
version: 1.0.10
|
|
310
330
|
type: :development
|
|
311
331
|
prerelease: false
|
|
312
332
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -316,7 +336,7 @@ dependencies:
|
|
|
316
336
|
version: '1.0'
|
|
317
337
|
- - ">="
|
|
318
338
|
- !ruby/object:Gem::Version
|
|
319
|
-
version: 1.0.
|
|
339
|
+
version: 1.0.10
|
|
320
340
|
- !ruby/object:Gem::Dependency
|
|
321
341
|
name: ruby-progressbar
|
|
322
342
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -340,7 +360,7 @@ dependencies:
|
|
|
340
360
|
version: '1.0'
|
|
341
361
|
- - ">="
|
|
342
362
|
- !ruby/object:Gem::Version
|
|
343
|
-
version: 1.0.
|
|
363
|
+
version: 1.0.3
|
|
344
364
|
type: :development
|
|
345
365
|
prerelease: false
|
|
346
366
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -350,7 +370,7 @@ dependencies:
|
|
|
350
370
|
version: '1.0'
|
|
351
371
|
- - ">="
|
|
352
372
|
- !ruby/object:Gem::Version
|
|
353
|
-
version: 1.0.
|
|
373
|
+
version: 1.0.3
|
|
354
374
|
- !ruby/object:Gem::Dependency
|
|
355
375
|
name: gitmoji-regex
|
|
356
376
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -447,17 +467,19 @@ files:
|
|
|
447
467
|
- sig/oauth2/error.rbs
|
|
448
468
|
- sig/oauth2/filtered_attributes.rbs
|
|
449
469
|
- sig/oauth2/response.rbs
|
|
470
|
+
- sig/oauth2/sanitized_logger.rbs
|
|
450
471
|
- sig/oauth2/strategy.rbs
|
|
472
|
+
- sig/oauth2/thing_filter.rbs
|
|
451
473
|
- sig/oauth2/version.rbs
|
|
452
474
|
homepage: https://github.com/ruby-oauth/oauth2
|
|
453
475
|
licenses:
|
|
454
476
|
- MIT
|
|
455
477
|
metadata:
|
|
456
478
|
homepage_uri: https://oauth2.galtzo.com/
|
|
457
|
-
source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.
|
|
458
|
-
changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.
|
|
479
|
+
source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.19
|
|
480
|
+
changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.19/CHANGELOG.md
|
|
459
481
|
bug_tracker_uri: https://github.com/ruby-oauth/oauth2/issues
|
|
460
|
-
documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.
|
|
482
|
+
documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.19
|
|
461
483
|
mailing_list_uri: https://groups.google.com/g/oauth-ruby
|
|
462
484
|
funding_uri: https://github.com/sponsors/pboling
|
|
463
485
|
wiki_uri: https://gitlab.com/ruby-oauth/oauth2/-/wiki
|
|
@@ -466,11 +488,11 @@ metadata:
|
|
|
466
488
|
rubygems_mfa_required: 'true'
|
|
467
489
|
post_install_message: |2
|
|
468
490
|
|
|
469
|
-
---+++--- oauth2 v2.0.
|
|
491
|
+
---+++--- oauth2 v2.0.19 ---+++---
|
|
470
492
|
|
|
471
493
|
(minor) ⚠️ BREAKING CHANGES ⚠️ when upgrading from < v2
|
|
472
494
|
• Summary of breaking changes: https://gitlab.com/ruby-oauth/oauth2#what-is-new-for-v20
|
|
473
|
-
• Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.
|
|
495
|
+
• Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.19/CHANGELOG.md#2015-2025-09-08
|
|
474
496
|
|
|
475
497
|
News:
|
|
476
498
|
1. New documentation website, including for OAuth 2.1 and OIDC: https://oauth2.galtzo.com
|
|
@@ -513,7 +535,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
513
535
|
- !ruby/object:Gem::Version
|
|
514
536
|
version: '0'
|
|
515
537
|
requirements: []
|
|
516
|
-
rubygems_version:
|
|
538
|
+
rubygems_version: 4.0.11
|
|
517
539
|
specification_version: 4
|
|
518
540
|
summary: "\U0001F510 OAuth 2.0, 2.1 & OIDC Core Ruby implementation"
|
|
519
541
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|