rack-oauth2 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc2833ffc404397f87ef3649c867783f4492cefab8eaceccadf7c18b740cf018
4
- data.tar.gz: 8bbf82e5725bbf685681cfa99ada0d6dd0652bbbf741077e240163611f2077f5
3
+ metadata.gz: 45ba67ac4566f374465673cc5711e71c15006bbe966531a4c1de2473206879b2
4
+ data.tar.gz: 56f8718f283533c369b1743dfd86499e49e5d828a83ac060fa919fac57a935d2
5
5
  SHA512:
6
- metadata.gz: d11c97df887b9c0e784d6dc322d61d9e7c9dd20f2e89ae118b2863449bf8bc5658642eb52808facec041a3b6ad64e805e8ee3ac84032567bdf5e13335c8b6337
7
- data.tar.gz: fdca45ec17029200d4d743e52614ef4b4ae5b15d5e3248805b69890644e7f2867f387bac50ebd27803bdbead21942efaf6e53de127a7093257c140156ae64327
6
+ metadata.gz: 63316467536c2c98cddea9b2b7907b3ff5fd6b53b892bd338709e1f7a6b014aa4dc20d71b12cd01ffac502c1ab0964218aac7ff6a0e81141ff8aa10e80557cdd
7
+ data.tar.gz: 97e685531853c4837a0e86636c865827033e25f646c4572d254e2584a811f937faa6dc7fe780742814bd9657066c9fc16394723ba87029605761d5acf2d490f7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.1.0] - 2022-10-10
4
+
5
+ ### Added
6
+
7
+ - accept local_http_config on Rack::OAuth2::Client#access_token! & revoke! to support custom headers etc. by @nov in https://github.com/nov/rack-oauth2/pull/93
8
+
3
9
  ## [2.0.1] - 2022-10-09
4
10
 
5
11
  ### Fixed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.2.0
@@ -39,5 +39,4 @@ end
39
39
 
40
40
  require 'rack/oauth2/access_token/authenticator'
41
41
  require 'rack/oauth2/access_token/bearer'
42
- require 'rack/oauth2/access_token/legacy'
43
42
  require 'rack/oauth2/access_token/mtls'
@@ -68,8 +68,8 @@ module Rack
68
68
  @forced_token_type = token_type.to_s
69
69
  end
70
70
 
71
- def access_token!(*args, &local_http_config)
72
- headers, params, http_client, options = authenticated_context_from(*args, &local_http_config)
71
+ def access_token!(*args)
72
+ headers, params, http_client, options = authenticated_context_from(*args)
73
73
  params[:scope] = Array(options.delete(:scope)).join(' ') if options[:scope].present?
74
74
  params.merge! @grant.as_json
75
75
  params.merge! options
@@ -78,12 +78,14 @@ module Rack
78
78
  absolute_uri_for(token_endpoint),
79
79
  Util.compact_hash(params),
80
80
  headers
81
- )
81
+ ) do |req|
82
+ yield req if block_given?
83
+ end
82
84
  end
83
85
  end
84
86
 
85
- def revoke!(*args, &local_http_config)
86
- headers, params, http_client, options = authenticated_context_from(*args, &local_http_config)
87
+ def revoke!(*args)
88
+ headers, params, http_client, options = authenticated_context_from(*args)
87
89
 
88
90
  params.merge! case
89
91
  when access_token = options.delete(:access_token)
@@ -111,7 +113,9 @@ module Rack
111
113
  absolute_uri_for(revocation_endpoint),
112
114
  Util.compact_hash(params),
113
115
  headers
114
- )
116
+ ) do |req|
117
+ yield req if block_given?
118
+ end
115
119
  end
116
120
  end
117
121
 
@@ -126,9 +130,9 @@ module Rack
126
130
  _endpoint_.to_s
127
131
  end
128
132
 
129
- def authenticated_context_from(*args, &local_http_config)
133
+ def authenticated_context_from(*args)
130
134
  headers, params = {}, {}
131
- http_client = Rack::OAuth2.http_client(&local_http_config)
135
+ http_client = Rack::OAuth2.http_client
132
136
 
133
137
  # NOTE:
134
138
  # Using Array#extract_options! for backward compatibility.
@@ -209,24 +213,19 @@ module Rack
209
213
  end
210
214
 
211
215
  def handle_success_response(response)
212
- token_hash = JSON.parse(response.body).with_indifferent_access
216
+ token_hash = response.body.with_indifferent_access
213
217
  case (@forced_token_type || token_hash[:token_type])&.downcase
214
218
  when 'bearer'
215
219
  AccessToken::Bearer.new(token_hash)
216
- when nil
217
- AccessToken::Legacy.new(token_hash)
218
220
  else
219
221
  raise 'Unknown Token Type'
220
222
  end
221
- rescue JSON::ParserError
222
- # NOTE: Facebook support (They don't use JSON as token response)
223
- AccessToken::Legacy.new Rack::Utils.parse_nested_query(response.body).with_indifferent_access
224
223
  end
225
224
 
226
225
  def handle_error_response(response)
227
- error = JSON.parse(response.body).with_indifferent_access
226
+ error = response.body.with_indifferent_access
228
227
  raise Error.new(response.status, error)
229
- rescue JSON::ParserError
228
+ rescue Faraday::ParsingError, NoMethodError
230
229
  raise Error.new(response.status, error: 'Unknown', error_description: response.body)
231
230
  end
232
231
  end
data/lib/rack/oauth2.rb CHANGED
@@ -44,6 +44,7 @@ module Rack
44
44
  Faraday.new(headers: {user_agent: agent_name}) do |faraday|
45
45
  faraday.request :url_encoded
46
46
  faraday.request :json
47
+ faraday.response :json
47
48
  faraday.response :logger, Rack::OAuth2.logger, {bodies: true} if debugging?
48
49
  faraday.adapter Faraday.default_adapter
49
50
  local_http_config&.call(faraday)
@@ -28,7 +28,13 @@ module WebMockHelper
28
28
 
29
29
  def response_for(response_file, options = {})
30
30
  response = {}
31
- response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', response_file))
31
+ format = options[:format] || :json
32
+ if format == :json
33
+ response[:headers] = {
34
+ 'Content-Type': 'application/json'
35
+ }
36
+ end
37
+ response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', "#{response_file}.#{format}"))
32
38
  if options[:status]
33
39
  response[:status] = options[:status]
34
40
  end
File without changes
@@ -12,15 +12,6 @@ describe Rack::OAuth2::AccessToken::Authenticator do
12
12
  end
13
13
  end
14
14
 
15
- context 'when Legacy token is given' do
16
- let(:token) do
17
- Rack::OAuth2::AccessToken::Legacy.new(
18
- access_token: 'access_token'
19
- )
20
- end
21
- it_behaves_like :authenticator
22
- end
23
-
24
15
  context 'when Bearer token is given' do
25
16
  let(:token) do
26
17
  Rack::OAuth2::AccessToken::Bearer.new(
@@ -93,7 +93,7 @@ describe Rack::OAuth2::Client do
93
93
  mock_response(
94
94
  :post,
95
95
  'https://server.example.com/oauth2/token',
96
- 'tokens/bearer.json',
96
+ 'tokens/bearer',
97
97
  request_header: {
98
98
  'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ='
99
99
  }
@@ -109,7 +109,7 @@ describe Rack::OAuth2::Client do
109
109
  mock_response(
110
110
  :post,
111
111
  'https://server.example.com/oauth2/token',
112
- 'tokens/bearer.json',
112
+ 'tokens/bearer',
113
113
  request_header: {
114
114
  'Authorization' => 'Basic aHR0cHMlM0ElMkYlMkZjbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
115
115
  }
@@ -127,7 +127,7 @@ describe Rack::OAuth2::Client do
127
127
  mock_response(
128
128
  :post,
129
129
  'https://server.example.com/oauth2/token',
130
- 'tokens/bearer.json',
130
+ 'tokens/bearer',
131
131
  request_header: {
132
132
  'Authorization' => 'Basic aHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
133
133
  }
@@ -143,7 +143,7 @@ describe Rack::OAuth2::Client do
143
143
  mock_response(
144
144
  :post,
145
145
  'https://server.example.com/oauth2/token',
146
- 'tokens/bearer.json',
146
+ 'tokens/bearer',
147
147
  params: {
148
148
  client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\..+/, # NOTE: HS256
149
149
  client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
@@ -171,7 +171,7 @@ describe Rack::OAuth2::Client do
171
171
  mock_response(
172
172
  :post,
173
173
  'https://server.example.com/oauth2/token',
174
- 'tokens/bearer.json',
174
+ 'tokens/bearer',
175
175
  params: {
176
176
  client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9\..+/, # NOTE: RS256
177
177
  client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
@@ -198,7 +198,7 @@ describe Rack::OAuth2::Client do
198
198
  mock_response(
199
199
  :post,
200
200
  'https://server.example.com/oauth2/token',
201
- 'tokens/bearer.json',
201
+ 'tokens/bearer',
202
202
  params: {
203
203
  client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9\..+/, # NOTE: ES256
204
204
  client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
@@ -225,7 +225,7 @@ describe Rack::OAuth2::Client do
225
225
  mock_response(
226
226
  :post,
227
227
  'https://server.example.com/oauth2/token',
228
- 'tokens/bearer.json',
228
+ 'tokens/bearer',
229
229
  params: {
230
230
  client_assertion: 'any.jwt.assertion',
231
231
  client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
@@ -244,7 +244,7 @@ describe Rack::OAuth2::Client do
244
244
  mock_response(
245
245
  :post,
246
246
  'https://server.example.com/oauth2/token',
247
- 'tokens/bearer.json',
247
+ 'tokens/bearer',
248
248
  params: {
249
249
  client_id: 'client_id',
250
250
  client_secret: 'client_secret',
@@ -262,7 +262,7 @@ describe Rack::OAuth2::Client do
262
262
  mock_response(
263
263
  :post,
264
264
  'https://server.example.com/oauth2/token',
265
- 'tokens/bearer.json',
265
+ 'tokens/bearer',
266
266
  params: {
267
267
  client_id: 'client_id',
268
268
  client_secret: 'client_secret',
@@ -282,7 +282,7 @@ describe Rack::OAuth2::Client do
282
282
  mock_response(
283
283
  :post,
284
284
  'https://server.example.com/oauth2/token',
285
- 'tokens/bearer.json',
285
+ 'tokens/bearer',
286
286
  params: {
287
287
  grant_type: 'client_credentials',
288
288
  scope: 'a b'
@@ -298,7 +298,7 @@ describe Rack::OAuth2::Client do
298
298
  mock_response(
299
299
  :post,
300
300
  'https://server.example.com/oauth2/token',
301
- 'tokens/bearer.json',
301
+ 'tokens/bearer',
302
302
  params: {
303
303
  grant_type: 'client_credentials',
304
304
  resource: 'something'
@@ -314,14 +314,14 @@ describe Rack::OAuth2::Client do
314
314
  mock_response(
315
315
  :post,
316
316
  'https://server.example.com/oauth2/token',
317
- 'tokens/bearer.json',
317
+ 'tokens/bearer',
318
318
  request_header: {
319
319
  'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=',
320
320
  'X-Foo' => 'bar'
321
321
  }
322
322
  )
323
323
  client.access_token! do |request|
324
- request.headers.merge! 'X-Foo' => 'bar'
324
+ request.headers['X-Foo'] = 'bar'
325
325
  end
326
326
  end
327
327
  end
@@ -332,7 +332,7 @@ describe Rack::OAuth2::Client do
332
332
  mock_response(
333
333
  :post,
334
334
  'https://server.example.com/oauth2/token',
335
- 'tokens/bearer.json'
335
+ 'tokens/bearer'
336
336
  )
337
337
  end
338
338
  it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
@@ -347,7 +347,7 @@ describe Rack::OAuth2::Client do
347
347
  mock_response(
348
348
  :post,
349
349
  'https://server.example.com/oauth2/token',
350
- 'tokens/_Bearer.json'
350
+ 'tokens/_Bearer'
351
351
  )
352
352
  end
353
353
  it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
@@ -355,62 +355,13 @@ describe Rack::OAuth2::Client do
355
355
  end
356
356
  end
357
357
 
358
- context 'when no-type token is given (JSON)' do
359
- before do
360
- client.authorization_code = 'code'
361
- mock_response(
362
- :post,
363
- 'https://server.example.com/oauth2/token',
364
- 'tokens/legacy.json'
365
- )
366
- end
367
- it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
368
- its(:token_type) { should == :legacy }
369
- its(:access_token) { should == 'access_token' }
370
- its(:refresh_token) { should == 'refresh_token' }
371
- its(:expires_in) { should == 3600 }
372
-
373
- context 'when token_type is forced' do
374
- before do
375
- client.force_token_type! :bearer
376
- end
377
- it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
378
- its(:token_type) { should == :bearer }
379
- end
380
- end
381
-
382
- context 'when no-type token is given (key-value)' do
383
- before do
384
- mock_response(
385
- :post,
386
- 'https://server.example.com/oauth2/token',
387
- 'tokens/legacy.txt'
388
- )
389
- end
390
- it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
391
- its(:token_type) { should == :legacy }
392
- its(:access_token) { should == 'access_token' }
393
- its(:expires_in) { should == 3600 }
394
-
395
- context 'when expires_in is not given' do
396
- before do
397
- mock_response(
398
- :post,
399
- 'https://server.example.com/oauth2/token',
400
- 'tokens/legacy_without_expires_in.txt'
401
- )
402
- end
403
- its(:expires_in) { should be_nil }
404
- end
405
- end
406
-
407
358
  context 'when unknown-type token is given' do
408
359
  before do
409
360
  client.authorization_code = 'code'
410
361
  mock_response(
411
362
  :post,
412
363
  'https://server.example.com/oauth2/token',
413
- 'tokens/unknown.json'
364
+ 'tokens/unknown'
414
365
  )
415
366
  end
416
367
  it do
@@ -423,7 +374,7 @@ describe Rack::OAuth2::Client do
423
374
  mock_response(
424
375
  :post,
425
376
  'https://server.example.com/oauth2/token',
426
- 'errors/invalid_request.json',
377
+ 'errors/invalid_request',
427
378
  status: 400
428
379
  )
429
380
  end
@@ -439,6 +390,7 @@ describe Rack::OAuth2::Client do
439
390
  :post,
440
391
  'https://server.example.com/oauth2/token',
441
392
  'blank',
393
+ format: 'txt',
442
394
  status: 400
443
395
  )
444
396
  end
@@ -456,6 +408,7 @@ describe Rack::OAuth2::Client do
456
408
  :post,
457
409
  'https://server.example.com/oauth2/revoke',
458
410
  'blank',
411
+ format: 'txt',
459
412
  status: 200,
460
413
  body: {
461
414
  token: 'access_token',
@@ -467,7 +420,7 @@ describe Rack::OAuth2::Client do
467
420
  }
468
421
  )
469
422
  client.revoke!(access_token: 'access_token') do |request|
470
- request.headers.merge! 'X-Foo' => 'bar'
423
+ request.headers['X-Foo'] = 'bar'
471
424
  end
472
425
  end
473
426
  end
@@ -478,6 +431,7 @@ describe Rack::OAuth2::Client do
478
431
  :post,
479
432
  'https://server.example.com/oauth2/revoke',
480
433
  'blank',
434
+ format: 'txt',
481
435
  status: 200,
482
436
  body: {
483
437
  token: 'access_token',
@@ -496,6 +450,7 @@ describe Rack::OAuth2::Client do
496
450
  :post,
497
451
  'https://server.example.com/oauth2/revoke',
498
452
  'blank',
453
+ format: 'txt',
499
454
  status: 200,
500
455
  body: {
501
456
  token: 'refresh_token',
@@ -523,7 +478,7 @@ describe Rack::OAuth2::Client do
523
478
  mock_response(
524
479
  :post,
525
480
  'https://server.example.com/oauth2/revoke',
526
- 'errors/invalid_request.json',
481
+ 'errors/invalid_request',
527
482
  status: 400
528
483
  )
529
484
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-09 00:00:00.000000000 Z
11
+ date: 2022-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -201,7 +201,6 @@ files:
201
201
  - lib/rack/oauth2/access_token.rb
202
202
  - lib/rack/oauth2/access_token/authenticator.rb
203
203
  - lib/rack/oauth2/access_token/bearer.rb
204
- - lib/rack/oauth2/access_token/legacy.rb
205
204
  - lib/rack/oauth2/access_token/mtls.rb
206
205
  - lib/rack/oauth2/client.rb
207
206
  - lib/rack/oauth2/client/error.rb
@@ -250,18 +249,14 @@ files:
250
249
  - rack-oauth2.gemspec
251
250
  - spec/helpers/time.rb
252
251
  - spec/helpers/webmock_helper.rb
253
- - spec/mock_response/blank
252
+ - spec/mock_response/blank.txt
254
253
  - spec/mock_response/errors/invalid_request.json
255
254
  - spec/mock_response/resources/fake.txt
256
255
  - spec/mock_response/tokens/_Bearer.json
257
256
  - spec/mock_response/tokens/bearer.json
258
- - spec/mock_response/tokens/legacy.json
259
- - spec/mock_response/tokens/legacy.txt
260
- - spec/mock_response/tokens/legacy_without_expires_in.txt
261
257
  - spec/mock_response/tokens/unknown.json
262
258
  - spec/rack/oauth2/access_token/authenticator_spec.rb
263
259
  - spec/rack/oauth2/access_token/bearer_spec.rb
264
- - spec/rack/oauth2/access_token/legacy_spec.rb
265
260
  - spec/rack/oauth2/access_token_spec.rb
266
261
  - spec/rack/oauth2/client/error_spec.rb
267
262
  - spec/rack/oauth2/client/grant/authorization_code_spec.rb
@@ -321,18 +316,14 @@ summary: OAuth 2.0 Server & Client Library - Both Bearer token type are supporte
321
316
  test_files:
322
317
  - spec/helpers/time.rb
323
318
  - spec/helpers/webmock_helper.rb
324
- - spec/mock_response/blank
319
+ - spec/mock_response/blank.txt
325
320
  - spec/mock_response/errors/invalid_request.json
326
321
  - spec/mock_response/resources/fake.txt
327
322
  - spec/mock_response/tokens/_Bearer.json
328
323
  - spec/mock_response/tokens/bearer.json
329
- - spec/mock_response/tokens/legacy.json
330
- - spec/mock_response/tokens/legacy.txt
331
- - spec/mock_response/tokens/legacy_without_expires_in.txt
332
324
  - spec/mock_response/tokens/unknown.json
333
325
  - spec/rack/oauth2/access_token/authenticator_spec.rb
334
326
  - spec/rack/oauth2/access_token/bearer_spec.rb
335
- - spec/rack/oauth2/access_token/legacy_spec.rb
336
327
  - spec/rack/oauth2/access_token_spec.rb
337
328
  - spec/rack/oauth2/client/error_spec.rb
338
329
  - spec/rack/oauth2/client/grant/authorization_code_spec.rb
@@ -1,19 +0,0 @@
1
- module Rack
2
- module OAuth2
3
- class AccessToken
4
- class Legacy < AccessToken
5
- def initialize(attributes = {})
6
- super
7
- self.expires_in = (
8
- self.expires_in ||
9
- attributes[:expires]
10
- )&.to_i
11
- end
12
-
13
- def authenticate(request)
14
- request.headers["Authorization"] = "OAuth #{access_token}"
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,5 +0,0 @@
1
- {
2
- "access_token":"access_token",
3
- "refresh_token":"refresh_token",
4
- "expires_in":3600
5
- }
@@ -1 +0,0 @@
1
- access_token=access_token&expires=3600
@@ -1 +0,0 @@
1
- access_token=access_token
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rack::OAuth2::AccessToken::Legacy do
4
- let :token do
5
- Rack::OAuth2::AccessToken::Legacy.new(
6
- access_token: 'access_token'
7
- )
8
- end
9
- let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
10
- let(:request) { Faraday::Request.new(:post, URI.parse(resource_endpoint), '', {hello: "world"}, {}) }
11
-
12
- describe '#to_s' do
13
- subject { token }
14
- its(:to_s) { should == token.access_token }
15
- end
16
-
17
- describe '.authenticate' do
18
- it 'should set Authorization header' do
19
- expect(request.headers).to receive(:[]=).with('Authorization', 'OAuth access_token')
20
- token.authenticate(request)
21
- end
22
- end
23
- end