rack-oauth2 1.15.0 → 2.2.0
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 +32 -0
- data/CHANGELOG.md +25 -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 +93 -40
- 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 +16 -5
- data/lib/rack/oauth2/util.rb +4 -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 +152 -74
- 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/client_credentials_spec.rb +32 -2
- data/spec/rack/oauth2/server/token/error_spec.rb +5 -5
- data/spec/rack/oauth2/server/token_spec.rb +71 -2
- data/spec/rack/oauth2/util_spec.rb +6 -6
- metadata +43 -47
- data/.travis.yml +0 -7
- 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
|
@@ -2,25 +2,16 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Rack::OAuth2::AccessToken::Authenticator do
|
|
4
4
|
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
|
|
5
|
-
let(:request) {
|
|
5
|
+
let(:request) { Faraday::Request.new(:get, URI.parse(resource_endpoint)) }
|
|
6
6
|
let(:authenticator) { Rack::OAuth2::AccessToken::Authenticator.new(token) }
|
|
7
7
|
|
|
8
8
|
shared_examples_for :authenticator do
|
|
9
9
|
it 'should let the token authenticate the request' do
|
|
10
10
|
expect(token).to receive(:authenticate).with(request)
|
|
11
|
-
authenticator.
|
|
11
|
+
authenticator.authenticate(request)
|
|
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(
|
|
@@ -29,15 +20,4 @@ describe Rack::OAuth2::AccessToken::Authenticator do
|
|
|
29
20
|
end
|
|
30
21
|
it_behaves_like :authenticator
|
|
31
22
|
end
|
|
32
|
-
|
|
33
|
-
context 'when MAC token is given' do
|
|
34
|
-
let(:token) do
|
|
35
|
-
Rack::OAuth2::AccessToken::MAC.new(
|
|
36
|
-
access_token: 'access_token',
|
|
37
|
-
mac_key: 'secret',
|
|
38
|
-
mac_algorithm: 'hmac-sha-256'
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
it_behaves_like :authenticator
|
|
42
|
-
end
|
|
43
23
|
end
|
|
@@ -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
|
}
|
|
@@ -117,13 +119,31 @@ describe Rack::OAuth2::Client do
|
|
|
117
119
|
end
|
|
118
120
|
end
|
|
119
121
|
|
|
122
|
+
context 'when basic_without_www_form_urlencode method is used' do
|
|
123
|
+
context 'when client_id is a url' do
|
|
124
|
+
let(:client_id) { 'https://client.example.com'}
|
|
125
|
+
|
|
126
|
+
it 'should be encoded in "application/x-www-form-urlencoded"' do
|
|
127
|
+
mock_response(
|
|
128
|
+
:post,
|
|
129
|
+
'https://server.example.com/oauth2/token',
|
|
130
|
+
'tokens/bearer',
|
|
131
|
+
request_header: {
|
|
132
|
+
'Authorization' => 'Basic aHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
client.access_token! :basic_without_www_form_urlencode
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
120
140
|
context 'when jwt_bearer auth method specified' do
|
|
121
141
|
context 'when client_secret is given' do
|
|
122
142
|
it 'should be JWT bearer client assertion w/ auto-generated HS256-signed JWT assertion' do
|
|
123
143
|
mock_response(
|
|
124
144
|
:post,
|
|
125
145
|
'https://server.example.com/oauth2/token',
|
|
126
|
-
'tokens/bearer
|
|
146
|
+
'tokens/bearer',
|
|
127
147
|
params: {
|
|
128
148
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\..+/, # NOTE: HS256
|
|
129
149
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
|
@@ -151,7 +171,7 @@ describe Rack::OAuth2::Client do
|
|
|
151
171
|
mock_response(
|
|
152
172
|
:post,
|
|
153
173
|
'https://server.example.com/oauth2/token',
|
|
154
|
-
'tokens/bearer
|
|
174
|
+
'tokens/bearer',
|
|
155
175
|
params: {
|
|
156
176
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9\..+/, # NOTE: RS256
|
|
157
177
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
|
@@ -168,7 +188,7 @@ describe Rack::OAuth2::Client do
|
|
|
168
188
|
let :client do
|
|
169
189
|
Rack::OAuth2::Client.new(
|
|
170
190
|
identifier: 'client_id',
|
|
171
|
-
private_key: OpenSSL::PKey::EC.
|
|
191
|
+
private_key: OpenSSL::PKey::EC.generate('prime256v1'),
|
|
172
192
|
host: 'server.example.com',
|
|
173
193
|
redirect_uri: 'https://client.example.com/callback'
|
|
174
194
|
)
|
|
@@ -178,7 +198,7 @@ describe Rack::OAuth2::Client do
|
|
|
178
198
|
mock_response(
|
|
179
199
|
:post,
|
|
180
200
|
'https://server.example.com/oauth2/token',
|
|
181
|
-
'tokens/bearer
|
|
201
|
+
'tokens/bearer',
|
|
182
202
|
params: {
|
|
183
203
|
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9\..+/, # NOTE: ES256
|
|
184
204
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
|
@@ -205,7 +225,7 @@ describe Rack::OAuth2::Client do
|
|
|
205
225
|
mock_response(
|
|
206
226
|
:post,
|
|
207
227
|
'https://server.example.com/oauth2/token',
|
|
208
|
-
'tokens/bearer
|
|
228
|
+
'tokens/bearer',
|
|
209
229
|
params: {
|
|
210
230
|
client_assertion: 'any.jwt.assertion',
|
|
211
231
|
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
|
|
@@ -224,7 +244,7 @@ describe Rack::OAuth2::Client do
|
|
|
224
244
|
mock_response(
|
|
225
245
|
:post,
|
|
226
246
|
'https://server.example.com/oauth2/token',
|
|
227
|
-
'tokens/bearer
|
|
247
|
+
'tokens/bearer',
|
|
228
248
|
params: {
|
|
229
249
|
client_id: 'client_id',
|
|
230
250
|
client_secret: 'client_secret',
|
|
@@ -242,7 +262,7 @@ describe Rack::OAuth2::Client do
|
|
|
242
262
|
mock_response(
|
|
243
263
|
:post,
|
|
244
264
|
'https://server.example.com/oauth2/token',
|
|
245
|
-
'tokens/bearer
|
|
265
|
+
'tokens/bearer',
|
|
246
266
|
params: {
|
|
247
267
|
client_id: 'client_id',
|
|
248
268
|
client_secret: 'client_secret',
|
|
@@ -262,7 +282,7 @@ describe Rack::OAuth2::Client do
|
|
|
262
282
|
mock_response(
|
|
263
283
|
:post,
|
|
264
284
|
'https://server.example.com/oauth2/token',
|
|
265
|
-
'tokens/bearer
|
|
285
|
+
'tokens/bearer',
|
|
266
286
|
params: {
|
|
267
287
|
grant_type: 'client_credentials',
|
|
268
288
|
scope: 'a b'
|
|
@@ -278,7 +298,7 @@ describe Rack::OAuth2::Client do
|
|
|
278
298
|
mock_response(
|
|
279
299
|
:post,
|
|
280
300
|
'https://server.example.com/oauth2/token',
|
|
281
|
-
'tokens/bearer
|
|
301
|
+
'tokens/bearer',
|
|
282
302
|
params: {
|
|
283
303
|
grant_type: 'client_credentials',
|
|
284
304
|
resource: 'something'
|
|
@@ -289,13 +309,30 @@ describe Rack::OAuth2::Client do
|
|
|
289
309
|
end
|
|
290
310
|
end
|
|
291
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
|
+
|
|
292
329
|
context 'when bearer token is given' do
|
|
293
330
|
before do
|
|
294
331
|
client.authorization_code = 'code'
|
|
295
332
|
mock_response(
|
|
296
333
|
:post,
|
|
297
334
|
'https://server.example.com/oauth2/token',
|
|
298
|
-
'tokens/bearer
|
|
335
|
+
'tokens/bearer'
|
|
299
336
|
)
|
|
300
337
|
end
|
|
301
338
|
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
|
@@ -310,7 +347,7 @@ describe Rack::OAuth2::Client do
|
|
|
310
347
|
mock_response(
|
|
311
348
|
:post,
|
|
312
349
|
'https://server.example.com/oauth2/token',
|
|
313
|
-
'tokens/_Bearer
|
|
350
|
+
'tokens/_Bearer'
|
|
314
351
|
)
|
|
315
352
|
end
|
|
316
353
|
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
|
@@ -318,112 +355,146 @@ describe Rack::OAuth2::Client do
|
|
|
318
355
|
end
|
|
319
356
|
end
|
|
320
357
|
|
|
321
|
-
context 'when
|
|
358
|
+
context 'when unknown-type token is given' do
|
|
322
359
|
before do
|
|
323
360
|
client.authorization_code = 'code'
|
|
324
361
|
mock_response(
|
|
325
362
|
:post,
|
|
326
363
|
'https://server.example.com/oauth2/token',
|
|
327
|
-
'tokens/
|
|
364
|
+
'tokens/unknown'
|
|
328
365
|
)
|
|
329
366
|
end
|
|
330
|
-
it
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
its(:refresh_token) { should == 'refresh_token' }
|
|
334
|
-
its(:expires_in) { should == 3600 }
|
|
367
|
+
it do
|
|
368
|
+
expect { client.access_token! }.to raise_error(StandardError, 'Unknown Token Type')
|
|
369
|
+
end
|
|
335
370
|
end
|
|
336
371
|
|
|
337
|
-
context 'when
|
|
372
|
+
context 'when error response is given' do
|
|
338
373
|
before do
|
|
339
|
-
client.authorization_code = 'code'
|
|
340
374
|
mock_response(
|
|
341
375
|
:post,
|
|
342
376
|
'https://server.example.com/oauth2/token',
|
|
343
|
-
'
|
|
377
|
+
'errors/invalid_request',
|
|
378
|
+
status: 400
|
|
344
379
|
)
|
|
345
380
|
end
|
|
346
|
-
it
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
its(:expires_in) { should == 3600 }
|
|
381
|
+
it do
|
|
382
|
+
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
|
|
383
|
+
end
|
|
384
|
+
end
|
|
351
385
|
|
|
352
|
-
|
|
386
|
+
context 'when no body given' do
|
|
387
|
+
context 'when error given' do
|
|
353
388
|
before do
|
|
354
|
-
|
|
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
|
|
355
399
|
end
|
|
356
|
-
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
|
357
|
-
its(:token_type) { should == :bearer }
|
|
358
400
|
end
|
|
359
401
|
end
|
|
402
|
+
end
|
|
360
403
|
|
|
361
|
-
|
|
362
|
-
|
|
404
|
+
describe '#revoke!' do
|
|
405
|
+
context 'local_http_config handling' do
|
|
406
|
+
it do
|
|
363
407
|
mock_response(
|
|
364
408
|
:post,
|
|
365
|
-
'https://server.example.com/oauth2/
|
|
366
|
-
'
|
|
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
|
+
}
|
|
367
421
|
)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
its(:token_type) { should == :legacy }
|
|
371
|
-
its(:access_token) { should == 'access_token' }
|
|
372
|
-
its(:expires_in) { should == 3600 }
|
|
373
|
-
|
|
374
|
-
context 'when expires_in is not given' do
|
|
375
|
-
before do
|
|
376
|
-
mock_response(
|
|
377
|
-
:post,
|
|
378
|
-
'https://server.example.com/oauth2/token',
|
|
379
|
-
'tokens/legacy_without_expires_in.txt'
|
|
380
|
-
)
|
|
422
|
+
client.revoke!(access_token: 'access_token') do |request|
|
|
423
|
+
request.headers['X-Foo'] = 'bar'
|
|
381
424
|
end
|
|
382
|
-
its(:expires_in) { should be_nil }
|
|
383
425
|
end
|
|
384
426
|
end
|
|
385
427
|
|
|
386
|
-
context 'when
|
|
428
|
+
context 'when access_token given' do
|
|
387
429
|
before do
|
|
388
|
-
client.authorization_code = 'code'
|
|
389
430
|
mock_response(
|
|
390
431
|
:post,
|
|
391
|
-
'https://server.example.com/oauth2/
|
|
392
|
-
'
|
|
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
|
+
}
|
|
393
440
|
)
|
|
394
441
|
end
|
|
395
442
|
it do
|
|
396
|
-
|
|
443
|
+
client.revoke!(access_token: 'access_token').should == :success
|
|
397
444
|
end
|
|
398
445
|
end
|
|
399
446
|
|
|
400
|
-
context 'when
|
|
447
|
+
context 'when refresh_token given' do
|
|
401
448
|
before do
|
|
402
449
|
mock_response(
|
|
403
450
|
:post,
|
|
404
|
-
'https://server.example.com/oauth2/
|
|
405
|
-
'
|
|
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',
|
|
406
482
|
status: 400
|
|
407
483
|
)
|
|
408
484
|
end
|
|
485
|
+
|
|
409
486
|
it do
|
|
410
|
-
expect
|
|
487
|
+
expect do
|
|
488
|
+
client.revoke! access_token: 'access_token'
|
|
489
|
+
end.to raise_error Rack::OAuth2::Client::Error
|
|
411
490
|
end
|
|
412
491
|
end
|
|
413
492
|
|
|
414
|
-
context 'when no
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
'https://server.example.com/oauth2/token',
|
|
420
|
-
'blank',
|
|
421
|
-
status: 400
|
|
422
|
-
)
|
|
423
|
-
end
|
|
424
|
-
it do
|
|
425
|
-
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
|
|
426
|
-
end
|
|
493
|
+
context 'when no token given' do
|
|
494
|
+
it do
|
|
495
|
+
expect do
|
|
496
|
+
client.revoke!
|
|
497
|
+
end.to raise_error ArgumentError
|
|
427
498
|
end
|
|
428
499
|
end
|
|
429
500
|
end
|
|
@@ -433,7 +504,8 @@ describe Rack::OAuth2::Client do
|
|
|
433
504
|
Rack::OAuth2::Client.new(
|
|
434
505
|
identifier: 'client_id',
|
|
435
506
|
secret: 'client_secret',
|
|
436
|
-
redirect_uri: 'https://client.example.com/callback'
|
|
507
|
+
redirect_uri: 'https://client.example.com/callback',
|
|
508
|
+
revocation_endpoint: '/oauth2/revoke'
|
|
437
509
|
)
|
|
438
510
|
end
|
|
439
511
|
|
|
@@ -448,5 +520,11 @@ describe Rack::OAuth2::Client do
|
|
|
448
520
|
expect { client.access_token! }.to raise_error 'No Host Info'
|
|
449
521
|
end
|
|
450
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
|
|
451
529
|
end
|
|
452
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
|