oauth2 1.4.11 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +133 -75
- data/CONTRIBUTING.md +1 -27
- data/LICENSE +1 -1
- data/README.md +128 -100
- data/SECURITY.md +5 -17
- data/lib/oauth2/access_token.rb +28 -19
- data/lib/oauth2/authenticator.rb +9 -4
- data/lib/oauth2/client.rb +74 -60
- data/lib/oauth2/error.rb +27 -18
- data/lib/oauth2/response.rb +61 -19
- data/lib/oauth2/snaky_hash.rb +8 -0
- data/lib/oauth2/strategy/assertion.rb +63 -38
- data/lib/oauth2/strategy/auth_code.rb +12 -1
- data/lib/oauth2/strategy/implicit.rb +7 -0
- data/lib/oauth2/version.rb +17 -19
- data/lib/oauth2.rb +14 -1
- metadata +55 -61
- data/lib/oauth2/mac_token.rb +0 -130
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/master/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/master/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
|
|
@@ -15,41 +15,45 @@ OAuth 2.0 focuses on client developer simplicity while providing specific author
|
|
15
15
|
This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applications.
|
16
16
|
See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
|
17
17
|
|
18
|
-
⚠️⚠️⚠️ **_WARNING_**: You are viewing the `README` of the
|
19
|
-
[supported-only-for-critical-enterprise-security-issues](#oauth2-for-enterprise) `1-4-stable`
|
20
|
-
branch. Please do not use this, and instead upgrade to version 2! ⚠️⚠️⚠️
|
21
|
-
|
22
|
-
No further releases of 1.x series are planned! [Version 2](https://gitlab.com/oauth-xx/oauth2/#what-is-new-for-v20) has *tons* of improvements!
|
23
|
-
|
24
|
-
If you must continue using 1.4.x please consider purchasing an open source security maintenance contract from [Tidelift][tidelift-ref].
|
25
|
-
|
26
18
|
---
|
27
19
|
|
28
20
|
* [OAuth 2.0 Spec][oauth2-spec]
|
29
|
-
* [
|
21
|
+
* [oauth sibling gem][sibling-gem] for OAuth 1.0 implementations in Ruby.
|
30
22
|
|
31
23
|
[oauth2-spec]: https://oauth.net/2/
|
32
|
-
[sibling-gem]: https://
|
24
|
+
[sibling-gem]: https://github.com/oauth-xx/oauth-ruby
|
25
|
+
[next-milestone-pct]: https://github.com/oauth-xx/oauth2/milestone/1
|
26
|
+
[next-milestone-pct-img]: https://img.shields.io/github/milestones/progress-percent/oauth-xx/oauth2/1
|
33
27
|
|
34
28
|
## Release Documentation
|
35
29
|
|
30
|
+
### Version 2.0.x
|
31
|
+
|
32
|
+
<details>
|
33
|
+
<summary>2.0.x Readmes</summary>
|
34
|
+
|
35
|
+
| Version | Release Date | Readme |
|
36
|
+
|---------|--------------|----------------------------------------------------------|
|
37
|
+
| 2.0.0 | Soon | https://github.com/oauth-xx/oauth2/blob/master/README.md |
|
38
|
+
</details>
|
39
|
+
|
40
|
+
### Older Releases
|
41
|
+
|
36
42
|
<details>
|
37
43
|
<summary>1.4.x Readmes</summary>
|
38
44
|
|
39
|
-
| Version | Release Date | Readme
|
40
|
-
|
41
|
-
| 1.4.
|
42
|
-
| 1.4.
|
43
|
-
| 1.4.
|
44
|
-
| 1.4.
|
45
|
-
| 1.4.
|
46
|
-
| 1.4.
|
47
|
-
| 1.4.
|
48
|
-
| 1.4.
|
49
|
-
| 1.4.
|
50
|
-
| 1.4.
|
51
|
-
| 1.4.1 | Oct 13, 2018 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.1/README.md |
|
52
|
-
| 1.4.0 | Jun 9, 2017 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.0/README.md |
|
45
|
+
| Version | Release Date | Readme |
|
46
|
+
|---------|--------------|----------------------------------------------------------|
|
47
|
+
| 1.4.9 | Feb 20, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.9/README.md |
|
48
|
+
| 1.4.8 | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md |
|
49
|
+
| 1.4.7 | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
|
50
|
+
| 1.4.6 | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
|
51
|
+
| 1.4.5 | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
|
52
|
+
| 1.4.4 | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
|
53
|
+
| 1.4.3 | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
|
54
|
+
| 1.4.2 | Oct 1, 2019 | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
|
55
|
+
| 1.4.1 | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
|
56
|
+
| 1.4.0 | Jun 9, 2017 | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
|
53
57
|
</details>
|
54
58
|
|
55
59
|
<details>
|
@@ -57,8 +61,8 @@ If you must continue using 1.4.x please consider purchasing an open source secur
|
|
57
61
|
|
58
62
|
| Version | Release Date | Readme |
|
59
63
|
|----------|--------------|----------------------------------------------------------|
|
60
|
-
| 1.3.1 | Mar 3, 2017 | https://
|
61
|
-
| 1.3.0 | Dec 27, 2016 | https://
|
64
|
+
| 1.3.1 | Mar 3, 2017 | https://github.com/oauth-xx/oauth2/blob/v1.3.1/README.md |
|
65
|
+
| 1.3.0 | Dec 27, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.3.0/README.md |
|
62
66
|
</details>
|
63
67
|
|
64
68
|
<details>
|
@@ -66,10 +70,10 @@ If you must continue using 1.4.x please consider purchasing an open source secur
|
|
66
70
|
|
67
71
|
| Version | Release Date | Readme |
|
68
72
|
|----------|--------------|----------------------------------------------------------|
|
69
|
-
| 1.2.0 | Jun 30, 2016 | https://
|
70
|
-
| 1.1.0 | Jan 30, 2016 | https://
|
71
|
-
| 1.0.0 | May 23, 2014 | https://
|
72
|
-
| < 1.0.0 | Find here | https://
|
73
|
+
| 1.2.0 | Jun 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.2.0/README.md |
|
74
|
+
| 1.1.0 | Jan 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.1.0/README.md |
|
75
|
+
| 1.0.0 | May 23, 2014 | https://github.com/oauth-xx/oauth2/blob/v1.0.0/README.md |
|
76
|
+
| < 1.0.0 | Find here | https://github.com/oauth-xx/oauth2/tags |
|
73
77
|
</details>
|
74
78
|
|
75
79
|
## Status
|
@@ -101,15 +105,15 @@ appended indicators:
|
|
101
105
|
♻️ - URL needs to be updated from SASS integration. Find / Replace is insufficient.
|
102
106
|
-->
|
103
107
|
|
104
|
-
| | Project | bundle add oauth2
|
105
|
-
|
106
|
-
| 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]
|
107
|
-
| 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]
|
108
|
-
| 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]
|
109
|
-
| 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]
|
110
|
-
| 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]
|
111
|
-
| 6️⃣ | resources | [![Discussion][⛳
|
112
|
-
| 7️⃣ | spread 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]
|
108
|
+
| | Project | bundle add oauth2 |
|
109
|
+
|:----|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
110
|
+
| 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] |
|
111
|
+
| 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] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img]][📗next] |
|
112
|
+
| 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] |
|
113
|
+
| 4️⃣ | testing | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![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] |
|
114
|
+
| 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] |
|
115
|
+
| 6️⃣ | resources | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki] |
|
116
|
+
| 7️⃣ | spread 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme] |
|
113
117
|
|
114
118
|
<!--
|
115
119
|
The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
|
@@ -130,17 +134,23 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
130
134
|
[⛳️version-img]: http://img.shields.io/gem/v/oauth2.svg
|
131
135
|
[🖇DL-total-img]: https://img.shields.io/gem/dt/oauth2.svg
|
132
136
|
[🏘DL-rank-img]: https://img.shields.io/gem/rt/oauth2.svg
|
133
|
-
[🚎src-home]: https://
|
134
|
-
[🚎src-home-img]: https://img.shields.io/badge/source-
|
135
|
-
|
136
|
-
|
137
|
+
[🚎src-home]: https://github.com/oauth-xx/oauth2
|
138
|
+
[🚎src-home-img]: https://img.shields.io/badge/source-github-brightgreen.svg?style=flat
|
139
|
+
[🖐prs-o]: https://github.com/oauth-xx/oauth2/pulls
|
140
|
+
[🖐prs-o-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
|
141
|
+
[🧮prs-c]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
|
142
|
+
[🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
|
143
|
+
[📗next]: https://github.com/oauth-xx/oauth2/milestone/1
|
144
|
+
[📗next-img]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/1?label=Next%20Version
|
145
|
+
|
146
|
+
<!-- 3️⃣ maintanence & linting -->
|
137
147
|
[⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
|
138
148
|
[⛳cclim-maint-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
|
139
149
|
[🖇triage-help]: https://www.codetriage.com/oauth-xx/oauth2
|
140
150
|
[🖇triage-help-img]: https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg
|
141
151
|
[🏘depfu♻️]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
|
142
152
|
[🏘depfu-img♻️]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
|
143
|
-
[🚎contributors]: https://
|
153
|
+
[🚎contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
|
144
154
|
[🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
|
145
155
|
[🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
|
146
156
|
[🖐style-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml/badge.svg
|
@@ -148,6 +158,10 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
148
158
|
[🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/oauth-xx/oauth2
|
149
159
|
|
150
160
|
<!-- 4️⃣ testing -->
|
161
|
+
[⛳iss-o]: https://github.com/oauth-xx/oauth2/issues
|
162
|
+
[⛳iss-o-img]: https://img.shields.io/github/issues-raw/oauth-xx/oauth2
|
163
|
+
[🖇iss-c]: https://github.com/oauth-xx/oauth2/issues?q=is%3Aissue+is%3Aclosed
|
164
|
+
[🖇iss-c-img]: https://img.shields.io/github/issues-closed-raw/oauth-xx/oauth2
|
151
165
|
[🏘sup-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
|
152
166
|
[🏘sup-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
|
153
167
|
[🚎heads-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/heads.yml
|
@@ -162,11 +176,11 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
162
176
|
<!-- 5️⃣ coverage & security -->
|
163
177
|
[⛳cclim-cov]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
|
164
178
|
[⛳cclim-cov-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage
|
165
|
-
[🖇codecov-img♻️]: https://codecov.io/gh/oauth-xx/oauth2/branch/
|
179
|
+
[🖇codecov-img♻️]: https://codecov.io/gh/oauth-xx/oauth2/branch/master/graph/badge.svg?token=bNqSzNiuo2
|
166
180
|
[🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
|
167
|
-
[🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=
|
168
|
-
[🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=
|
169
|
-
[🚎sec-pol]: https://
|
181
|
+
[🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=master
|
182
|
+
[🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=master
|
183
|
+
[🚎sec-pol]: https://github.com/oauth-xx/oauth2/blob/master/SECURITY.md
|
170
184
|
[🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
|
171
185
|
[🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
|
172
186
|
[🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
|
@@ -174,15 +188,15 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
174
188
|
[🧮cov-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
|
175
189
|
|
176
190
|
<!-- 6️⃣ resources -->
|
177
|
-
[⛳
|
178
|
-
[⛳
|
191
|
+
[⛳gh-discussions]: https://github.com/oauth-xx/oauth2/discussions
|
192
|
+
[⛳gh-discussions-img]: https://img.shields.io/github/discussions/oauth-xx/oauth2
|
179
193
|
[🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
|
180
194
|
[🖇codementor-img]: https://cdn.codementor.io/badges/get_help_github.svg
|
181
195
|
[🏘chat]: https://gitter.im/oauth-xx/oauth2
|
182
196
|
[🏘chat-img]: https://img.shields.io/gitter/room/oauth-xx/oauth2.svg
|
183
197
|
[🚎blog]: http://www.railsbling.com/tags/oauth2/
|
184
198
|
[🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
|
185
|
-
[🖐wiki]: https://
|
199
|
+
[🖐wiki]: https://github.com/oauth-xx/oauth2/wiki
|
186
200
|
[🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
|
187
201
|
|
188
202
|
<!-- 7️⃣ spread 💖 -->
|
@@ -199,6 +213,7 @@ The link tokens in the following sections should be kept ordered by the row and
|
|
199
213
|
[aboutme]: https://about.me/peter.boling
|
200
214
|
[angelme]: https://angel.co/peter-boling
|
201
215
|
[coderme]:http://coderwall.com/pboling
|
216
|
+
[politicme]: https://nationalprogressiveparty.org
|
202
217
|
|
203
218
|
## Installation
|
204
219
|
|
@@ -214,9 +229,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
214
229
|
|
215
230
|
Available as part of the Tidelift Subscription.
|
216
231
|
|
217
|
-
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.]
|
218
|
-
|
219
|
-
[tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise
|
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.](https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise)
|
220
233
|
|
221
234
|
## Security contact information
|
222
235
|
|
@@ -225,7 +238,7 @@ Tidelift will coordinate the fix and disclosure.
|
|
225
238
|
|
226
239
|
For more see [SECURITY.md][🚎sec-pol].
|
227
240
|
|
228
|
-
##
|
241
|
+
## What is new for v2.0 (unreleased, `master` branch)?
|
229
242
|
|
230
243
|
- Officially support Ruby versions >= 2.7
|
231
244
|
- Unofficially support Ruby versions >= 2.5
|
@@ -240,20 +253,13 @@ For more see [SECURITY.md][🚎sec-pol].
|
|
240
253
|
- `:access_token_class` (`AccessToken`); user specified class to use for all calls to `get_token`
|
241
254
|
- Adds new option to `OAuth2::AccessToken#initialize`:
|
242
255
|
- `:expires_latency` (`nil`); number of seconds by which AccessToken validity will be reduced to offset latency
|
243
|
-
-
|
244
|
-
- Original keys will still work as previously, in most scenarios, thanks to `rash_alt` gem.
|
245
|
-
- However, this is a _breaking_ change if you rely on `response.parsed.to_h`, as the keys in the result will be camel case.
|
246
|
-
- As of version 2.0.4 you can turn key transformation off with the `snaky: false` option.
|
247
|
-
- By default, the `:auth_scheme` is now `:basic_auth` (instead of `:request_body`)
|
248
|
-
- Third-party strategies and gems may need to be updated if a provider was requiring client id/secret in the request body
|
249
|
-
- [... A lot more](https://gitlab.com/oauth-xx/oauth2/-/blob/main/CHANGELOG.md#2.0.0)
|
256
|
+
- [... A lot more](https://github.com/oauth-xx/oauth2/blob/master/CHANGELOG.md#unreleased)
|
250
257
|
|
251
258
|
## Compatibility
|
252
259
|
|
253
|
-
Targeted ruby compatibility is 2.7, 3.0 and
|
254
|
-
supported and unsupported versions of Ruby.
|
255
|
-
|
256
|
-
Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and is be 2.2+ for next major version releases (see `master` branch).
|
260
|
+
Targeted ruby compatibility is non-EOL versions of Ruby, currently 2.7, 3.0 and
|
261
|
+
3.1. Compatibility is further distinguished by supported and unsupported versions of Ruby.
|
262
|
+
Ruby is limited to 2.2+ for 2.x releases. See `1-4-stable` branch for older rubies.
|
257
263
|
|
258
264
|
<details>
|
259
265
|
<summary>Ruby Engine Compatibility Policy</summary>
|
@@ -262,7 +268,8 @@ This gem is tested against MRI, JRuby, and Truffleruby.
|
|
262
268
|
Each of those has varying versions that target a specific version of MRI Ruby.
|
263
269
|
This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
|
264
270
|
If you would like to add support for additional engines,
|
265
|
-
|
271
|
+
first make sure Github Actions supports the engine,
|
272
|
+
then submit a PR to the correct maintenance branch as according to the table below.
|
266
273
|
</details>
|
267
274
|
|
268
275
|
<details>
|
@@ -282,30 +289,59 @@ fashion. If critical issues for a particular implementation exist at the time
|
|
282
289
|
of a major release, support for that Ruby version may be dropped.
|
283
290
|
</details>
|
284
291
|
|
285
|
-
| | Ruby
|
286
|
-
|
287
|
-
| 1️⃣ | 2.0.x
|
288
|
-
| 2️⃣ | 1.4.x
|
289
|
-
| 3️⃣ | older
|
292
|
+
| | Ruby OAuth 2 Version | Maintenance Branch | Supported Officially | Supported Unofficially | Supported Incidentally |
|
293
|
+
|:----|----------------------|--------------------|-------------------------|------------------------|------------------------|
|
294
|
+
| 1️⃣ | 2.0.x (unreleased) | `master` | 2.7, 3.0, 3.1 | 2.5, 2.6 | 2.2, 2.3, 2.4 |
|
295
|
+
| 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 |
|
296
|
+
| 3️⃣ | older | N/A | Best of luck to you! | Please upgrade! | |
|
290
297
|
|
291
|
-
NOTE: The 1.4 series will only receive critical security updates.
|
298
|
+
NOTE: The 1.4 series will only receive critical bug and security updates.
|
292
299
|
See [SECURITY.md][🚎sec-pol]
|
293
300
|
|
294
301
|
## Usage Examples
|
295
302
|
|
303
|
+
### `authorize_url` and `token_url` are on site root (Just Works!)
|
304
|
+
|
296
305
|
```ruby
|
297
306
|
require 'oauth2'
|
298
|
-
client = OAuth2::Client.new('client_id', 'client_secret', :
|
299
|
-
|
300
|
-
client.auth_code.authorize_url(:
|
301
|
-
# => "https://example.org/oauth/
|
307
|
+
client = OAuth2::Client.new('client_id', 'client_secret', site: 'https://example.org')
|
308
|
+
# => #<OAuth2::Client:0x00000001204c8288 @id="client_id", @secret="client_sec...
|
309
|
+
client.auth_code.authorize_url(redirect_uri: 'http://localhost:8080/oauth2/callback')
|
310
|
+
# => "https://example.org/oauth/authorize?client_id=client_id&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcallback&response_type=code"
|
302
311
|
|
303
|
-
token = client.auth_code.get_token('authorization_code_value', :
|
304
|
-
response = token.get('/api/resource', :
|
312
|
+
token = client.auth_code.get_token('authorization_code_value', redirect_uri: 'http://localhost:8080/oauth2/callback', headers: {'Authorization' => 'Basic some_password'})
|
313
|
+
response = token.get('/api/resource', params: {'query_foo' => 'bar'})
|
305
314
|
response.class.name
|
306
315
|
# => OAuth2::Response
|
307
316
|
```
|
308
317
|
|
318
|
+
### Relative `authorize_url` and `token_url` (Not on site root, Just Works!)
|
319
|
+
|
320
|
+
In above example, the default Authorization URL is `oauth/authorize` and default Access Token URL is `oauth/token`, and, as they are missing a leading `/`, both are relative.
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
client = OAuth2::Client.new('client_id', 'client_secret', site: 'https://example.org/nested/directory/on/your/server')
|
324
|
+
# => #<OAuth2::Client:0x00000001204c8288 @id="client_id", @secret="client_sec...
|
325
|
+
client.auth_code.authorize_url(redirect_uri: 'http://localhost:8080/oauth2/callback')
|
326
|
+
# => "https://example.org/nested/directory/on/your/server/oauth/authorize?client_id=client_id&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcallback&response_type=code"
|
327
|
+
```
|
328
|
+
|
329
|
+
### Customize `authorize_url` and `token_url`
|
330
|
+
|
331
|
+
You can specify custom URLs for authorization and access token, and when using a leading `/` they will _not be relative_, as shown below:
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
client = OAuth2::Client.new('client_id', 'client_secret',
|
335
|
+
site: 'https://example.org/nested/directory/on/your/server',
|
336
|
+
authorize_url: '/jaunty/authorize/',
|
337
|
+
token_url: '/stirrups/access_token')
|
338
|
+
# => #<OAuth2::Client:0x00000001204c8288 @id="client_id", @secret="client_sec...
|
339
|
+
client.auth_code.authorize_url(redirect_uri: 'http://localhost:8080/oauth2/callback')
|
340
|
+
# => "https://example.org/jaunty/authorize/?client_id=client_id&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcallback&response_type=code"
|
341
|
+
client.class.name
|
342
|
+
# => OAuth2::Client
|
343
|
+
```
|
344
|
+
|
309
345
|
<details>
|
310
346
|
<summary>Debugging</summary>
|
311
347
|
|
@@ -324,8 +360,8 @@ require 'oauth2'
|
|
324
360
|
client = OAuth2::Client.new(
|
325
361
|
'client_id',
|
326
362
|
'client_secret',
|
327
|
-
:
|
328
|
-
:
|
363
|
+
site: 'https://example.org',
|
364
|
+
logger: Logger.new('example.log', 'weekly')
|
329
365
|
)
|
330
366
|
```
|
331
367
|
</details>
|
@@ -369,10 +405,10 @@ authentication grant types have helper strategy classes that simplify client
|
|
369
405
|
use. They are available via the `#auth_code`, `#implicit`, `#password`, `#client_credentials`, and `#assertion` methods respectively.
|
370
406
|
|
371
407
|
```ruby
|
372
|
-
auth_url = client.auth_code.authorize_url(:
|
373
|
-
token = client.auth_code.get_token('code_value', :
|
408
|
+
auth_url = client.auth_code.authorize_url(redirect_uri: 'http://localhost:8080/oauth/callback')
|
409
|
+
token = client.auth_code.get_token('code_value', redirect_uri: 'http://localhost:8080/oauth/callback')
|
374
410
|
|
375
|
-
auth_url = client.implicit.authorize_url(:
|
411
|
+
auth_url = client.implicit.authorize_url(redirect_uri: 'http://localhost:8080/oauth/callback')
|
376
412
|
# get the token params in the callback and
|
377
413
|
token = OAuth2::AccessToken.from_kvform(client, query_string)
|
378
414
|
|
@@ -387,7 +423,7 @@ If you want to specify additional headers to be sent out with the
|
|
387
423
|
request, add a 'headers' hash under 'params':
|
388
424
|
|
389
425
|
```ruby
|
390
|
-
token = client.auth_code.get_token('code_value', :
|
426
|
+
token = client.auth_code.get_token('code_value', redirect_uri: 'http://localhost:8080/oauth/callback', headers: {'Some' => 'Header'})
|
391
427
|
```
|
392
428
|
|
393
429
|
You can always use the `#request` method on the `OAuth2::Client` instance to make
|
@@ -408,7 +444,7 @@ dependency on this gem using the [Pessimistic Version Constraint][pvc] with two
|
|
408
444
|
For example:
|
409
445
|
|
410
446
|
```ruby
|
411
|
-
spec.add_dependency 'oauth2', '~>
|
447
|
+
spec.add_dependency 'oauth2', '~> 2.0'
|
412
448
|
```
|
413
449
|
|
414
450
|
[semver]: http://semver.org/
|
@@ -424,8 +460,8 @@ spec.add_dependency 'oauth2', '~> 1.4'
|
|
424
460
|
|
425
461
|
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]
|
426
462
|
|
427
|
-
[license]: https://
|
428
|
-
[oauth-xx]: https://
|
463
|
+
[license]: https://github.com/oauth-xx/oauth2/blob/master/LICENSE
|
464
|
+
[oauth-xx]: https://github.com/oauth-xx
|
429
465
|
[fossa2]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_large
|
430
466
|
|
431
467
|
## Development
|
@@ -436,16 +472,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
436
472
|
|
437
473
|
## Contributing
|
438
474
|
|
439
|
-
|
440
|
-
|
441
|
-
[contributing]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/CONTRIBUTING.md
|
442
|
-
|
443
|
-
## Contributors
|
444
|
-
|
445
|
-
[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://gitlab.com/oauth-xx/oauth2/-/graphs/main")
|
446
|
-
|
447
|
-
Made with [contributors-img](https://contrib.rocks).
|
475
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/oauth-xx/oauth2. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
448
476
|
|
449
477
|
## Code of Conduct
|
450
478
|
|
451
|
-
Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://
|
479
|
+
Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/oauth-xx/oauth2/blob/master/CODE_OF_CONDUCT.md).
|
data/SECURITY.md
CHANGED
@@ -2,25 +2,13 @@
|
|
2
2
|
|
3
3
|
## Supported Versions
|
4
4
|
|
5
|
-
| Version
|
6
|
-
|
7
|
-
| 2.latest | ✅ |
|
8
|
-
| 1.latest | ✅ |
|
9
|
-
|
|
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.
|
5
|
+
| Version | Supported |
|
6
|
+
|--------------|-----------|
|
7
|
+
| 2.0.<latest> | ✅ |
|
8
|
+
| 1.4.<latest> | ✅ |
|
9
|
+
| older | ⛔️ |
|
14
10
|
|
15
11
|
## Reporting a Vulnerability
|
16
12
|
|
17
13
|
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
|
18
14
|
Tidelift will coordinate the fix and disclosure.
|
19
|
-
|
20
|
-
## OAuth2 for Enterprise
|
21
|
-
|
22
|
-
Available as part of the Tidelift Subscription.
|
23
|
-
|
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
@@ -1,33 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OAuth2
|
4
|
-
class AccessToken
|
5
|
-
attr_reader :client, :token, :expires_in, :expires_at, :params
|
6
|
-
attr_accessor :options, :refresh_token
|
4
|
+
class AccessToken # rubocop:disable Metrics/ClassLength
|
5
|
+
attr_reader :client, :token, :expires_in, :expires_at, :expires_latency, :params
|
6
|
+
attr_accessor :options, :refresh_token, :response
|
7
7
|
|
8
|
-
# Should these methods be deprecated?
|
9
8
|
class << self
|
10
9
|
# Initializes an AccessToken from a Hash
|
11
10
|
#
|
12
|
-
# @param [Client] the OAuth2::Client instance
|
13
|
-
# @param [Hash] a hash of AccessToken property values
|
14
|
-
# @return [AccessToken] the
|
11
|
+
# @param client [Client] the OAuth2::Client instance
|
12
|
+
# @param hash [Hash] a hash of AccessToken property values
|
13
|
+
# @return [AccessToken] the initialized AccessToken
|
15
14
|
def from_hash(client, hash)
|
16
15
|
hash = hash.dup
|
17
|
-
new(client, hash.delete('access_token') || hash.delete(:access_token), hash)
|
16
|
+
new(client, hash.delete('access_token') || hash.delete(:access_token) || hash.delete('token') || hash.delete(:token), hash)
|
18
17
|
end
|
19
18
|
|
20
19
|
# Initializes an AccessToken from a key/value application/x-www-form-urlencoded string
|
21
20
|
#
|
22
21
|
# @param [Client] client the OAuth2::Client instance
|
23
22
|
# @param [String] kvform the application/x-www-form-urlencoded string
|
24
|
-
# @return [AccessToken] the
|
23
|
+
# @return [AccessToken] the initialized AccessToken
|
25
24
|
def from_kvform(client, kvform)
|
26
25
|
from_hash(client, Rack::Utils.parse_query(kvform))
|
27
26
|
end
|
27
|
+
|
28
|
+
def contains_token?(hash)
|
29
|
+
hash.key?('access_token') || hash.key?('id_token') || hash.key?('token')
|
30
|
+
end
|
28
31
|
end
|
29
32
|
|
30
|
-
#
|
33
|
+
# Initialize an AccessToken
|
31
34
|
#
|
32
35
|
# @param [Client] client the OAuth2::Client instance
|
33
36
|
# @param [String] token the Access Token value
|
@@ -35,6 +38,7 @@ module OAuth2
|
|
35
38
|
# @option opts [String] :refresh_token (nil) the refresh_token value
|
36
39
|
# @option opts [FixNum, String] :expires_in (nil) the number of seconds in which the AccessToken will expire
|
37
40
|
# @option opts [FixNum, String] :expires_at (nil) the epoch time in seconds in which AccessToken will expire
|
41
|
+
# @option opts [FixNum, String] :expires_latency (nil) the number of seconds by which AccessToken validity will be reduced to offset latency, @version 2.0+
|
38
42
|
# @option opts [Symbol] :mode (:header) the transmission mode of the Access Token parameter value
|
39
43
|
# one of :header, :body or :query
|
40
44
|
# @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
|
@@ -44,16 +48,18 @@ module OAuth2
|
|
44
48
|
@client = client
|
45
49
|
@token = token.to_s
|
46
50
|
opts = opts.dup
|
47
|
-
[
|
51
|
+
%i[refresh_token expires_in expires_at expires_latency].each do |arg|
|
48
52
|
instance_variable_set("@#{arg}", opts.delete(arg) || opts.delete(arg.to_s))
|
49
53
|
end
|
50
54
|
@expires_in ||= opts.delete('expires')
|
51
55
|
@expires_in &&= @expires_in.to_i
|
52
56
|
@expires_at &&= convert_expires_at(@expires_at)
|
57
|
+
@expires_latency &&= @expires_latency.to_i
|
53
58
|
@expires_at ||= Time.now.to_i + @expires_in if @expires_in
|
54
|
-
@
|
55
|
-
|
56
|
-
:
|
59
|
+
@expires_at -= @expires_latency if @expires_latency
|
60
|
+
@options = {mode: opts.delete(:mode) || :header,
|
61
|
+
header_format: opts.delete(:header_format) || 'Bearer %s',
|
62
|
+
param_name: opts.delete(:param_name) || 'access_token'}
|
57
63
|
@params = opts
|
58
64
|
end
|
59
65
|
|
@@ -75,29 +81,32 @@ module OAuth2
|
|
75
81
|
#
|
76
82
|
# @return [Boolean]
|
77
83
|
def expired?
|
78
|
-
expires? && (expires_at
|
84
|
+
expires? && (expires_at <= Time.now.to_i)
|
79
85
|
end
|
80
86
|
|
81
87
|
# Refreshes the current Access Token
|
82
88
|
#
|
83
89
|
# @return [AccessToken] a new AccessToken
|
84
90
|
# @note options should be carried over to the new AccessToken
|
85
|
-
def refresh
|
91
|
+
def refresh(params = {}, access_token_opts = {}, access_token_class = self.class)
|
86
92
|
raise('A refresh_token is not available') unless refresh_token
|
87
93
|
|
88
94
|
params[:grant_type] = 'refresh_token'
|
89
95
|
params[:refresh_token] = refresh_token
|
90
|
-
new_token = @client.get_token(params)
|
96
|
+
new_token = @client.get_token(params, access_token_opts, access_token_class: access_token_class)
|
91
97
|
new_token.options = options
|
92
98
|
new_token.refresh_token = refresh_token unless new_token.refresh_token
|
93
99
|
new_token
|
94
100
|
end
|
101
|
+
# A compatibility alias
|
102
|
+
# @note does not modify the receiver, so bang is not the default method
|
103
|
+
alias refresh! refresh
|
95
104
|
|
96
105
|
# Convert AccessToken to a hash which can be used to rebuild itself with AccessToken.from_hash
|
97
106
|
#
|
98
107
|
# @return [Hash] a hash of AccessToken property values
|
99
108
|
def to_hash
|
100
|
-
params.merge(:
|
109
|
+
params.merge(access_token: token, refresh_token: refresh_token, expires_at: expires_at)
|
101
110
|
end
|
102
111
|
|
103
112
|
# Make a request with the Access Token
|
@@ -166,7 +175,7 @@ module OAuth2
|
|
166
175
|
if opts[:body].is_a?(Hash)
|
167
176
|
opts[:body][options[:param_name]] = token
|
168
177
|
else
|
169
|
-
opts[:body]
|
178
|
+
opts[:body] += "&#{options[:param_name]}=#{token}"
|
170
179
|
end
|
171
180
|
# @todo support for multi-part (file uploads)
|
172
181
|
else
|
data/lib/oauth2/authenticator.rb
CHANGED
@@ -37,7 +37,7 @@ module OAuth2
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.encode_basic_auth(user, password)
|
40
|
-
|
40
|
+
"Basic #{Base64.strict_encode64("#{user}:#{password}")}"
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
@@ -45,13 +45,18 @@ module OAuth2
|
|
45
45
|
# Adds client_id and client_secret request parameters if they are not
|
46
46
|
# already set.
|
47
47
|
def apply_params_auth(params)
|
48
|
-
|
48
|
+
result = {}
|
49
|
+
result['client_id'] = id unless id.nil?
|
50
|
+
result['client_secret'] = secret unless secret.nil?
|
51
|
+
result.merge(params)
|
49
52
|
end
|
50
53
|
|
51
54
|
# When using schemes that don't require the client_secret to be passed i.e TLS Client Auth,
|
52
55
|
# we don't want to send the secret
|
53
56
|
def apply_client_id(params)
|
54
|
-
|
57
|
+
result = {}
|
58
|
+
result['client_id'] = id unless id.nil?
|
59
|
+
result.merge(params)
|
55
60
|
end
|
56
61
|
|
57
62
|
# Adds an `Authorization` header with Basic Auth credentials if and only if
|
@@ -59,7 +64,7 @@ module OAuth2
|
|
59
64
|
def apply_basic_auth(params)
|
60
65
|
headers = params.fetch(:headers, {})
|
61
66
|
headers = basic_auth_header.merge(headers)
|
62
|
-
params.merge(:
|
67
|
+
params.merge(headers: headers)
|
63
68
|
end
|
64
69
|
|
65
70
|
# @see https://datatracker.ietf.org/doc/html/rfc2617#section-2
|