oauth2 2.0.13 → 2.0.15
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 +190 -256
- data/CONTRIBUTING.md +36 -4
- data/FUNDING.md +2 -2
- data/OIDC.md +158 -0
- data/README.md +457 -100
- data/SECURITY.md +3 -17
- data/lib/oauth2/access_token.rb +10 -6
- data/lib/oauth2/client.rb +4 -0
- data/lib/oauth2/strategy/auth_code.rb +10 -0
- data/lib/oauth2/strategy/implicit.rb +8 -0
- data/lib/oauth2/strategy/password.rb +8 -0
- data/lib/oauth2/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +171 -18
- metadata.gz.sig +0 -0
data/SECURITY.md
CHANGED
@@ -2,15 +2,9 @@
|
|
2
2
|
|
3
3
|
## Supported Versions
|
4
4
|
|
5
|
-
| Version | Supported |
|
6
|
-
|
7
|
-
|
|
8
|
-
| 1.latest | ✅ | [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.
|
5
|
+
| Version | Supported |
|
6
|
+
|----------|-----------|
|
7
|
+
| 1.latest | ✅ |
|
14
8
|
|
15
9
|
## Security contact information
|
16
10
|
|
@@ -25,11 +19,3 @@ please consider sponsoring the project / maintainer @ https://liberapay.com/pbol
|
|
25
19
|
or find other sponsorship links in the [README].
|
26
20
|
|
27
21
|
[README]: README.md
|
28
|
-
|
29
|
-
## Enterprise Support
|
30
|
-
|
31
|
-
Available as part of the Tidelift Subscription.
|
32
|
-
|
33
|
-
The maintainers of this library 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]
|
34
|
-
|
35
|
-
[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
@@ -132,8 +132,9 @@ You may need to set `snaky: false`. See inline documentation for more info.
|
|
132
132
|
# @option opts [FixNum, String] :expires_in (nil) the number of seconds in which the AccessToken will expire
|
133
133
|
# @option opts [FixNum, String] :expires_at (nil) the epoch time in seconds in which AccessToken will expire
|
134
134
|
# @option opts [FixNum, String] :expires_latency (nil) the number of seconds by which AccessToken validity will be reduced to offset latency, @version 2.0+
|
135
|
-
# @option opts [Symbol] :mode (:header) the transmission mode of the Access Token parameter value
|
136
|
-
# one of :header, :body or :query
|
135
|
+
# @option opts [Symbol or callable] :mode (:header) the transmission mode of the Access Token parameter value:
|
136
|
+
# either one of :header, :body or :query, or a callable that accepts a request-verb parameter
|
137
|
+
# and returns one of these three symbols.
|
137
138
|
# @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
|
138
139
|
# @option opts [String] :param_name ('access_token') the parameter name to use for transmission of the
|
139
140
|
# Access Token value in :body or :query transmission mode
|
@@ -324,7 +325,7 @@ You may need to set `snaky: false`. See inline documentation for more info.
|
|
324
325
|
#
|
325
326
|
# @see OAuth2::Client#request
|
326
327
|
def request(verb, path, opts = {}, &block)
|
327
|
-
configure_authentication!(opts)
|
328
|
+
configure_authentication!(opts, verb)
|
328
329
|
@client.request(verb, path, opts, &block)
|
329
330
|
end
|
330
331
|
|
@@ -370,12 +371,15 @@ You may need to set `snaky: false`. See inline documentation for more info.
|
|
370
371
|
|
371
372
|
private
|
372
373
|
|
373
|
-
def configure_authentication!(opts)
|
374
|
-
|
374
|
+
def configure_authentication!(opts, verb)
|
375
|
+
mode = options[:mode].respond_to?(:call) ? options[:mode].call(verb) : options[:mode]
|
376
|
+
case mode
|
375
377
|
when :header
|
376
378
|
opts[:headers] ||= {}
|
377
379
|
opts[:headers].merge!(headers)
|
378
380
|
when :query
|
381
|
+
# OAuth 2.1 note: Bearer tokens in the query string are omitted from the spec due to security risks.
|
382
|
+
# Prefer the default :header mode whenever possible.
|
379
383
|
opts[:params] ||= {}
|
380
384
|
opts[:params][options[:param_name]] = token
|
381
385
|
when :body
|
@@ -387,7 +391,7 @@ You may need to set `snaky: false`. See inline documentation for more info.
|
|
387
391
|
end
|
388
392
|
# @todo support for multi-part (file uploads)
|
389
393
|
else
|
390
|
-
raise("invalid :mode option of #{
|
394
|
+
raise("invalid :mode option of #{mode}")
|
391
395
|
end
|
392
396
|
end
|
393
397
|
|
data/lib/oauth2/client.rb
CHANGED
@@ -321,6 +321,9 @@ module OAuth2
|
|
321
321
|
# requesting authorization. If it is provided at authorization time it MUST
|
322
322
|
# also be provided with the token exchange request.
|
323
323
|
#
|
324
|
+
# OAuth 2.1 note: Authorization Servers must compare redirect URIs using exact string matching.
|
325
|
+
# This client simply forwards the configured redirect_uri; the exact-match validation happens server-side.
|
326
|
+
#
|
324
327
|
# Providing :redirect_uri to the OAuth2::Client instantiation will take
|
325
328
|
# care of managing this.
|
326
329
|
#
|
@@ -330,6 +333,7 @@ module OAuth2
|
|
330
333
|
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
|
331
334
|
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1
|
332
335
|
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-10.6
|
336
|
+
# @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
|
333
337
|
#
|
334
338
|
# @return [Hash] the params to add to a request or URL
|
335
339
|
def redirection_params
|
@@ -4,6 +4,16 @@ module OAuth2
|
|
4
4
|
module Strategy
|
5
5
|
# The Authorization Code Strategy
|
6
6
|
#
|
7
|
+
# OAuth 2.1 notes:
|
8
|
+
# - PKCE is required for all OAuth clients using the authorization code flow (especially public clients).
|
9
|
+
# This library does not enforce PKCE generation/verification; implement PKCE in your application when required.
|
10
|
+
# - Redirect URIs must be compared using exact string matching by the Authorization Server.
|
11
|
+
# This client forwards redirect_uri but does not perform server-side validation.
|
12
|
+
#
|
13
|
+
# References:
|
14
|
+
# - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
|
15
|
+
# - OAuth for native apps (RFC 8252) and PKCE (RFC 7636)
|
16
|
+
#
|
7
17
|
# @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
|
8
18
|
class AuthCode < Base
|
9
19
|
# The required query parameters for the authorize URL
|
@@ -4,6 +4,14 @@ module OAuth2
|
|
4
4
|
module Strategy
|
5
5
|
# The Implicit Strategy
|
6
6
|
#
|
7
|
+
# IMPORTANT (OAuth 2.1): The Implicit grant (response_type=token) is omitted from the OAuth 2.1 draft specification.
|
8
|
+
# It remains here for backward compatibility with OAuth 2.0 providers. Prefer the Authorization Code flow with PKCE.
|
9
|
+
#
|
10
|
+
# References:
|
11
|
+
# - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
|
12
|
+
# - Why drop implicit: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
|
13
|
+
# - Background: https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1/
|
14
|
+
#
|
7
15
|
# @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.2
|
8
16
|
class Implicit < Base
|
9
17
|
# The required query parameters for the authorize URL
|
@@ -4,6 +4,14 @@ module OAuth2
|
|
4
4
|
module Strategy
|
5
5
|
# The Resource Owner Password Credentials Authorization Strategy
|
6
6
|
#
|
7
|
+
# IMPORTANT (OAuth 2.1): The Resource Owner Password Credentials grant is omitted in OAuth 2.1.
|
8
|
+
# It remains here for backward compatibility with OAuth 2.0 providers. Prefer Authorization Code + PKCE.
|
9
|
+
#
|
10
|
+
# References:
|
11
|
+
# - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
|
12
|
+
# - Okta explainer: https://developer.okta.com/blog/2019/12/13/oauth-2-1-how-many-rfcs
|
13
|
+
# - FusionAuth blog: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
|
14
|
+
#
|
7
15
|
# @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
|
8
16
|
class Password < Base
|
9
17
|
# Not used for this strategy
|
data/lib/oauth2/version.rb
CHANGED
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.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
@@ -207,8 +207,90 @@ dependencies:
|
|
207
207
|
- - ">="
|
208
208
|
- !ruby/object:Gem::Version
|
209
209
|
version: 3.25.1
|
210
|
+
- !ruby/object:Gem::Dependency
|
211
|
+
name: nkf
|
212
|
+
requirement: !ruby/object:Gem::Requirement
|
213
|
+
requirements:
|
214
|
+
- - "~>"
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0.2'
|
217
|
+
type: :development
|
218
|
+
prerelease: false
|
219
|
+
version_requirements: !ruby/object:Gem::Requirement
|
220
|
+
requirements:
|
221
|
+
- - "~>"
|
222
|
+
- !ruby/object:Gem::Version
|
223
|
+
version: '0.2'
|
224
|
+
- !ruby/object:Gem::Dependency
|
225
|
+
name: rexml
|
226
|
+
requirement: !ruby/object:Gem::Requirement
|
227
|
+
requirements:
|
228
|
+
- - "~>"
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: '3.2'
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: 3.2.5
|
234
|
+
type: :development
|
235
|
+
prerelease: false
|
236
|
+
version_requirements: !ruby/object:Gem::Requirement
|
237
|
+
requirements:
|
238
|
+
- - "~>"
|
239
|
+
- !ruby/object:Gem::Version
|
240
|
+
version: '3.2'
|
241
|
+
- - ">="
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: 3.2.5
|
210
244
|
- !ruby/object:Gem::Dependency
|
211
245
|
name: kettle-dev
|
246
|
+
requirement: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - "~>"
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '1.1'
|
251
|
+
- - ">="
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: 1.1.9
|
254
|
+
type: :development
|
255
|
+
prerelease: false
|
256
|
+
version_requirements: !ruby/object:Gem::Requirement
|
257
|
+
requirements:
|
258
|
+
- - "~>"
|
259
|
+
- !ruby/object:Gem::Version
|
260
|
+
version: '1.1'
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: 1.1.9
|
264
|
+
- !ruby/object:Gem::Dependency
|
265
|
+
name: bundler-audit
|
266
|
+
requirement: !ruby/object:Gem::Requirement
|
267
|
+
requirements:
|
268
|
+
- - "~>"
|
269
|
+
- !ruby/object:Gem::Version
|
270
|
+
version: 0.9.2
|
271
|
+
type: :development
|
272
|
+
prerelease: false
|
273
|
+
version_requirements: !ruby/object:Gem::Requirement
|
274
|
+
requirements:
|
275
|
+
- - "~>"
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: 0.9.2
|
278
|
+
- !ruby/object:Gem::Dependency
|
279
|
+
name: rake
|
280
|
+
requirement: !ruby/object:Gem::Requirement
|
281
|
+
requirements:
|
282
|
+
- - "~>"
|
283
|
+
- !ruby/object:Gem::Version
|
284
|
+
version: '13.0'
|
285
|
+
type: :development
|
286
|
+
prerelease: false
|
287
|
+
version_requirements: !ruby/object:Gem::Requirement
|
288
|
+
requirements:
|
289
|
+
- - "~>"
|
290
|
+
- !ruby/object:Gem::Version
|
291
|
+
version: '13.0'
|
292
|
+
- !ruby/object:Gem::Dependency
|
293
|
+
name: require_bench
|
212
294
|
requirement: !ruby/object:Gem::Requirement
|
213
295
|
requirements:
|
214
296
|
- - "~>"
|
@@ -216,7 +298,7 @@ dependencies:
|
|
216
298
|
version: '1.0'
|
217
299
|
- - ">="
|
218
300
|
- !ruby/object:Gem::Version
|
219
|
-
version: 1.0.
|
301
|
+
version: 1.0.4
|
220
302
|
type: :development
|
221
303
|
prerelease: false
|
222
304
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -226,45 +308,114 @@ dependencies:
|
|
226
308
|
version: '1.0'
|
227
309
|
- - ">="
|
228
310
|
- !ruby/object:Gem::Version
|
229
|
-
version: 1.0.
|
311
|
+
version: 1.0.4
|
230
312
|
- !ruby/object:Gem::Dependency
|
231
|
-
name:
|
313
|
+
name: appraisal2
|
232
314
|
requirement: !ruby/object:Gem::Requirement
|
233
315
|
requirements:
|
234
316
|
- - "~>"
|
235
317
|
- !ruby/object:Gem::Version
|
236
|
-
version: '0
|
318
|
+
version: '3.0'
|
237
319
|
type: :development
|
238
320
|
prerelease: false
|
239
321
|
version_requirements: !ruby/object:Gem::Requirement
|
240
322
|
requirements:
|
241
323
|
- - "~>"
|
242
324
|
- !ruby/object:Gem::Version
|
243
|
-
version: '0
|
325
|
+
version: '3.0'
|
244
326
|
- !ruby/object:Gem::Dependency
|
245
|
-
name:
|
327
|
+
name: kettle-test
|
246
328
|
requirement: !ruby/object:Gem::Requirement
|
247
329
|
requirements:
|
248
330
|
- - "~>"
|
249
331
|
- !ruby/object:Gem::Version
|
250
|
-
version: '
|
332
|
+
version: '1.0'
|
333
|
+
type: :development
|
334
|
+
prerelease: false
|
335
|
+
version_requirements: !ruby/object:Gem::Requirement
|
336
|
+
requirements:
|
337
|
+
- - "~>"
|
338
|
+
- !ruby/object:Gem::Version
|
339
|
+
version: '1.0'
|
340
|
+
- !ruby/object:Gem::Dependency
|
341
|
+
name: rspec-pending_for
|
342
|
+
requirement: !ruby/object:Gem::Requirement
|
343
|
+
requirements:
|
344
|
+
- - "~>"
|
345
|
+
- !ruby/object:Gem::Version
|
346
|
+
version: '0.0'
|
251
347
|
- - ">="
|
252
348
|
- !ruby/object:Gem::Version
|
253
|
-
version:
|
349
|
+
version: 0.0.17
|
254
350
|
type: :development
|
255
351
|
prerelease: false
|
256
352
|
version_requirements: !ruby/object:Gem::Requirement
|
257
353
|
requirements:
|
258
354
|
- - "~>"
|
259
355
|
- !ruby/object:Gem::Version
|
260
|
-
version: '
|
356
|
+
version: '0.0'
|
261
357
|
- - ">="
|
262
358
|
- !ruby/object:Gem::Version
|
263
|
-
version:
|
359
|
+
version: 0.0.17
|
360
|
+
- !ruby/object:Gem::Dependency
|
361
|
+
name: ruby-progressbar
|
362
|
+
requirement: !ruby/object:Gem::Requirement
|
363
|
+
requirements:
|
364
|
+
- - "~>"
|
365
|
+
- !ruby/object:Gem::Version
|
366
|
+
version: '1.13'
|
367
|
+
type: :development
|
368
|
+
prerelease: false
|
369
|
+
version_requirements: !ruby/object:Gem::Requirement
|
370
|
+
requirements:
|
371
|
+
- - "~>"
|
372
|
+
- !ruby/object:Gem::Version
|
373
|
+
version: '1.13'
|
374
|
+
- !ruby/object:Gem::Dependency
|
375
|
+
name: stone_checksums
|
376
|
+
requirement: !ruby/object:Gem::Requirement
|
377
|
+
requirements:
|
378
|
+
- - "~>"
|
379
|
+
- !ruby/object:Gem::Version
|
380
|
+
version: '1.0'
|
381
|
+
- - ">="
|
382
|
+
- !ruby/object:Gem::Version
|
383
|
+
version: 1.0.2
|
384
|
+
type: :development
|
385
|
+
prerelease: false
|
386
|
+
version_requirements: !ruby/object:Gem::Requirement
|
387
|
+
requirements:
|
388
|
+
- - "~>"
|
389
|
+
- !ruby/object:Gem::Version
|
390
|
+
version: '1.0'
|
391
|
+
- - ">="
|
392
|
+
- !ruby/object:Gem::Version
|
393
|
+
version: 1.0.2
|
394
|
+
- !ruby/object:Gem::Dependency
|
395
|
+
name: gitmoji-regex
|
396
|
+
requirement: !ruby/object:Gem::Requirement
|
397
|
+
requirements:
|
398
|
+
- - "~>"
|
399
|
+
- !ruby/object:Gem::Version
|
400
|
+
version: '1.0'
|
401
|
+
- - ">="
|
402
|
+
- !ruby/object:Gem::Version
|
403
|
+
version: 1.0.3
|
404
|
+
type: :development
|
405
|
+
prerelease: false
|
406
|
+
version_requirements: !ruby/object:Gem::Requirement
|
407
|
+
requirements:
|
408
|
+
- - "~>"
|
409
|
+
- !ruby/object:Gem::Version
|
410
|
+
version: '1.0'
|
411
|
+
- - ">="
|
412
|
+
- !ruby/object:Gem::Version
|
413
|
+
version: 1.0.3
|
264
414
|
description: "\U0001F510 A Ruby wrapper for the OAuth 2.0 Authorization Framework,
|
265
415
|
including the OAuth 2.1 draft spec, and OpenID Connect (OIDC)"
|
266
416
|
email:
|
267
417
|
- floss@galtzo.com
|
418
|
+
- oauth-ruby@googlegroups.com
|
268
419
|
executables: []
|
269
420
|
extensions: []
|
270
421
|
extra_rdoc_files:
|
@@ -274,6 +425,7 @@ extra_rdoc_files:
|
|
274
425
|
- CONTRIBUTING.md
|
275
426
|
- FUNDING.md
|
276
427
|
- LICENSE.txt
|
428
|
+
- OIDC.md
|
277
429
|
- README.md
|
278
430
|
- REEK
|
279
431
|
- RUBOCOP.md
|
@@ -285,6 +437,7 @@ files:
|
|
285
437
|
- CONTRIBUTING.md
|
286
438
|
- FUNDING.md
|
287
439
|
- LICENSE.txt
|
440
|
+
- OIDC.md
|
288
441
|
- README.md
|
289
442
|
- REEK
|
290
443
|
- RUBOCOP.md
|
@@ -317,10 +470,10 @@ licenses:
|
|
317
470
|
- MIT
|
318
471
|
metadata:
|
319
472
|
homepage_uri: https://oauth2.galtzo.com/
|
320
|
-
source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.
|
321
|
-
changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.
|
473
|
+
source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.15
|
474
|
+
changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.15/CHANGELOG.md
|
322
475
|
bug_tracker_uri: https://github.com/ruby-oauth/oauth2/issues
|
323
|
-
documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.
|
476
|
+
documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.15
|
324
477
|
mailing_list_uri: https://groups.google.com/g/oauth-ruby
|
325
478
|
funding_uri: https://github.com/sponsors/pboling
|
326
479
|
wiki_uri: https://gitlab.com/ruby-oauth/oauth2/-/wiki
|
@@ -329,19 +482,19 @@ metadata:
|
|
329
482
|
rubygems_mfa_required: 'true'
|
330
483
|
post_install_message: |2
|
331
484
|
|
332
|
-
---+++--- oauth2 v2.0.
|
485
|
+
---+++--- oauth2 v2.0.15 ---+++---
|
333
486
|
|
334
487
|
(minor) ⚠️ BREAKING CHANGES ⚠️ when upgrading from < v2
|
335
488
|
• Summary of breaking changes: https://gitlab.com/ruby-oauth/oauth2#what-is-new-for-v20
|
336
|
-
• Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.
|
489
|
+
• Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.15/CHANGELOG.md#2015-2025-09-08
|
337
490
|
|
338
491
|
News:
|
339
|
-
1. New documentation website: https://oauth2.galtzo.com
|
492
|
+
1. New documentation website, including for OAuth 2.1 and OIDC: https://oauth2.galtzo.com
|
340
493
|
2. New official Discord for discussion and support: https://discord.gg/3qme4XHNKN
|
341
494
|
3. New org name "ruby-oauth" on Open Source Collective, GitHub, GitLab, Codeberg (update git remotes!)
|
342
495
|
4. Non-commercial support for the 2.x series will end by April, 2026. Please make a plan to upgrade to the next version prior to that date.
|
343
496
|
Support will be dropped for Ruby 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1 and any other Ruby versions which will also have reached EOL by then.
|
344
|
-
5. Gem releases are cryptographically signed with a 20-year cert
|
497
|
+
5. Gem releases are cryptographically signed with a 20-year cert; SHA-256 & SHA-512 checksums by stone_checksums.
|
345
498
|
6. Please consider supporting this project:
|
346
499
|
• https://opencollective.com/ruby-oauth (new!)
|
347
500
|
• https://liberapay.com/pboling
|
metadata.gz.sig
CHANGED
Binary file
|