rack-oauth2 1.17.0 → 2.2.1
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
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/spec.yml +31 -0
- data/CHANGELOG.md +31 -0
- data/README.rdoc +1 -20
- data/VERSION +1 -1
- data/lib/rack/oauth2/access_token/authenticator.rb +1 -10
- data/lib/rack/oauth2/access_token/bearer.rb +1 -1
- data/lib/rack/oauth2/access_token/mtls.rb +2 -2
- data/lib/rack/oauth2/access_token.rb +4 -6
- data/lib/rack/oauth2/client.rb +86 -38
- data/lib/rack/oauth2/server/abstract/error.rb +2 -1
- data/lib/rack/oauth2/server/extension/pkce.rb +1 -1
- data/lib/rack/oauth2/server/rails/response_ext.rb +3 -3
- data/lib/rack/oauth2/server/resource/error.rb +4 -4
- data/lib/rack/oauth2/server/resource.rb +0 -1
- data/lib/rack/oauth2/server/token/error.rb +3 -1
- data/lib/rack/oauth2/server/token.rb +13 -4
- data/lib/rack/oauth2.rb +11 -10
- data/rack-oauth2.gemspec +6 -4
- data/spec/helpers/webmock_helper.rb +8 -2
- data/spec/rack/oauth2/access_token/authenticator_spec.rb +2 -22
- data/spec/rack/oauth2/access_token/bearer_spec.rb +2 -2
- data/spec/rack/oauth2/access_token_spec.rb +0 -17
- data/spec/rack/oauth2/client_spec.rb +135 -75
- data/spec/rack/oauth2/oauth2_spec.rb +0 -43
- data/spec/rack/oauth2/server/authorize/error_spec.rb +6 -6
- data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +2 -2
- data/spec/rack/oauth2/server/resource/bearer_spec.rb +9 -9
- data/spec/rack/oauth2/server/resource/error_spec.rb +14 -14
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +2 -2
- data/spec/rack/oauth2/server/token/error_spec.rb +5 -5
- data/spec/rack/oauth2/server/token_spec.rb +71 -2
- metadata +43 -47
- data/.travis.yml +0 -8
- data/lib/rack/oauth2/access_token/legacy.rb +0 -19
- data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +0 -17
- data/lib/rack/oauth2/access_token/mac/signature.rb +0 -34
- data/lib/rack/oauth2/access_token/mac/verifier.rb +0 -44
- data/lib/rack/oauth2/access_token/mac.rb +0 -103
- data/lib/rack/oauth2/debugger/request_filter.rb +0 -30
- data/lib/rack/oauth2/debugger.rb +0 -3
- data/lib/rack/oauth2/server/resource/mac/error.rb +0 -24
- data/lib/rack/oauth2/server/resource/mac.rb +0 -36
- data/spec/mock_response/tokens/legacy.json +0 -5
- data/spec/mock_response/tokens/legacy.txt +0 -1
- data/spec/mock_response/tokens/legacy_without_expires_in.txt +0 -1
- data/spec/mock_response/tokens/mac.json +0 -8
- data/spec/rack/oauth2/access_token/legacy_spec.rb +0 -23
- data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +0 -28
- data/spec/rack/oauth2/access_token/mac/signature_spec.rb +0 -59
- data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +0 -25
- data/spec/rack/oauth2/access_token/mac_spec.rb +0 -141
- data/spec/rack/oauth2/debugger/request_filter_spec.rb +0 -33
- data/spec/rack/oauth2/server/resource/mac/error_spec.rb +0 -52
- data/spec/rack/oauth2/server/resource/mac_spec.rb +0 -119
- /data/spec/mock_response/{blank → blank.txt} +0 -0
@@ -7,11 +7,11 @@ describe Rack::OAuth2::AccessToken::Bearer do
|
|
7
7
|
)
|
8
8
|
end
|
9
9
|
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
|
10
|
-
let(:request) {
|
10
|
+
let(:request) { Faraday::Request.new(:post, URI.parse(resource_endpoint), '', {hello: "world"}, {}) }
|
11
11
|
|
12
12
|
describe '.authenticate' do
|
13
13
|
it 'should set Authorization header' do
|
14
|
-
expect(request.
|
14
|
+
expect(request.headers).to receive(:[]=).with('Authorization', 'Bearer access_token')
|
15
15
|
token.authenticate(request)
|
16
16
|
end
|
17
17
|
end
|
@@ -49,23 +49,6 @@ describe Rack::OAuth2::AccessToken do
|
|
49
49
|
|
50
50
|
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
|
51
51
|
[:get, :delete, :post, :put].each do |method|
|
52
|
-
describe method do
|
53
|
-
it 'should delegate to HTTPClient with Authenticator filter' do
|
54
|
-
expect(token.httpclient).to receive(method).with(resource_endpoint)
|
55
|
-
token.httpclient.request_filter.last.should be_a Rack::OAuth2::AccessToken::Authenticator
|
56
|
-
token.send method, resource_endpoint
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'in debug mode' do
|
61
|
-
it do
|
62
|
-
Rack::OAuth2.debug do
|
63
|
-
token.httpclient.request_filter[-2].should be_a Rack::OAuth2::AccessToken::Authenticator
|
64
|
-
token.httpclient.request_filter.last.should be_a Rack::OAuth2::Debugger::RequestFilter
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
52
|
context 'when extension params given' do
|
70
53
|
subject do
|
71
54
|
Rack::OAuth2::AccessToken::Bearer.new(
|
@@ -8,7 +8,8 @@ describe Rack::OAuth2::Client do
|
|
8
8
|
identifier: client_id,
|
9
9
|
secret: client_secret,
|
10
10
|
host: 'server.example.com',
|
11
|
-
redirect_uri: 'https://client.example.com/callback'
|
11
|
+
redirect_uri: 'https://client.example.com/callback',
|
12
|
+
revocation_endpoint: '/oauth2/revoke'
|
12
13
|
)
|
13
14
|
end
|
14
15
|
subject { client }
|
@@ -17,6 +18,7 @@ describe Rack::OAuth2::Client do
|
|
17
18
|
its(:secret) { should == 'client_secret' }
|
18
19
|
its(:authorization_endpoint) { should == '/oauth2/authorize' }
|
19
20
|
its(:token_endpoint) { should == '/oauth2/token' }
|
21
|
+
its(:revocation_endpoint) { should == '/oauth2/revoke' }
|
20
22
|
|
21
23
|
context 'when identifier is missing' do
|
22
24
|
it do
|
@@ -91,7 +93,7 @@ describe Rack::OAuth2::Client do
|
|
91
93
|
mock_response(
|
92
94
|
:post,
|
93
95
|
'https://server.example.com/oauth2/token',
|
94
|
-
'tokens/bearer
|
96
|
+
'tokens/bearer',
|
95
97
|
request_header: {
|
96
98
|
'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ='
|
97
99
|
}
|
@@ -107,7 +109,7 @@ describe Rack::OAuth2::Client do
|
|
107
109
|
mock_response(
|
108
110
|
:post,
|
109
111
|
'https://server.example.com/oauth2/token',
|
110
|
-
'tokens/bearer
|
112
|
+
'tokens/bearer',
|
111
113
|
request_header: {
|
112
114
|
'Authorization' => 'Basic aHR0cHMlM0ElMkYlMkZjbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
|
113
115
|
}
|
@@ -125,7 +127,7 @@ describe Rack::OAuth2::Client do
|
|
125
127
|
mock_response(
|
126
128
|
:post,
|
127
129
|
'https://server.example.com/oauth2/token',
|
128
|
-
'tokens/bearer
|
130
|
+
'tokens/bearer',
|
129
131
|
request_header: {
|
130
132
|
'Authorization' => 'Basic aHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
|
131
133
|
}
|
@@ -141,7 +143,7 @@ describe Rack::OAuth2::Client do
|
|
141
143
|
mock_response(
|
142
144
|
:post,
|
143
145
|
'https://server.example.com/oauth2/token',
|
144
|
-
'tokens/bearer
|
146
|
+
'tokens/bearer',
|
145
147
|
params: {
|
146
148
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\..+/, # NOTE: HS256
|
147
149
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
@@ -169,7 +171,7 @@ describe Rack::OAuth2::Client do
|
|
169
171
|
mock_response(
|
170
172
|
:post,
|
171
173
|
'https://server.example.com/oauth2/token',
|
172
|
-
'tokens/bearer
|
174
|
+
'tokens/bearer',
|
173
175
|
params: {
|
174
176
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9\..+/, # NOTE: RS256
|
175
177
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
@@ -186,7 +188,7 @@ describe Rack::OAuth2::Client do
|
|
186
188
|
let :client do
|
187
189
|
Rack::OAuth2::Client.new(
|
188
190
|
identifier: 'client_id',
|
189
|
-
private_key: OpenSSL::PKey::EC.
|
191
|
+
private_key: OpenSSL::PKey::EC.generate('prime256v1'),
|
190
192
|
host: 'server.example.com',
|
191
193
|
redirect_uri: 'https://client.example.com/callback'
|
192
194
|
)
|
@@ -196,7 +198,7 @@ describe Rack::OAuth2::Client do
|
|
196
198
|
mock_response(
|
197
199
|
:post,
|
198
200
|
'https://server.example.com/oauth2/token',
|
199
|
-
'tokens/bearer
|
201
|
+
'tokens/bearer',
|
200
202
|
params: {
|
201
203
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9\..+/, # NOTE: ES256
|
202
204
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
@@ -223,7 +225,7 @@ describe Rack::OAuth2::Client do
|
|
223
225
|
mock_response(
|
224
226
|
:post,
|
225
227
|
'https://server.example.com/oauth2/token',
|
226
|
-
'tokens/bearer
|
228
|
+
'tokens/bearer',
|
227
229
|
params: {
|
228
230
|
client_assertion: 'any.jwt.assertion',
|
229
231
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
@@ -242,7 +244,7 @@ describe Rack::OAuth2::Client do
|
|
242
244
|
mock_response(
|
243
245
|
:post,
|
244
246
|
'https://server.example.com/oauth2/token',
|
245
|
-
'tokens/bearer
|
247
|
+
'tokens/bearer',
|
246
248
|
params: {
|
247
249
|
client_id: 'client_id',
|
248
250
|
client_secret: 'client_secret',
|
@@ -260,7 +262,7 @@ describe Rack::OAuth2::Client do
|
|
260
262
|
mock_response(
|
261
263
|
:post,
|
262
264
|
'https://server.example.com/oauth2/token',
|
263
|
-
'tokens/bearer
|
265
|
+
'tokens/bearer',
|
264
266
|
params: {
|
265
267
|
client_id: 'client_id',
|
266
268
|
client_secret: 'client_secret',
|
@@ -280,7 +282,7 @@ describe Rack::OAuth2::Client do
|
|
280
282
|
mock_response(
|
281
283
|
:post,
|
282
284
|
'https://server.example.com/oauth2/token',
|
283
|
-
'tokens/bearer
|
285
|
+
'tokens/bearer',
|
284
286
|
params: {
|
285
287
|
grant_type: 'client_credentials',
|
286
288
|
scope: 'a b'
|
@@ -296,7 +298,7 @@ describe Rack::OAuth2::Client do
|
|
296
298
|
mock_response(
|
297
299
|
:post,
|
298
300
|
'https://server.example.com/oauth2/token',
|
299
|
-
'tokens/bearer
|
301
|
+
'tokens/bearer',
|
300
302
|
params: {
|
301
303
|
grant_type: 'client_credentials',
|
302
304
|
resource: 'something'
|
@@ -307,13 +309,30 @@ describe Rack::OAuth2::Client do
|
|
307
309
|
end
|
308
310
|
end
|
309
311
|
|
312
|
+
context 'local_http_config handling' do
|
313
|
+
it do
|
314
|
+
mock_response(
|
315
|
+
:post,
|
316
|
+
'https://server.example.com/oauth2/token',
|
317
|
+
'tokens/bearer',
|
318
|
+
request_header: {
|
319
|
+
'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=',
|
320
|
+
'X-Foo' => 'bar'
|
321
|
+
}
|
322
|
+
)
|
323
|
+
client.access_token! do |request|
|
324
|
+
request.headers['X-Foo'] = 'bar'
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
310
329
|
context 'when bearer token is given' do
|
311
330
|
before do
|
312
331
|
client.authorization_code = 'code'
|
313
332
|
mock_response(
|
314
333
|
:post,
|
315
334
|
'https://server.example.com/oauth2/token',
|
316
|
-
'tokens/bearer
|
335
|
+
'tokens/bearer'
|
317
336
|
)
|
318
337
|
end
|
319
338
|
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
@@ -328,7 +347,7 @@ describe Rack::OAuth2::Client do
|
|
328
347
|
mock_response(
|
329
348
|
:post,
|
330
349
|
'https://server.example.com/oauth2/token',
|
331
|
-
'tokens/_Bearer
|
350
|
+
'tokens/_Bearer'
|
332
351
|
)
|
333
352
|
end
|
334
353
|
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
@@ -336,112 +355,146 @@ describe Rack::OAuth2::Client do
|
|
336
355
|
end
|
337
356
|
end
|
338
357
|
|
339
|
-
context 'when
|
358
|
+
context 'when unknown-type token is given' do
|
340
359
|
before do
|
341
360
|
client.authorization_code = 'code'
|
342
361
|
mock_response(
|
343
362
|
:post,
|
344
363
|
'https://server.example.com/oauth2/token',
|
345
|
-
'tokens/
|
364
|
+
'tokens/unknown'
|
346
365
|
)
|
347
366
|
end
|
348
|
-
it
|
349
|
-
|
350
|
-
|
351
|
-
its(:refresh_token) { should == 'refresh_token' }
|
352
|
-
its(:expires_in) { should == 3600 }
|
367
|
+
it do
|
368
|
+
expect { client.access_token! }.to raise_error(StandardError, 'Unknown Token Type')
|
369
|
+
end
|
353
370
|
end
|
354
371
|
|
355
|
-
context 'when
|
372
|
+
context 'when error response is given' do
|
356
373
|
before do
|
357
|
-
client.authorization_code = 'code'
|
358
374
|
mock_response(
|
359
375
|
:post,
|
360
376
|
'https://server.example.com/oauth2/token',
|
361
|
-
'
|
377
|
+
'errors/invalid_request',
|
378
|
+
status: 400
|
362
379
|
)
|
363
380
|
end
|
364
|
-
it
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
its(:expires_in) { should == 3600 }
|
381
|
+
it do
|
382
|
+
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
|
383
|
+
end
|
384
|
+
end
|
369
385
|
|
370
|
-
|
386
|
+
context 'when no body given' do
|
387
|
+
context 'when error given' do
|
371
388
|
before do
|
372
|
-
|
389
|
+
mock_response(
|
390
|
+
:post,
|
391
|
+
'https://server.example.com/oauth2/token',
|
392
|
+
'blank',
|
393
|
+
format: 'txt',
|
394
|
+
status: 400
|
395
|
+
)
|
396
|
+
end
|
397
|
+
it do
|
398
|
+
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
|
373
399
|
end
|
374
|
-
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
375
|
-
its(:token_type) { should == :bearer }
|
376
400
|
end
|
377
401
|
end
|
402
|
+
end
|
378
403
|
|
379
|
-
|
380
|
-
|
404
|
+
describe '#revoke!' do
|
405
|
+
context 'local_http_config handling' do
|
406
|
+
it do
|
381
407
|
mock_response(
|
382
408
|
:post,
|
383
|
-
'https://server.example.com/oauth2/
|
384
|
-
'
|
409
|
+
'https://server.example.com/oauth2/revoke',
|
410
|
+
'blank',
|
411
|
+
format: 'txt',
|
412
|
+
status: 200,
|
413
|
+
body: {
|
414
|
+
token: 'access_token',
|
415
|
+
token_type_hint: 'access_token'
|
416
|
+
},
|
417
|
+
request_header: {
|
418
|
+
'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=',
|
419
|
+
'X-Foo' => 'bar'
|
420
|
+
}
|
385
421
|
)
|
386
|
-
|
387
|
-
|
388
|
-
its(:token_type) { should == :legacy }
|
389
|
-
its(:access_token) { should == 'access_token' }
|
390
|
-
its(:expires_in) { should == 3600 }
|
391
|
-
|
392
|
-
context 'when expires_in is not given' do
|
393
|
-
before do
|
394
|
-
mock_response(
|
395
|
-
:post,
|
396
|
-
'https://server.example.com/oauth2/token',
|
397
|
-
'tokens/legacy_without_expires_in.txt'
|
398
|
-
)
|
422
|
+
client.revoke!(access_token: 'access_token') do |request|
|
423
|
+
request.headers['X-Foo'] = 'bar'
|
399
424
|
end
|
400
|
-
its(:expires_in) { should be_nil }
|
401
425
|
end
|
402
426
|
end
|
403
427
|
|
404
|
-
context 'when
|
428
|
+
context 'when access_token given' do
|
405
429
|
before do
|
406
|
-
client.authorization_code = 'code'
|
407
430
|
mock_response(
|
408
431
|
:post,
|
409
|
-
'https://server.example.com/oauth2/
|
410
|
-
'
|
432
|
+
'https://server.example.com/oauth2/revoke',
|
433
|
+
'blank',
|
434
|
+
format: 'txt',
|
435
|
+
status: 200,
|
436
|
+
body: {
|
437
|
+
token: 'access_token',
|
438
|
+
token_type_hint: 'access_token'
|
439
|
+
}
|
411
440
|
)
|
412
441
|
end
|
413
442
|
it do
|
414
|
-
|
443
|
+
client.revoke!(access_token: 'access_token').should == :success
|
415
444
|
end
|
416
445
|
end
|
417
446
|
|
418
|
-
context 'when
|
447
|
+
context 'when refresh_token given' do
|
419
448
|
before do
|
420
449
|
mock_response(
|
421
450
|
:post,
|
422
|
-
'https://server.example.com/oauth2/
|
423
|
-
'
|
451
|
+
'https://server.example.com/oauth2/revoke',
|
452
|
+
'blank',
|
453
|
+
format: 'txt',
|
454
|
+
status: 200,
|
455
|
+
body: {
|
456
|
+
token: 'refresh_token',
|
457
|
+
token_type_hint: 'refresh_token'
|
458
|
+
}
|
459
|
+
)
|
460
|
+
end
|
461
|
+
|
462
|
+
context 'as argument' do
|
463
|
+
it do
|
464
|
+
client.revoke!(refresh_token: 'refresh_token').should == :success
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
context 'as grant' do
|
469
|
+
it do
|
470
|
+
client.refresh_token = 'refresh_token'
|
471
|
+
client.revoke!
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
context 'when error response given' do
|
477
|
+
before do
|
478
|
+
mock_response(
|
479
|
+
:post,
|
480
|
+
'https://server.example.com/oauth2/revoke',
|
481
|
+
'errors/invalid_request',
|
424
482
|
status: 400
|
425
483
|
)
|
426
484
|
end
|
485
|
+
|
427
486
|
it do
|
428
|
-
expect
|
487
|
+
expect do
|
488
|
+
client.revoke! access_token: 'access_token'
|
489
|
+
end.to raise_error Rack::OAuth2::Client::Error
|
429
490
|
end
|
430
491
|
end
|
431
492
|
|
432
|
-
context 'when no
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
'https://server.example.com/oauth2/token',
|
438
|
-
'blank',
|
439
|
-
status: 400
|
440
|
-
)
|
441
|
-
end
|
442
|
-
it do
|
443
|
-
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
|
444
|
-
end
|
493
|
+
context 'when no token given' do
|
494
|
+
it do
|
495
|
+
expect do
|
496
|
+
client.revoke!
|
497
|
+
end.to raise_error ArgumentError
|
445
498
|
end
|
446
499
|
end
|
447
500
|
end
|
@@ -451,7 +504,8 @@ describe Rack::OAuth2::Client do
|
|
451
504
|
Rack::OAuth2::Client.new(
|
452
505
|
identifier: 'client_id',
|
453
506
|
secret: 'client_secret',
|
454
|
-
redirect_uri: 'https://client.example.com/callback'
|
507
|
+
redirect_uri: 'https://client.example.com/callback',
|
508
|
+
revocation_endpoint: '/oauth2/revoke'
|
455
509
|
)
|
456
510
|
end
|
457
511
|
|
@@ -466,5 +520,11 @@ describe Rack::OAuth2::Client do
|
|
466
520
|
expect { client.access_token! }.to raise_error 'No Host Info'
|
467
521
|
end
|
468
522
|
end
|
523
|
+
|
524
|
+
describe '#revoke!' do
|
525
|
+
it do
|
526
|
+
expect { client.revoke! access_token: 'access_token' }.to raise_error 'No Host Info'
|
527
|
+
end
|
528
|
+
end
|
469
529
|
end
|
470
530
|
end
|
@@ -28,47 +28,4 @@ describe Rack::OAuth2 do
|
|
28
28
|
Rack::OAuth2.debugging?.should == true
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
describe '.http_config' do
|
33
|
-
context 'when request_filter added' do
|
34
|
-
context 'when "debug!" is called' do
|
35
|
-
after { Rack::OAuth2.reset_http_config! }
|
36
|
-
|
37
|
-
it 'should put Debugger::RequestFilter at last' do
|
38
|
-
Rack::OAuth2.debug!
|
39
|
-
Rack::OAuth2.http_config do |config|
|
40
|
-
config.request_filter << Proc.new {}
|
41
|
-
end
|
42
|
-
Rack::OAuth2.http_client.request_filter.last.should be_instance_of Rack::OAuth2::Debugger::RequestFilter
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should reset_http_config' do
|
46
|
-
Rack::OAuth2.debug!
|
47
|
-
Rack::OAuth2.http_config do |config|
|
48
|
-
config.request_filter << Proc.new {}
|
49
|
-
end
|
50
|
-
size = Rack::OAuth2.http_client.request_filter.size
|
51
|
-
Rack::OAuth2.reset_http_config!
|
52
|
-
Rack::OAuth2.http_client.request_filter.size.should == size - 1
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe ".http_client" do
|
60
|
-
context "when local_http_config is used" do
|
61
|
-
it "should correctly set request_filter" do
|
62
|
-
clnt1 = Rack::OAuth2.http_client
|
63
|
-
clnt2 = Rack::OAuth2.http_client("my client") do |config|
|
64
|
-
config.request_filter << Proc.new {}
|
65
|
-
end
|
66
|
-
clnt3 = Rack::OAuth2.http_client
|
67
|
-
|
68
|
-
clnt1.request_filter.size.should == clnt3.request_filter.size
|
69
|
-
clnt1.request_filter.size.should == clnt2.request_filter.size - 1
|
70
|
-
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
31
|
end
|
@@ -23,27 +23,27 @@ describe Rack::OAuth2::Server::Authorize::BadRequest do
|
|
23
23
|
context 'when protocol_params_location = :query' do
|
24
24
|
before { error.protocol_params_location = :query }
|
25
25
|
it 'should redirect with error in query' do
|
26
|
-
state,
|
26
|
+
state, headers, response = error.finish
|
27
27
|
state.should == 302
|
28
|
-
|
28
|
+
headers["Location"].should == "#{redirect_uri}?error=invalid_request"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'when protocol_params_location = :fragment' do
|
33
33
|
before { error.protocol_params_location = :fragment }
|
34
34
|
it 'should redirect with error in fragment' do
|
35
|
-
state,
|
35
|
+
state, headers, response = error.finish
|
36
36
|
state.should == 302
|
37
|
-
|
37
|
+
headers["Location"].should == "#{redirect_uri}#error=invalid_request"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
context 'otherwise' do
|
42
42
|
before { error.protocol_params_location = :other }
|
43
43
|
it 'should redirect without error' do
|
44
|
-
state,
|
44
|
+
state, headers, response = error.finish
|
45
45
|
state.should == 302
|
46
|
-
|
46
|
+
headers["Location"].should == redirect_uri
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -12,8 +12,8 @@ describe Rack::OAuth2::Server::Resource::Bearer::Unauthorized do
|
|
12
12
|
|
13
13
|
describe '#finish' do
|
14
14
|
it 'should use Bearer scheme' do
|
15
|
-
status,
|
16
|
-
|
15
|
+
status, headers, response = error.finish
|
16
|
+
headers['WWW-Authenticate'].should include 'Bearer'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -22,29 +22,29 @@ describe Rack::OAuth2::Server::Resource::Bearer do
|
|
22
22
|
|
23
23
|
shared_examples_for :authenticated_bearer_request do
|
24
24
|
it 'should be authenticated' do
|
25
|
-
status,
|
25
|
+
status, headers, response = request
|
26
26
|
status.should == 200
|
27
27
|
access_token.should == bearer_token
|
28
28
|
end
|
29
29
|
end
|
30
30
|
shared_examples_for :unauthorized_bearer_request do
|
31
31
|
it 'should be unauthorized' do
|
32
|
-
status,
|
32
|
+
status, headers, response = request
|
33
33
|
status.should == 401
|
34
|
-
|
34
|
+
headers['WWW-Authenticate'].should include 'Bearer'
|
35
35
|
access_token.should be_nil
|
36
36
|
end
|
37
37
|
end
|
38
38
|
shared_examples_for :bad_bearer_request do
|
39
39
|
it 'should be bad_request' do
|
40
|
-
status,
|
40
|
+
status, headers, response = request
|
41
41
|
status.should == 400
|
42
42
|
access_token.should be_nil
|
43
43
|
end
|
44
44
|
end
|
45
45
|
shared_examples_for :skipped_authentication_request do
|
46
46
|
it 'should skip OAuth 2.0 authentication' do
|
47
|
-
status,
|
47
|
+
status, headers, response = request
|
48
48
|
status.should == 200
|
49
49
|
access_token.should be_nil
|
50
50
|
end
|
@@ -94,15 +94,15 @@ describe Rack::OAuth2::Server::Resource::Bearer do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
it 'should use specified realm' do
|
97
|
-
status,
|
98
|
-
|
97
|
+
status, headers, response = request
|
98
|
+
headers['WWW-Authenticate'].should include "Bearer realm=\"#{realm}\""
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
context 'otherwize' do
|
103
103
|
it 'should use default realm' do
|
104
|
-
status,
|
105
|
-
|
104
|
+
status, headers, response = request
|
105
|
+
headers['WWW-Authenticate'].should include "Bearer realm=\"#{Rack::OAuth2::Server::Resource::Bearer::DEFAULT_REALM}\""
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -7,9 +7,9 @@ describe Rack::OAuth2::Server::Resource::BadRequest do
|
|
7
7
|
|
8
8
|
describe '#finish' do
|
9
9
|
it 'should respond in JSON' do
|
10
|
-
status,
|
10
|
+
status, headers, response = error.finish
|
11
11
|
status.should == 400
|
12
|
-
|
12
|
+
headers['Content-Type'].should == 'application/json'
|
13
13
|
response.should == ['{"error":"invalid_request"}']
|
14
14
|
end
|
15
15
|
end
|
@@ -40,10 +40,10 @@ describe Rack::OAuth2::Server::Resource::Unauthorized do
|
|
40
40
|
|
41
41
|
describe '#finish' do
|
42
42
|
it 'should respond in JSON' do
|
43
|
-
status,
|
43
|
+
status, headers, response = error_with_scheme.finish
|
44
44
|
status.should == 401
|
45
|
-
|
46
|
-
|
45
|
+
headers['Content-Type'].should == 'application/json'
|
46
|
+
headers['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\", error=\"invalid_token\""
|
47
47
|
response.should == ['{"error":"invalid_token"}']
|
48
48
|
end
|
49
49
|
|
@@ -51,8 +51,8 @@ describe Rack::OAuth2::Server::Resource::Unauthorized do
|
|
51
51
|
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:something) }
|
52
52
|
|
53
53
|
it 'should have error_code in body but not in WWW-Authenticate header' do
|
54
|
-
status,
|
55
|
-
|
54
|
+
status, headers, response = error_with_scheme.finish
|
55
|
+
headers['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
|
56
56
|
response.first.should include '"error":"something"'
|
57
57
|
end
|
58
58
|
end
|
@@ -61,8 +61,8 @@ describe Rack::OAuth2::Server::Resource::Unauthorized do
|
|
61
61
|
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new }
|
62
62
|
|
63
63
|
it 'should have error_code in body but not in WWW-Authenticate header' do
|
64
|
-
status,
|
65
|
-
|
64
|
+
status, headers, response = error_with_scheme.finish
|
65
|
+
headers['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
|
66
66
|
response.first.should == '{"error":"unauthorized"}'
|
67
67
|
end
|
68
68
|
end
|
@@ -72,8 +72,8 @@ describe Rack::OAuth2::Server::Resource::Unauthorized do
|
|
72
72
|
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:something, nil, realm: realm) }
|
73
73
|
|
74
74
|
it 'should use given realm' do
|
75
|
-
status,
|
76
|
-
|
75
|
+
status, headers, response = error_with_scheme.finish
|
76
|
+
headers['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
|
77
77
|
response.first.should include '"error":"something"'
|
78
78
|
end
|
79
79
|
end
|
@@ -88,9 +88,9 @@ describe Rack::OAuth2::Server::Resource::Forbidden do
|
|
88
88
|
|
89
89
|
describe '#finish' do
|
90
90
|
it 'should respond in JSON' do
|
91
|
-
status,
|
91
|
+
status, headers, response = error.finish
|
92
92
|
status.should == 403
|
93
|
-
|
93
|
+
headers['Content-Type'].should == 'application/json'
|
94
94
|
response.should == ['{"error":"insufficient_scope"}']
|
95
95
|
end
|
96
96
|
end
|
@@ -99,7 +99,7 @@ describe Rack::OAuth2::Server::Resource::Forbidden do
|
|
99
99
|
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Forbidden.new(:insufficient_scope, 'Desc', scope: [:scope1, :scope2]) }
|
100
100
|
|
101
101
|
it 'should have blank WWW-Authenticate header' do
|
102
|
-
status,
|
102
|
+
status, headers, response = error.finish
|
103
103
|
response.first.should include '"scope":"scope1 scope2"'
|
104
104
|
end
|
105
105
|
end
|
@@ -24,8 +24,8 @@ describe Rack::OAuth2::Server::Token::AuthorizationCode do
|
|
24
24
|
its(:body) { should include '"token_type":"bearer"' }
|
25
25
|
|
26
26
|
it 'should prevent to be cached' do
|
27
|
-
response.
|
28
|
-
response.
|
27
|
+
response.headers['Cache-Control'].should == 'no-store'
|
28
|
+
response.headers['Pragma'].should == 'no-cache'
|
29
29
|
end
|
30
30
|
|
31
31
|
[:code].each do |required|
|