oauth2 2.0.3 → 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +202 -139
- data/CONTRIBUTING.md +5 -5
- data/LICENSE +1 -1
- data/README.md +95 -73
- data/SECURITY.md +12 -6
- data/lib/oauth2/access_token.rb +38 -8
- data/lib/oauth2/client.rb +49 -24
- data/lib/oauth2/error.rb +17 -9
- data/lib/oauth2/response.rb +6 -2
- data/lib/oauth2/strategy/assertion.rb +1 -1
- data/lib/oauth2/strategy/auth_code.rb +1 -1
- data/lib/oauth2/strategy/client_credentials.rb +1 -1
- data/lib/oauth2/version.rb +1 -1
- data/lib/oauth2.rb +10 -2
- metadata +40 -29
- data/lib/oauth2/snaky_hash.rb +0 -8
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
<p align="center">
|
2
2
|
<a href="http://oauth.net/2/" target="_blank" rel="noopener">
|
3
|
-
<img src="https://github.com/oauth-xx/oauth2/raw/
|
3
|
+
<img src="https://github.com/oauth-xx/oauth2/raw/main/docs/images/logo/oauth2-logo-124px.png?raw=true" alt="OAuth 2.0 Logo by Chris Messina, CC BY-SA 3.0">
|
4
4
|
</a>
|
5
5
|
<a href="https://www.ruby-lang.org/" target="_blank" rel="noopener">
|
6
|
-
<img width="124px" src="https://github.com/oauth-xx/oauth2/raw/
|
6
|
+
<img width="124px" src="https://github.com/oauth-xx/oauth2/raw/main/docs/images/logo/ruby-logo-198px.svg?raw=true" alt="Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5">
|
7
7
|
</a>
|
8
8
|
</p>
|
9
9
|
|
@@ -21,7 +21,7 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
|
21
21
|
* [oauth sibling gem][sibling-gem] for OAuth 1.0 implementations in Ruby.
|
22
22
|
|
23
23
|
[oauth2-spec]: https://oauth.net/2/
|
24
|
-
[sibling-gem]: https://
|
24
|
+
[sibling-gem]: https://gitlab.com/oauth-xx/oauth
|
25
25
|
|
26
26
|
## Release Documentation
|
27
27
|
|
@@ -32,10 +32,16 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
|
32
32
|
|
33
33
|
| Version | Release Date | Readme |
|
34
34
|
|---------|--------------|----------------------------------------------------------|
|
35
|
-
| 2.0.
|
36
|
-
| 2.0.
|
37
|
-
| 2.0.
|
38
|
-
| 2.0.
|
35
|
+
| 2.0.9 | 2022-09-16 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.9/README.md |
|
36
|
+
| 2.0.8 | 2022-09-01 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.8/README.md |
|
37
|
+
| 2.0.7 | 2022-08-22 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.7/README.md |
|
38
|
+
| 2.0.6 | 2022-07-13 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.6/README.md |
|
39
|
+
| 2.0.5 | 2022-07-07 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.5/README.md |
|
40
|
+
| 2.0.4 | 2022-07-01 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.4/README.md |
|
41
|
+
| 2.0.3 | 2022-06-28 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.3/README.md |
|
42
|
+
| 2.0.2 | 2022-06-24 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.2/README.md |
|
43
|
+
| 2.0.1 | 2022-06-22 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.1/README.md |
|
44
|
+
| 2.0.0 | 2022-06-21 | https://gitlab.com/oauth-xx/oauth2/-/blob/v2.0.0/README.md |
|
39
45
|
</details>
|
40
46
|
|
41
47
|
### Older Releases
|
@@ -43,18 +49,20 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
|
43
49
|
<details>
|
44
50
|
<summary>1.4.x Readmes</summary>
|
45
51
|
|
46
|
-
| Version | Release Date | Readme
|
47
|
-
|
48
|
-
| 1.4.
|
49
|
-
| 1.4.
|
50
|
-
| 1.4.
|
51
|
-
| 1.4.
|
52
|
-
| 1.4.
|
53
|
-
| 1.4.
|
54
|
-
| 1.4.
|
55
|
-
| 1.4.
|
56
|
-
| 1.4.
|
57
|
-
| 1.4.
|
52
|
+
| Version | Release Date | Readme |
|
53
|
+
|---------|--------------|-------------------------------------------------------------|
|
54
|
+
| 1.4.11 | Sep 16, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.11/README.md |
|
55
|
+
| 1.4.10 | Jul 1, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.10/README.md |
|
56
|
+
| 1.4.9 | Feb 20, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.9/README.md |
|
57
|
+
| 1.4.8 | Feb 18, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.8/README.md |
|
58
|
+
| 1.4.7 | Mar 19, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.7/README.md |
|
59
|
+
| 1.4.6 | Mar 19, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.6/README.md |
|
60
|
+
| 1.4.5 | Mar 18, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.5/README.md |
|
61
|
+
| 1.4.4 | Feb 12, 2020 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.4/README.md |
|
62
|
+
| 1.4.3 | Jan 29, 2020 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.3/README.md |
|
63
|
+
| 1.4.2 | Oct 1, 2019 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.2/README.md |
|
64
|
+
| 1.4.1 | Oct 13, 2018 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.1/README.md |
|
65
|
+
| 1.4.0 | Jun 9, 2017 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.0/README.md |
|
58
66
|
</details>
|
59
67
|
|
60
68
|
<details>
|
@@ -62,8 +70,8 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
|
62
70
|
|
63
71
|
| Version | Release Date | Readme |
|
64
72
|
|----------|--------------|----------------------------------------------------------|
|
65
|
-
| 1.3.1 | Mar 3, 2017 | https://
|
66
|
-
| 1.3.0 | Dec 27, 2016 | https://
|
73
|
+
| 1.3.1 | Mar 3, 2017 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.3.1/README.md |
|
74
|
+
| 1.3.0 | Dec 27, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.3.0/README.md |
|
67
75
|
</details>
|
68
76
|
|
69
77
|
<details>
|
@@ -71,10 +79,10 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
|
71
79
|
|
72
80
|
| Version | Release Date | Readme |
|
73
81
|
|----------|--------------|----------------------------------------------------------|
|
74
|
-
| 1.2.0 | Jun 30, 2016 | https://
|
75
|
-
| 1.1.0 | Jan 30, 2016 | https://
|
76
|
-
| 1.0.0 | May 23, 2014 | https://
|
77
|
-
| < 1.0.0 | Find here | https://
|
82
|
+
| 1.2.0 | Jun 30, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.2.0/README.md |
|
83
|
+
| 1.1.0 | Jan 30, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.1.0/README.md |
|
84
|
+
| 1.0.0 | May 23, 2014 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.0.0/README.md |
|
85
|
+
| < 1.0.0 | Find here | https://gitlab.com/oauth-xx/oauth2/-/tags |
|
78
86
|
</details>
|
79
87
|
|
80
88
|
## Status
|
@@ -106,15 +114,15 @@ appended indicators:
|
|
106
114
|
♻️ - URL needs to be updated from SASS integration. Find / Replace is insufficient.
|
107
115
|
-->
|
108
116
|
|
109
|
-
| | Project | bundle add oauth2
|
110
|
-
|
111
|
-
| 1️⃣ | name, license, docs | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]
|
112
|
-
| 2️⃣ | version & activity | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home]
|
113
|
-
| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]
|
114
|
-
| 4️⃣ | testing | [![
|
115
|
-
| 5️⃣ | coverage & security | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]
|
116
|
-
| 6️⃣ | resources | [![Discussion][⛳
|
117
|
-
| 7️⃣ | spread 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]
|
117
|
+
| | Project | bundle add oauth2 |
|
118
|
+
|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
119
|
+
| 1️⃣ | name, license, docs | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard] |
|
120
|
+
| 2️⃣ | version & activity | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] |
|
121
|
+
| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
|
122
|
+
| 4️⃣ | testing | [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf] |
|
123
|
+
| 5️⃣ | coverage & security | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf] |
|
124
|
+
| 6️⃣ | resources | [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki] |
|
125
|
+
| 7️⃣ | spread 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] |
|
118
126
|
|
119
127
|
<!--
|
120
128
|
The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
|
@@ -135,23 +143,17 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
135
143
|
[⛳️version-img]: http://img.shields.io/gem/v/oauth2.svg
|
136
144
|
[🖇DL-total-img]: https://img.shields.io/gem/dt/oauth2.svg
|
137
145
|
[🏘DL-rank-img]: https://img.shields.io/gem/rt/oauth2.svg
|
138
|
-
[🚎src-home]: https://
|
139
|
-
[🚎src-home-img]: https://img.shields.io/badge/source-
|
140
|
-
|
141
|
-
|
142
|
-
[🧮prs-c]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
|
143
|
-
[🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
|
144
|
-
[📗next♻️]: https://github.com/oauth-xx/oauth2/milestone/15
|
145
|
-
[📗next-img♻️]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/15?label=Next%20Version
|
146
|
-
|
147
|
-
<!-- 3️⃣ maintanence & linting -->
|
146
|
+
[🚎src-home]: https://gitlab.com/oauth-xx/oauth2/
|
147
|
+
[🚎src-home-img]: https://img.shields.io/badge/source-gitlab-blue.svg?style=flat
|
148
|
+
|
149
|
+
<!-- 3️⃣ maintenance & linting -->
|
148
150
|
[⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
|
149
151
|
[⛳cclim-maint-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
|
150
152
|
[🖇triage-help]: https://www.codetriage.com/oauth-xx/oauth2
|
151
153
|
[🖇triage-help-img]: https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg
|
152
154
|
[🏘depfu♻️]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
|
153
155
|
[🏘depfu-img♻️]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
|
154
|
-
[🚎contributors]: https://
|
156
|
+
[🚎contributors]: https://gitlab.com/oauth-xx/oauth2/-/graphs/main
|
155
157
|
[🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
|
156
158
|
[🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
|
157
159
|
[🖐style-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml/badge.svg
|
@@ -159,10 +161,6 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
159
161
|
[🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/oauth-xx/oauth2
|
160
162
|
|
161
163
|
<!-- 4️⃣ testing -->
|
162
|
-
[⛳iss-o]: https://github.com/oauth-xx/oauth2/issues
|
163
|
-
[⛳iss-o-img]: https://img.shields.io/github/issues-raw/oauth-xx/oauth2
|
164
|
-
[🖇iss-c]: https://github.com/oauth-xx/oauth2/issues?q=is%3Aissue+is%3Aclosed
|
165
|
-
[🖇iss-c-img]: https://img.shields.io/github/issues-closed-raw/oauth-xx/oauth2
|
166
164
|
[🏘sup-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
|
167
165
|
[🏘sup-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
|
168
166
|
[🚎heads-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/heads.yml
|
@@ -177,11 +175,11 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
177
175
|
<!-- 5️⃣ coverage & security -->
|
178
176
|
[⛳cclim-cov]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
|
179
177
|
[⛳cclim-cov-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage
|
180
|
-
[🖇codecov-img♻️]: https://codecov.io/gh/oauth-xx/oauth2/branch/
|
178
|
+
[🖇codecov-img♻️]: https://codecov.io/gh/oauth-xx/oauth2/branch/main/graph/badge.svg?token=bNqSzNiuo2
|
181
179
|
[🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
|
182
|
-
[🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=
|
183
|
-
[🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=
|
184
|
-
[🚎sec-pol]: https://
|
180
|
+
[🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=main
|
181
|
+
[🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=main
|
182
|
+
[🚎sec-pol]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/SECURITY.md
|
185
183
|
[🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
|
186
184
|
[🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
|
187
185
|
[🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
|
@@ -189,15 +187,15 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
189
187
|
[🧮cov-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
|
190
188
|
|
191
189
|
<!-- 6️⃣ resources -->
|
192
|
-
[⛳
|
193
|
-
[⛳
|
190
|
+
[⛳gg-discussions]: https://groups.google.com/g/oauth-ruby
|
191
|
+
[⛳gg-discussions-img]: https://img.shields.io/badge/google-group-purple.svg?style=flat
|
194
192
|
[🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
|
195
193
|
[🖇codementor-img]: https://cdn.codementor.io/badges/get_help_github.svg
|
196
194
|
[🏘chat]: https://gitter.im/oauth-xx/oauth2
|
197
195
|
[🏘chat-img]: https://img.shields.io/gitter/room/oauth-xx/oauth2.svg
|
198
196
|
[🚎blog]: http://www.railsbling.com/tags/oauth2/
|
199
197
|
[🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
|
200
|
-
[🖐wiki]: https://
|
198
|
+
[🖐wiki]: https://gitlab.com/oauth-xx/oauth2/-/wikis/home
|
201
199
|
[🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
|
202
200
|
|
203
201
|
<!-- 7️⃣ spread 💖 -->
|
@@ -229,7 +227,9 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
229
227
|
|
230
228
|
Available as part of the Tidelift Subscription.
|
231
229
|
|
232
|
-
The maintainers of OAuth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.]
|
230
|
+
The maintainers of OAuth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.][tidelift-ref]
|
231
|
+
|
232
|
+
[tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise
|
233
233
|
|
234
234
|
## Security contact information
|
235
235
|
|
@@ -253,7 +253,13 @@ For more see [SECURITY.md][🚎sec-pol].
|
|
253
253
|
- `:access_token_class` (`AccessToken`); user specified class to use for all calls to `get_token`
|
254
254
|
- Adds new option to `OAuth2::AccessToken#initialize`:
|
255
255
|
- `:expires_latency` (`nil`); number of seconds by which AccessToken validity will be reduced to offset latency
|
256
|
-
-
|
256
|
+
- By default, keys are transformed to camel case.
|
257
|
+
- Original keys will still work as previously, in most scenarios, thanks to `rash_alt` gem.
|
258
|
+
- However, this is a _breaking_ change if you rely on `response.parsed.to_h`, as the keys in the result will be camel case.
|
259
|
+
- As of version 2.0.4 you can turn key transformation off with the `snaky: false` option.
|
260
|
+
- By default, the `:auth_scheme` is now `:basic_auth` (instead of `:request_body`)
|
261
|
+
- Third-party strategies and gems may need to be updated if a provider was requiring client id/secret in the request body
|
262
|
+
- [... A lot more](https://gitlab.com/oauth-xx/oauth2/-/blob/main/CHANGELOG.md#2.0.0)
|
257
263
|
|
258
264
|
## Compatibility
|
259
265
|
|
@@ -268,8 +274,7 @@ This gem is tested against MRI, JRuby, and Truffleruby.
|
|
268
274
|
Each of those has varying versions that target a specific version of MRI Ruby.
|
269
275
|
This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
|
270
276
|
If you would like to add support for additional engines,
|
271
|
-
|
272
|
-
then submit a PR to the correct maintenance branch as according to the table below.
|
277
|
+
see `gemfiles/README.md`, then submit a PR to the correct maintenance branch as according to the table below.
|
273
278
|
</details>
|
274
279
|
|
275
280
|
<details>
|
@@ -289,17 +294,30 @@ fashion. If critical issues for a particular implementation exist at the time
|
|
289
294
|
of a major release, support for that Ruby version may be dropped.
|
290
295
|
</details>
|
291
296
|
|
292
|
-
| | Ruby
|
293
|
-
|
294
|
-
| 1️⃣ | 2.0.x
|
295
|
-
| 2️⃣ | 1.4.x
|
296
|
-
| 3️⃣ | older
|
297
|
+
| | Ruby OAuth2 Version | Maintenance Branch | Supported Officially | Supported Unofficially | Supported Incidentally |
|
298
|
+
|:----|---------------------|--------------------|-------------------------|------------------------|------------------------|
|
299
|
+
| 1️⃣ | 2.0.x | `main` | 2.7, 3.0, 3.1 | 2.5, 2.6 | 2.2, 2.3, 2.4 |
|
300
|
+
| 2️⃣ | 1.4.x | `1-4-stable` | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4 | 1.9, 2.0 |
|
301
|
+
| 3️⃣ | older | N/A | Best of luck to you! | Please upgrade! | |
|
297
302
|
|
298
|
-
NOTE: The 1.4 series will only receive critical
|
303
|
+
NOTE: The 1.4 series will only receive critical security updates.
|
299
304
|
See [SECURITY.md][🚎sec-pol]
|
300
305
|
|
301
306
|
## Usage Examples
|
302
307
|
|
308
|
+
### Global Configuration
|
309
|
+
|
310
|
+
If you started seeing this warning, but everything it working fine, you can now silence it.
|
311
|
+
```log
|
312
|
+
OAuth2::AccessToken.from_hash: `hash` contained more than one 'token' key
|
313
|
+
```
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
OAuth2.configure do |config|
|
317
|
+
config.silence_extra_tokens_warning = true # default: false
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
303
321
|
### `authorize_url` and `token_url` are on site root (Just Works!)
|
304
322
|
|
305
323
|
```ruby
|
@@ -397,7 +415,7 @@ The `AccessToken` methods `#get`, `#post`, `#put` and `#delete` and the generic
|
|
397
415
|
will return an instance of the #OAuth2::Response class.
|
398
416
|
|
399
417
|
This instance contains a `#parsed` method that will parse the response body and
|
400
|
-
return a Hash-like [`OAuth2::SnakyHash`](https://
|
418
|
+
return a Hash-like [`OAuth2::SnakyHash`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/snaky_hash.rb) if the `Content-Type` is `application/x-www-form-urlencoded` or if
|
401
419
|
the body is a JSON object. It will return an Array if the body is a JSON
|
402
420
|
array. Otherwise, it will return the original body string.
|
403
421
|
|
@@ -427,7 +445,11 @@ Response instance will contain the `OAuth2::Error` instance.
|
|
427
445
|
|
428
446
|
Currently the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
|
429
447
|
authentication grant types have helper strategy classes that simplify client
|
430
|
-
use. They are available via the [`#auth_code`](https://
|
448
|
+
use. They are available via the [`#auth_code`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
|
449
|
+
[`#implicit`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/implicit.rb),
|
450
|
+
[`#password`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/password.rb),
|
451
|
+
[`#client_credentials`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/client_credentials.rb), and
|
452
|
+
[`#assertion`](https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
|
431
453
|
|
432
454
|
These aren't full examples, but demonstrative of the differences between usage for each strategy.
|
433
455
|
```ruby
|
@@ -499,8 +521,8 @@ spec.add_dependency 'oauth2', '~> 2.0'
|
|
499
521
|
|
500
522
|
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]
|
501
523
|
|
502
|
-
[license]: https://
|
503
|
-
[oauth-xx]: https://
|
524
|
+
[license]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/LICENSE
|
525
|
+
[oauth-xx]: https://gitlab.com/oauth-xx
|
504
526
|
[fossa2]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_large
|
505
527
|
|
506
528
|
## Development
|
@@ -513,14 +535,14 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
513
535
|
|
514
536
|
See [CONTRIBUTING.md][contributing]
|
515
537
|
|
516
|
-
[contributing]: https://
|
538
|
+
[contributing]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/CONTRIBUTING.md
|
517
539
|
|
518
540
|
## Contributors
|
519
541
|
|
520
|
-
[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://
|
542
|
+
[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://gitlab.com/oauth-xx/oauth2/-/graphs/main")
|
521
543
|
|
522
544
|
Made with [contributors-img](https://contrib.rocks).
|
523
545
|
|
524
546
|
## Code of Conduct
|
525
547
|
|
526
|
-
Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://
|
548
|
+
Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/oauth-xx/oauth2/-/blob/main/CODE_OF_CONDUCT.md).
|
data/SECURITY.md
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
|
3
3
|
## Supported Versions
|
4
4
|
|
5
|
-
| Version | Supported |
|
6
|
-
|
7
|
-
| 2.latest | ✅
|
8
|
-
| 1.latest | ✅
|
9
|
-
|
|
5
|
+
| Version | Supported | EOL | Post-EOL / Enterprise |
|
6
|
+
|----------|-----------|---------|---------------------------------------|
|
7
|
+
| 2.latest | ✅ | 04/2024 | [Tidelift Subscription][tidelift-ref] |
|
8
|
+
| 1.latest | ✅ | 04/2023 | [Tidelift Subscription][tidelift-ref] |
|
9
|
+
| <= 1 | ⛔ | ⛔ | ⛔ |
|
10
|
+
|
11
|
+
### EOL Policy
|
12
|
+
|
13
|
+
Non-commercial support for the oldest version of Ruby (which itself is going EOL) will be dropped each year in April.
|
10
14
|
|
11
15
|
## Reporting a Vulnerability
|
12
16
|
|
@@ -17,4 +21,6 @@ Tidelift will coordinate the fix and disclosure.
|
|
17
21
|
|
18
22
|
Available as part of the Tidelift Subscription.
|
19
23
|
|
20
|
-
The maintainers of oauth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.]
|
24
|
+
The maintainers of oauth2 and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.][tidelift-ref]
|
25
|
+
|
26
|
+
[tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise&utm_term=repo
|
data/lib/oauth2/access_token.rb
CHANGED
@@ -2,18 +2,27 @@
|
|
2
2
|
|
3
3
|
module OAuth2
|
4
4
|
class AccessToken # rubocop:disable Metrics/ClassLength
|
5
|
+
TOKEN_KEYS_STR = %w[access_token id_token token accessToken idToken].freeze
|
6
|
+
TOKEN_KEYS_SYM = %i[access_token id_token token accessToken idToken].freeze
|
7
|
+
TOKEN_KEY_LOOKUP = TOKEN_KEYS_STR + TOKEN_KEYS_SYM
|
8
|
+
|
5
9
|
attr_reader :client, :token, :expires_in, :expires_at, :expires_latency, :params
|
6
10
|
attr_accessor :options, :refresh_token, :response
|
7
11
|
|
8
12
|
class << self
|
9
13
|
# Initializes an AccessToken from a Hash
|
10
14
|
#
|
11
|
-
# @param
|
12
|
-
# @param
|
15
|
+
# @param [Client] client the OAuth2::Client instance
|
16
|
+
# @param [Hash] hash a hash of AccessToken property values
|
17
|
+
# @option hash [String, Symbol] 'access_token', 'id_token', 'token', :access_token, :id_token, or :token the access token
|
13
18
|
# @return [AccessToken] the initialized AccessToken
|
14
19
|
def from_hash(client, hash)
|
15
|
-
|
16
|
-
|
20
|
+
fresh = hash.dup
|
21
|
+
supported_keys = TOKEN_KEY_LOOKUP & fresh.keys
|
22
|
+
key = supported_keys[0]
|
23
|
+
extra_tokens_warning(supported_keys, key)
|
24
|
+
token = fresh.delete(key)
|
25
|
+
new(client, token, fresh)
|
17
26
|
end
|
18
27
|
|
19
28
|
# Initializes an AccessToken from a key/value application/x-www-form-urlencoded string
|
@@ -25,15 +34,21 @@ module OAuth2
|
|
25
34
|
from_hash(client, Rack::Utils.parse_query(kvform))
|
26
35
|
end
|
27
36
|
|
28
|
-
|
29
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
# Having too many is sus, and may lead to bugs. Having none is fine (e.g. refresh flow doesn't need a token).
|
40
|
+
def extra_tokens_warning(supported_keys, key)
|
41
|
+
return if OAuth2.config.silence_extra_tokens_warning
|
42
|
+
return if supported_keys.length <= 1
|
43
|
+
|
44
|
+
warn("OAuth2::AccessToken.from_hash: `hash` contained more than one 'token' key (#{supported_keys}); using #{key.inspect}.")
|
30
45
|
end
|
31
46
|
end
|
32
47
|
|
33
48
|
# Initialize an AccessToken
|
34
49
|
#
|
35
50
|
# @param [Client] client the OAuth2::Client instance
|
36
|
-
# @param [String] token the Access Token value
|
51
|
+
# @param [String] token the Access Token value (optional, may not be used in refresh flows)
|
37
52
|
# @param [Hash] opts the options to create the Access Token with
|
38
53
|
# @option opts [String] :refresh_token (nil) the refresh_token value
|
39
54
|
# @option opts [FixNum, String] :expires_in (nil) the number of seconds in which the AccessToken will expire
|
@@ -47,10 +62,21 @@ module OAuth2
|
|
47
62
|
def initialize(client, token, opts = {})
|
48
63
|
@client = client
|
49
64
|
@token = token.to_s
|
65
|
+
|
50
66
|
opts = opts.dup
|
51
67
|
%i[refresh_token expires_in expires_at expires_latency].each do |arg|
|
52
68
|
instance_variable_set("@#{arg}", opts.delete(arg) || opts.delete(arg.to_s))
|
53
69
|
end
|
70
|
+
no_tokens = (@token.nil? || @token.empty?) && (@refresh_token.nil? || @refresh_token.empty?)
|
71
|
+
if no_tokens
|
72
|
+
if @client.options[:raise_errors]
|
73
|
+
error = Error.new(opts)
|
74
|
+
raise(error)
|
75
|
+
else
|
76
|
+
warn('OAuth2::AccessToken has no token')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
# @option opts [Fixnum, String] :expires is deprecated
|
54
80
|
@expires_in ||= opts.delete('expires')
|
55
81
|
@expires_in &&= @expires_in.to_i
|
56
82
|
@expires_at &&= convert_expires_at(@expires_at)
|
@@ -95,7 +121,11 @@ module OAuth2
|
|
95
121
|
params[:refresh_token] = refresh_token
|
96
122
|
new_token = @client.get_token(params, access_token_opts)
|
97
123
|
new_token.options = options
|
98
|
-
|
124
|
+
if new_token.refresh_token
|
125
|
+
# Keep it, if there is one
|
126
|
+
else
|
127
|
+
new_token.refresh_token = refresh_token
|
128
|
+
end
|
99
129
|
new_token
|
100
130
|
end
|
101
131
|
# A compatibility alias
|
data/lib/oauth2/client.rb
CHANGED
@@ -9,7 +9,7 @@ module OAuth2
|
|
9
9
|
|
10
10
|
# The OAuth2::Client class
|
11
11
|
class Client # rubocop:disable Metrics/ClassLength
|
12
|
-
RESERVED_PARAM_KEYS = %w[headers parse].freeze
|
12
|
+
RESERVED_PARAM_KEYS = %w[body headers params parse snaky].freeze
|
13
13
|
|
14
14
|
attr_reader :id, :secret, :site
|
15
15
|
attr_accessor :options
|
@@ -108,7 +108,7 @@ module OAuth2
|
|
108
108
|
# @option opts [Boolean] :raise_errors whether or not to raise an OAuth2::Error on 400+ status
|
109
109
|
# code response for this request. Will default to client option
|
110
110
|
# @option opts [Symbol] :parse @see Response::initialize
|
111
|
-
# @option opts [
|
111
|
+
# @option opts [true, false] :snaky (true) @see Response::initialize
|
112
112
|
# @yield [req] @see Faraday::Connection#run_request
|
113
113
|
def request(verb, url, opts = {}, &block)
|
114
114
|
response = execute_request(verb, url, opts, &block)
|
@@ -149,7 +149,7 @@ module OAuth2
|
|
149
149
|
#
|
150
150
|
# @param params [Hash] a Hash of params for the token endpoint, except:
|
151
151
|
# @option params [Symbol] :parse @see Response#initialize
|
152
|
-
# @option params [true, false] :snaky @see Response#initialize
|
152
|
+
# @option params [true, false] :snaky (true) @see Response#initialize
|
153
153
|
# @param access_token_opts [Hash] access token options, to pass to the AccessToken object
|
154
154
|
# @param extract_access_token [Proc] proc that extracts the access token from the response (DEPRECATED)
|
155
155
|
# @yield [req] @see Faraday::Connection#run_request
|
@@ -157,44 +157,50 @@ module OAuth2
|
|
157
157
|
def get_token(params, access_token_opts = {}, extract_access_token = nil, &block)
|
158
158
|
warn('OAuth2::Client#get_token argument `extract_access_token` will be removed in oauth2 v3. Refactor to use `access_token_class` on #initialize.') if extract_access_token
|
159
159
|
extract_access_token ||= options[:extract_access_token]
|
160
|
-
|
161
|
-
if RESERVED_PARAM_KEYS.include?(key)
|
162
|
-
[key.to_sym, value]
|
163
|
-
else
|
164
|
-
[key, value]
|
165
|
-
end
|
166
|
-
end.to_h
|
160
|
+
parse, snaky, params, headers = parse_snaky_params_headers(params)
|
167
161
|
|
168
162
|
request_opts = {
|
169
163
|
raise_errors: options[:raise_errors],
|
170
|
-
parse:
|
171
|
-
snaky:
|
164
|
+
parse: parse,
|
165
|
+
snaky: snaky,
|
172
166
|
}
|
173
|
-
|
174
|
-
params = authenticator.apply(params)
|
175
|
-
headers = params.delete(:headers) || {}
|
176
167
|
if options[:token_method] == :post
|
177
|
-
|
168
|
+
|
169
|
+
# NOTE: If proliferation of request types continues we should implement a parser solution for Request,
|
170
|
+
# just like we have with Response.
|
171
|
+
request_opts[:body] = if headers['Content-Type'] == 'application/json'
|
172
|
+
params.to_json
|
173
|
+
else
|
174
|
+
params
|
175
|
+
end
|
176
|
+
|
178
177
|
request_opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
179
178
|
else
|
180
179
|
request_opts[:params] = params
|
181
180
|
request_opts[:headers] = {}
|
182
181
|
end
|
183
182
|
request_opts[:headers].merge!(headers)
|
184
|
-
http_method = options[:token_method]
|
185
|
-
http_method = :post if http_method == :post_with_query_string
|
186
183
|
response = request(http_method, token_url, request_opts, &block)
|
187
184
|
|
188
185
|
# In v1.4.x, the deprecated extract_access_token option retrieves the token from the response.
|
189
186
|
# We preserve this behavior here, but a custom access_token_class that implements #from_hash
|
190
187
|
# should be used instead.
|
191
188
|
if extract_access_token
|
192
|
-
|
189
|
+
parse_response_legacy(response, access_token_opts, extract_access_token)
|
193
190
|
else
|
194
191
|
parse_response(response, access_token_opts)
|
195
192
|
end
|
196
193
|
end
|
197
194
|
|
195
|
+
# The HTTP Method of the request
|
196
|
+
# @return [Symbol] HTTP verb, one of :get, :post, :put, :delete
|
197
|
+
def http_method
|
198
|
+
http_meth = options[:token_method].to_sym
|
199
|
+
return :post if http_meth == :post_with_query_string
|
200
|
+
|
201
|
+
http_meth
|
202
|
+
end
|
203
|
+
|
198
204
|
# The Authorization Code strategy
|
199
205
|
#
|
200
206
|
# @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
|
@@ -253,6 +259,22 @@ module OAuth2
|
|
253
259
|
|
254
260
|
private
|
255
261
|
|
262
|
+
def parse_snaky_params_headers(params)
|
263
|
+
params = params.map do |key, value|
|
264
|
+
if RESERVED_PARAM_KEYS.include?(key)
|
265
|
+
[key.to_sym, value]
|
266
|
+
else
|
267
|
+
[key, value]
|
268
|
+
end
|
269
|
+
end.to_h
|
270
|
+
parse = params.key?(:parse) ? params.delete(:parse) : Response::DEFAULT_OPTIONS[:parse]
|
271
|
+
snaky = params.key?(:snaky) ? params.delete(:snaky) : Response::DEFAULT_OPTIONS[:snaky]
|
272
|
+
params = authenticator.apply(params)
|
273
|
+
# authenticator may add :headers, and we remove them here
|
274
|
+
headers = params.delete(:headers) || {}
|
275
|
+
[parse, snaky, params, headers]
|
276
|
+
end
|
277
|
+
|
256
278
|
def execute_request(verb, url, opts = {})
|
257
279
|
url = connection.build_url(url).to_s
|
258
280
|
|
@@ -267,7 +289,10 @@ module OAuth2
|
|
267
289
|
raise TimeoutError, e
|
268
290
|
end
|
269
291
|
|
270
|
-
|
292
|
+
parse = opts.key?(:parse) ? opts.delete(:parse) : Response::DEFAULT_OPTIONS[:parse]
|
293
|
+
snaky = opts.key?(:snaky) ? opts.delete(:snaky) : Response::DEFAULT_OPTIONS[:snaky]
|
294
|
+
|
295
|
+
Response.new(response, parse: parse, snaky: snaky)
|
271
296
|
end
|
272
297
|
|
273
298
|
# Returns the authenticator object
|
@@ -277,8 +302,8 @@ module OAuth2
|
|
277
302
|
Authenticator.new(id, secret, options[:auth_scheme])
|
278
303
|
end
|
279
304
|
|
280
|
-
def
|
281
|
-
access_token =
|
305
|
+
def parse_response_legacy(response, access_token_opts, extract_access_token)
|
306
|
+
access_token = build_access_token_legacy(response, access_token_opts, extract_access_token)
|
282
307
|
|
283
308
|
return access_token if access_token
|
284
309
|
|
@@ -294,7 +319,7 @@ module OAuth2
|
|
294
319
|
access_token_class = options[:access_token_class]
|
295
320
|
data = response.parsed
|
296
321
|
|
297
|
-
unless data.is_a?(Hash) &&
|
322
|
+
unless data.is_a?(Hash) && !data.empty?
|
298
323
|
return unless options[:raise_errors]
|
299
324
|
|
300
325
|
error = Error.new(response)
|
@@ -316,7 +341,7 @@ module OAuth2
|
|
316
341
|
# Builds the access token from the response of the HTTP call with legacy extract_access_token
|
317
342
|
#
|
318
343
|
# @return [AccessToken] the initialized AccessToken
|
319
|
-
def
|
344
|
+
def build_access_token_legacy(response, access_token_opts, extract_access_token)
|
320
345
|
extract_access_token.call(self, response.parsed.merge(access_token_opts))
|
321
346
|
rescue StandardError
|
322
347
|
nil
|