openid_connect 0.6.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/spec.yml +31 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +3 -1
- data/README.rdoc +10 -3
- data/Rakefile +6 -6
- data/TODOs +12 -0
- data/VERSION +1 -1
- data/lib/openid_connect/access_token/mtls.rb +9 -0
- data/lib/openid_connect/access_token.rb +14 -6
- data/lib/openid_connect/client/registrar.rb +69 -130
- data/lib/openid_connect/client.rb +7 -12
- data/lib/openid_connect/discovery/provider/config/resource.rb +5 -3
- data/lib/openid_connect/discovery/provider/config/response.rb +73 -78
- data/lib/openid_connect/discovery/provider/config.rb +5 -2
- data/lib/openid_connect/discovery/provider.rb +6 -2
- data/lib/openid_connect/discovery.rb +0 -2
- data/lib/openid_connect/jwtnizable.rb +6 -4
- data/lib/openid_connect/request_object/claimable.rb +4 -6
- data/lib/openid_connect/request_object.rb +6 -13
- data/lib/openid_connect/response_object/id_token.rb +38 -37
- data/lib/openid_connect/response_object/user_info/address.rb +10 -0
- data/lib/openid_connect/response_object/user_info.rb +64 -2
- data/lib/openid_connect.rb +26 -11
- data/lib/rack/oauth2/server/authorize/extension/code_and_id_token.rb +5 -1
- data/lib/rack/oauth2/server/authorize/extension/code_and_id_token_and_token.rb +1 -1
- data/lib/rack/oauth2/server/authorize/extension/id_token.rb +1 -1
- data/lib/rack/oauth2/server/authorize/extension/id_token_and_token.rb +1 -1
- data/lib/rack/oauth2/server/authorize/request_with_connect_params.rb +17 -14
- data/lib/rack/oauth2/server/id_token_response.rb +11 -13
- data/openid_connect.gemspec +19 -13
- data/spec/helpers/crypto_spec_helper.rb +2 -2
- data/spec/helpers/webmock_helper.rb +14 -9
- data/spec/mock_response/access_token/without_token_type.json +3 -0
- data/spec/mock_response/discovery/config.json +3 -3
- data/spec/mock_response/discovery/config_with_custom_port.json +13 -0
- data/spec/mock_response/discovery/config_with_invalid_issuer.json +13 -0
- data/spec/mock_response/discovery/config_with_path.json +13 -0
- data/spec/mock_response/discovery/config_without_issuer.json +12 -0
- data/spec/mock_response/errors/unknown.json +3 -1
- data/spec/mock_response/public_keys/{jwk.json → jwks.json} +1 -1
- data/spec/mock_response/public_keys/jwks_with_private_key.json +8 -0
- data/spec/mock_response/public_keys/private_key.pem +27 -0
- data/spec/openid_connect/access_token_spec.rb +11 -20
- data/spec/openid_connect/client/registrar_spec.rb +93 -208
- data/spec/openid_connect/client_spec.rb +79 -22
- data/spec/openid_connect/connect_object_spec.rb +1 -1
- data/spec/openid_connect/discovery/provider/config/response_spec.rb +76 -284
- data/spec/openid_connect/discovery/provider/config_spec.rb +64 -27
- data/spec/openid_connect/discovery/provider_spec.rb +2 -2
- data/spec/openid_connect/request_object_spec.rb +4 -4
- data/spec/openid_connect/response_object/id_token_spec.rb +94 -52
- data/spec/openid_connect/response_object/user_info/{open_id/address_spec.rb → address_spec.rb} +3 -3
- data/spec/openid_connect/response_object/{user_info/open_id_spec.rb → user_info_spec.rb} +13 -12
- data/spec/openid_connect_spec.rb +19 -19
- data/spec/rack/oauth2/server/authorize/extension/code_and_id_token_and_token_spec.rb +11 -0
- data/spec/rack/oauth2/server/authorize/extension/code_and_id_token_spec.rb +11 -0
- data/spec/rack/oauth2/server/authorize/extension/id_token_and_token_spec.rb +11 -0
- data/spec/rack/oauth2/server/authorize/extension/id_token_spec.rb +1 -1
- data/spec/rack/oauth2/server/authorize/request_with_connect_params_spec.rb +45 -0
- data/spec/spec_helper.rb +12 -1
- metadata +155 -90
- data/.travis.yml +0 -3
- data/Gemfile.lock +0 -102
- data/lib/openid_connect/debugger/request_filter.rb +0 -28
- data/lib/openid_connect/debugger.rb +0 -3
- data/lib/openid_connect/response_object/user_info/open_id/address.rb +0 -12
- data/lib/openid_connect/response_object/user_info/open_id.rb +0 -64
- data/lib/rack/oauth2/server/resource/error_with_connect_ext.rb +0 -14
- data/spec/mock_response/public_keys/x509.pem +0 -21
- data/spec/openid_connect/debugger/request_filter_spec.rb +0 -33
- data/spec/rack/oauth2/server/resource/error_with_connect_ext_spec.rb +0 -12
- /data/spec/mock_response/{user_info → userinfo}/openid.json +0 -0
@@ -19,7 +19,20 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
19
19
|
describe 'attributes' do
|
20
20
|
subject { klass }
|
21
21
|
its(:required_attributes) { should == [:iss, :sub, :aud, :exp, :iat] }
|
22
|
-
its(:optional_attributes) { should == [:acr, :auth_time, :nonce, :sub_jwk, :at_hash, :c_hash] }
|
22
|
+
its(:optional_attributes) { should == [:acr, :amr, :azp, :jti, :sid, :auth_time, :nonce, :sub_jwk, :at_hash, :c_hash, :s_hash] }
|
23
|
+
|
24
|
+
describe 'auth_time' do
|
25
|
+
subject { id_token.auth_time }
|
26
|
+
|
27
|
+
context 'when Time object given' do
|
28
|
+
let(:attributes) do
|
29
|
+
required_attributes.merge(auth_time: Time.now)
|
30
|
+
end
|
31
|
+
it do
|
32
|
+
should be_a Numeric
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
23
36
|
end
|
24
37
|
|
25
38
|
describe '#verify!' do
|
@@ -28,7 +41,18 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
28
41
|
id_token.verify!(
|
29
42
|
issuer: attributes[:iss],
|
30
43
|
client_id: attributes[:aud]
|
31
|
-
).should
|
44
|
+
).should == true
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when aud(ience) is an array of identifiers' do
|
48
|
+
let(:client_id) { 'client_id' }
|
49
|
+
let(:attributes) { required_attributes.merge(aud: ['some_other_identifier', client_id]) }
|
50
|
+
it do
|
51
|
+
id_token.verify!(
|
52
|
+
issuer: attributes[:iss],
|
53
|
+
client_id: client_id
|
54
|
+
).should == true
|
55
|
+
end
|
32
56
|
end
|
33
57
|
|
34
58
|
context 'when expired' do
|
@@ -95,7 +119,7 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
95
119
|
issuer: attributes[:iss],
|
96
120
|
client_id: attributes[:aud],
|
97
121
|
nonce: attributes[:nonce]
|
98
|
-
).should
|
122
|
+
).should == true
|
99
123
|
end
|
100
124
|
end
|
101
125
|
|
@@ -133,7 +157,7 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
133
157
|
t = id_token.to_jwt private_key do |t|
|
134
158
|
t.header[:x5u] = "http://server.example.com/x5u"
|
135
159
|
end
|
136
|
-
h =
|
160
|
+
h = Base64.urlsafe_decode64 t.split('.').first
|
137
161
|
h.should include 'x5u'
|
138
162
|
end
|
139
163
|
end
|
@@ -145,8 +169,9 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
145
169
|
jwt = JSON::JWT.decode t, public_key
|
146
170
|
jwt.should include :at_hash
|
147
171
|
jwt.should_not include :c_hash
|
148
|
-
jwt[:at_hash].should ==
|
149
|
-
OpenSSL::Digest::SHA256.digest('access_token')[0, 128 / 8]
|
172
|
+
jwt[:at_hash].should == Base64.urlsafe_encode64(
|
173
|
+
OpenSSL::Digest::SHA256.digest('access_token')[0, 128 / 8],
|
174
|
+
padding: false
|
150
175
|
)
|
151
176
|
end
|
152
177
|
end
|
@@ -169,8 +194,9 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
169
194
|
jwt = JSON::JWT.decode t, public_key
|
170
195
|
jwt.should_not include :at_hash
|
171
196
|
jwt.should include :c_hash
|
172
|
-
jwt[:c_hash].should ==
|
173
|
-
OpenSSL::Digest::SHA256.digest('authorization_code')[0, 128 / 8]
|
197
|
+
jwt[:c_hash].should == Base64.urlsafe_encode64(
|
198
|
+
OpenSSL::Digest::SHA256.digest('authorization_code')[0, 128 / 8],
|
199
|
+
padding: false
|
174
200
|
)
|
175
201
|
end
|
176
202
|
end
|
@@ -185,11 +211,13 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
185
211
|
jwt = JSON::JWT.decode t, public_key
|
186
212
|
jwt.should include :at_hash
|
187
213
|
jwt.should include :c_hash
|
188
|
-
jwt[:at_hash].should ==
|
189
|
-
OpenSSL::Digest::SHA256.digest('access_token')[0, 128 / 8]
|
214
|
+
jwt[:at_hash].should == Base64.urlsafe_encode64(
|
215
|
+
OpenSSL::Digest::SHA256.digest('access_token')[0, 128 / 8],
|
216
|
+
padding: false
|
190
217
|
)
|
191
|
-
jwt[:c_hash].should ==
|
192
|
-
OpenSSL::Digest::SHA256.digest('authorization_code')[0, 128 / 8]
|
218
|
+
jwt[:c_hash].should == Base64.urlsafe_encode64(
|
219
|
+
OpenSSL::Digest::SHA256.digest('authorization_code')[0, 128 / 8],
|
220
|
+
padding: false
|
193
221
|
)
|
194
222
|
end
|
195
223
|
end
|
@@ -221,11 +249,60 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
221
249
|
its(key) { should == attributes[key] }
|
222
250
|
end
|
223
251
|
its(:exp) { should == attributes[:exp].to_i }
|
252
|
+
its(:raw_attributes) { should be_instance_of JSON::JWS }
|
253
|
+
|
254
|
+
context 'when IdP config is given' do
|
255
|
+
subject { klass.decode id_token.to_jwt(private_key), idp_config }
|
256
|
+
let(:jwks) do
|
257
|
+
jwk_str = File.read(File.join(__dir__, '../../mock_response/public_keys/jwks_with_private_key.json'))
|
258
|
+
jwk = JSON::JWK::Set.new JSON.parse(jwk_str)
|
259
|
+
end
|
260
|
+
let(:idp_config) do
|
261
|
+
OpenIDConnect::Discovery::Provider::Config::Response.new(
|
262
|
+
issuer: attributes[:issuer],
|
263
|
+
authorization_endpoint: File.join(attributes[:iss], 'authorize'),
|
264
|
+
jwks_uri: File.join(attributes[:iss], 'jwks'),
|
265
|
+
response_types_supported: ['code'],
|
266
|
+
subject_types_supported: ['public'],
|
267
|
+
id_token_signing_alg_values_supported: ['RS256']
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'when id_token has kid' do
|
272
|
+
let(:private_key) do
|
273
|
+
OpenSSL::PKey::RSA.new(
|
274
|
+
File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem'))
|
275
|
+
).to_jwk
|
276
|
+
end
|
277
|
+
|
278
|
+
it do
|
279
|
+
mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do
|
280
|
+
should be_a klass
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
context 'otherwise' do
|
286
|
+
let(:private_key) do
|
287
|
+
OpenSSL::PKey::RSA.new(
|
288
|
+
File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem'))
|
289
|
+
)
|
290
|
+
end
|
291
|
+
|
292
|
+
it do
|
293
|
+
mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do
|
294
|
+
expect do
|
295
|
+
should
|
296
|
+
end.to raise_error JSON::JWK::Set::KidNotFound
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
224
301
|
|
225
302
|
context 'when self-issued' do
|
226
303
|
context 'when valid' do
|
227
304
|
let(:self_issued) do
|
228
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.
|
305
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlbGYtaXNzdWVkLm1lIiwic3ViIjoiMmdDUWFLUmJkY0RaeUlDTE92ODJJR2EtdHBSVU52QW1ZN3BnZ3Z5NGdENCIsImF1ZCI6ImNsaWVudC5leGFtcGxlLmNvbSIsImV4cCI6MTQ0MjQ4Mjc4MiwiaWF0IjoxNDQxODc3OTgyLCJzdWJfandrIjp7Imt0eSI6IlJTQSIsImUiOiJBUUFCIiwibiI6IjN1RzNiSTV6MTFhM1hlOXUyZFVJNDBpcWZrVl9vTmFQVmNlalN4V3l0YnMybTZKMGMzNjJESlJQNGtyUl9TZjNtQXJ3Qjd6Qm5UWExkbW1tZW85VzloSDhsSnFGOUthMTY3dHBTQWJCajB1MjhyaTgwZFZ4NUxzblJTX19uUUd6Y3dNa2sxTTBERUx2X0FXbVYwU2JudDhJZEpSeFhwdG5xRE5tWXJ0cmItMkk0a1lwRHlwN2pvTXd0bDNXeGp2cnkwbENLNExqOU9SeXdod05zYUU2MHFsako5aHBGZV8wTmpmaThzaVBlMDRJSkFaUjl3NXo0TnAtQS1HbWdmeTNJTmNZVFYyQ25FekNSY29HSGl5OGduRzA1a015TnRtZTFVdV8xanBhdF9lcF9QUG9PWEJ6Q1NwbzB5QlRNSWhmdEJTQ3p2a2V1ZFdhNks2aW5LMkYxdyJ9fQ.wchF80oFxdjEcOEwPZ9TUlV6R96Vz8XK9MzednMOsZmEMnNSEqKKTyO0Mhp9lijJPZX8J7lTtAGkz4gfsjyoYBIHQOTf0qHRHSx9RTeC31whw1TJ9x5V6UXpKN0EW1EhjAEGIZ0EyFJ-cRTgVs0V7PT7e63JOUYyW6LqqHa4MV9SdK8BdnaN0D4-402Pf7yFqjneSHq3KZbXcgjUPT_hszsGvnn9qEyuIHQqON6YnDt55z5SvP_RfKtBfUe2VY-yglJT41LfhkIgpvjLYdYYRPh9G9ftJr17qht5RtHSNpTp4FPw7BR7rCnptb4xTxyq-sLu7qjSLRtqQ35Xpi_6qQ'
|
229
306
|
end
|
230
307
|
|
231
308
|
context 'when key == :self_issued' do
|
@@ -247,7 +324,7 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
247
324
|
|
248
325
|
context 'when invalid subject' do
|
249
326
|
let(:self_issued) do
|
250
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.
|
327
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlbGYtaXNzdWVkLm1lIiwic3ViIjoiUFdFYXFfVnlUd1hTSFR4QVlSZHdWTjNMN2s0UnNxOVBwaTZ4WHZ6ZGZWTSIsImF1ZCI6InRhcGlkLnRhcGlkZW50aXR5LmNvbSIsImV4cCI6MTM2MjI3OTkwMCwiaWF0IjoxMzYyMjc2MzAwLCJzdWJfandrIjp7Imt0eSI6IlJTQSIsImUiOiJBUUFCIiwibiI6IjRGTWl5M08zbFlOd2RzeC15aXVjemRsek81eU11d1p4WFlzSDgydmM0RkM0QXgyMGpNVV94emJHSUhWVUtFQ0pndFp3clBlajhRSWUtZFZFYXQtaGxjNTB5TXluM0h3cmtJVjVZOTdET1E2Sks4azk2QTFqVWxPLW5sRjl4ZUx2VDlwYTJXRTZtYm1KOG5EQW5mR0d6bmRNd3VKNzVLZDI2YmZHY21wcm5qUUJLTkVrakdJbW9MMEhFODFUcjROeC1tN1lsYkRGaVFNRDVpYjhCY3N4S0tvMTZTeG5tSi1EeUY2c094Y2JtV1ZrdkZBa3FKWFBnVFVoNXVYT3YwYk9nN0I2d2RHdUMtWnpJUl8tdUx3YlcxN2V4NGx3ZTFPb0ppdFJ3SFczYlo3NEc3RkdoSmhfTUp4YzB3WXBkbW5uNVpjRFFOWl9sWVRvMHYzaU1PUWk3USJ9fQ.DZKaSne22DjKFSpSUphsTeCMkcMWDexQCm8BPb1nI1PzQYsEAOfwumDajt85UA0x28y2zuOevMj29VpwTzbpRDkduv2NWAI4MHw8DYEsIN__-QGANmdU1sKmthET2iFmeFySwWomLqFvYIaNmVYVLkD53Zqfct5qH3Wznd_hrK8T1d6Cxg-gyZlAeqEu2V8EL2yuz8Gdaeze4b78l5Ux-B_5FQhZ3UkXbL1B2gzKJQVKAQdFJb9zUfzmCeIiUmeM9mw_VU64tAvFDRiTKS1P6b62Gxuyx1DhMLFg2evDaTJERJOta9ywtPfdcLH3qcIiUBffP2-FnAz44bOlKzJorQ'
|
251
328
|
end
|
252
329
|
|
253
330
|
it do
|
@@ -286,43 +363,8 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
286
363
|
[:iss, :sub, :aud, :exp, :iat, :sub_jwk].each do |attribute|
|
287
364
|
its(attribute) { should be_present }
|
288
365
|
end
|
289
|
-
its(:iss)
|
366
|
+
its(:iss) { should == 'https://self-issued.me' }
|
290
367
|
its(:sub_jwk) { should == sub_jwk}
|
291
|
-
its(:subject)
|
292
|
-
end
|
293
|
-
|
294
|
-
describe '.self_issued_subject' do
|
295
|
-
context 'when RSA key given' do
|
296
|
-
let(:jwk) { JSON::JWK.new(public_key) }
|
297
|
-
it do
|
298
|
-
user_id = klass.self_issued_subject jwk
|
299
|
-
user_id.should == UrlSafeBase64.encode64(
|
300
|
-
OpenSSL::Digest::SHA256.digest([jwk[:n], jwk[:e]].join)
|
301
|
-
)
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
context 'when EC key given' do
|
306
|
-
let(:jwk) { JSON::JWK.new(ec_public_key) }
|
307
|
-
it do
|
308
|
-
expect do
|
309
|
-
klass.self_issued_subject jwk
|
310
|
-
end.to raise_error NotImplementedError
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
context 'when unknown algorithm JWK given' do
|
315
|
-
let(:jwk) do
|
316
|
-
{
|
317
|
-
alg: 'unknown'
|
318
|
-
}
|
319
|
-
end
|
320
|
-
|
321
|
-
it do
|
322
|
-
expect do
|
323
|
-
klass.self_issued_subject jwk
|
324
|
-
end.to raise_error OpenIDConnect::ResponseObject::IdToken::InvalidToken
|
325
|
-
end
|
326
|
-
end
|
368
|
+
its(:subject) { should == sub_jwk.thumbprint }
|
327
369
|
end
|
328
|
-
end
|
370
|
+
end
|
data/spec/openid_connect/response_object/user_info/{open_id/address_spec.rb → address_spec.rb}
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe OpenIDConnect::ResponseObject::UserInfo::
|
4
|
-
let(:klass) { OpenIDConnect::ResponseObject::UserInfo::
|
3
|
+
describe OpenIDConnect::ResponseObject::UserInfo::Address do
|
4
|
+
let(:klass) { OpenIDConnect::ResponseObject::UserInfo::Address }
|
5
5
|
|
6
6
|
describe 'attributes' do
|
7
7
|
subject { klass }
|
@@ -20,7 +20,7 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID::Address do
|
|
20
20
|
let :attributes do
|
21
21
|
{}
|
22
22
|
end
|
23
|
-
its(:valid?) { should
|
23
|
+
its(:valid?) { should == false }
|
24
24
|
its(:errors) { should include :base }
|
25
25
|
end
|
26
26
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe OpenIDConnect::ResponseObject::UserInfo
|
4
|
-
let(:klass) { OpenIDConnect::ResponseObject::UserInfo
|
3
|
+
describe OpenIDConnect::ResponseObject::UserInfo do
|
4
|
+
let(:klass) { OpenIDConnect::ResponseObject::UserInfo }
|
5
5
|
let(:instance) { klass.new attributes }
|
6
6
|
subject { instance }
|
7
7
|
|
@@ -27,8 +27,9 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
27
27
|
:zoneinfo,
|
28
28
|
:locale,
|
29
29
|
:phone_number,
|
30
|
+
:phone_number_verified,
|
30
31
|
:address,
|
31
|
-
:
|
32
|
+
:updated_at
|
32
33
|
]
|
33
34
|
end
|
34
35
|
end
|
@@ -44,7 +45,7 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
44
45
|
let :attributes do
|
45
46
|
{}
|
46
47
|
end
|
47
|
-
its(:valid?) { should
|
48
|
+
its(:valid?) { should == false }
|
48
49
|
its(:errors) { should include :base }
|
49
50
|
end
|
50
51
|
|
@@ -52,16 +53,16 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
52
53
|
let :attributes do
|
53
54
|
{email: 'nov@localhost'}
|
54
55
|
end
|
55
|
-
its(:valid?) { should
|
56
|
+
its(:valid?) { should == false }
|
56
57
|
its(:errors) { should include :email }
|
57
58
|
end
|
58
59
|
|
59
|
-
[:email_verified, :
|
60
|
+
[:email_verified, :zoneinfo].each do |one_of_list|
|
60
61
|
context "when #{one_of_list} is invalid" do
|
61
62
|
let :attributes do
|
62
63
|
{one_of_list => 'Out of List'}
|
63
64
|
end
|
64
|
-
its(:valid?) { should
|
65
|
+
its(:valid?) { should == false }
|
65
66
|
its(:errors) { should include one_of_list }
|
66
67
|
end
|
67
68
|
end
|
@@ -75,7 +76,7 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
75
76
|
let :attributes do
|
76
77
|
{url => 'Invalid'}
|
77
78
|
end
|
78
|
-
its(:valid?) { should
|
79
|
+
its(:valid?) { should == false }
|
79
80
|
its(:errors) { should include url }
|
80
81
|
end
|
81
82
|
end
|
@@ -84,7 +85,7 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
84
85
|
let :attributes do
|
85
86
|
{address: {}}
|
86
87
|
end
|
87
|
-
its(:valid?) { should
|
88
|
+
its(:valid?) { should == false }
|
88
89
|
its(:errors) { should include :address }
|
89
90
|
end
|
90
91
|
end
|
@@ -94,14 +95,14 @@ describe OpenIDConnect::ResponseObject::UserInfo::OpenID do
|
|
94
95
|
let :attributes do
|
95
96
|
{address: {}}
|
96
97
|
end
|
97
|
-
its(:address) { should be_a OpenIDConnect::ResponseObject::UserInfo::
|
98
|
+
its(:address) { should be_a OpenIDConnect::ResponseObject::UserInfo::Address }
|
98
99
|
end
|
99
100
|
|
100
101
|
context 'when Address is given' do
|
101
102
|
let :attributes do
|
102
|
-
{address: OpenIDConnect::ResponseObject::UserInfo::
|
103
|
+
{address: OpenIDConnect::ResponseObject::UserInfo::Address.new}
|
103
104
|
end
|
104
|
-
its(:address) { should be_a OpenIDConnect::ResponseObject::UserInfo::
|
105
|
+
its(:address) { should be_a OpenIDConnect::ResponseObject::UserInfo::Address }
|
105
106
|
end
|
106
107
|
end
|
107
108
|
|
data/spec/openid_connect_spec.rb
CHANGED
@@ -4,24 +4,24 @@ describe OpenIDConnect do
|
|
4
4
|
after { OpenIDConnect.debugging = false }
|
5
5
|
|
6
6
|
its(:logger) { should be_a Logger }
|
7
|
-
its(:debugging?) { should
|
7
|
+
its(:debugging?) { should == false }
|
8
8
|
|
9
9
|
describe '.debug!' do
|
10
10
|
before { OpenIDConnect.debug! }
|
11
|
-
its(:debugging?) { should
|
11
|
+
its(:debugging?) { should == true }
|
12
12
|
end
|
13
13
|
|
14
14
|
describe '.debug' do
|
15
15
|
it 'should enable debugging within given block' do
|
16
16
|
OpenIDConnect.debug do
|
17
|
-
SWD.debugging?.should
|
18
|
-
WebFinger.debugging?.should
|
19
|
-
Rack::OAuth2.debugging?.should
|
20
|
-
OpenIDConnect.debugging?.should
|
17
|
+
SWD.debugging?.should == true
|
18
|
+
WebFinger.debugging?.should == true
|
19
|
+
Rack::OAuth2.debugging?.should == true
|
20
|
+
OpenIDConnect.debugging?.should == true
|
21
21
|
end
|
22
|
-
SWD.debugging?.should
|
23
|
-
Rack::OAuth2.debugging?.should
|
24
|
-
OpenIDConnect.debugging?.should
|
22
|
+
SWD.debugging?.should == false
|
23
|
+
Rack::OAuth2.debugging?.should == false
|
24
|
+
OpenIDConnect.debugging?.should == false
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should not force disable debugging' do
|
@@ -30,15 +30,15 @@ describe OpenIDConnect do
|
|
30
30
|
Rack::OAuth2.debug!
|
31
31
|
OpenIDConnect.debug!
|
32
32
|
OpenIDConnect.debug do
|
33
|
-
SWD.debugging?.should
|
34
|
-
WebFinger.debugging?.should
|
35
|
-
Rack::OAuth2.debugging?.should
|
36
|
-
OpenIDConnect.debugging?.should
|
33
|
+
SWD.debugging?.should == true
|
34
|
+
WebFinger.debugging?.should == true
|
35
|
+
Rack::OAuth2.debugging?.should == true
|
36
|
+
OpenIDConnect.debugging?.should == true
|
37
37
|
end
|
38
|
-
SWD.debugging?.should
|
39
|
-
WebFinger.debugging?.should
|
40
|
-
Rack::OAuth2.debugging?.should
|
41
|
-
OpenIDConnect.debugging?.should
|
38
|
+
SWD.debugging?.should == true
|
39
|
+
WebFinger.debugging?.should == true
|
40
|
+
Rack::OAuth2.debugging?.should == true
|
41
|
+
OpenIDConnect.debugging?.should == true
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -46,12 +46,12 @@ describe OpenIDConnect do
|
|
46
46
|
context 'with http_config' do
|
47
47
|
before do
|
48
48
|
OpenIDConnect.http_config do |config|
|
49
|
-
config.
|
49
|
+
config.ssl.verify = false
|
50
50
|
end
|
51
51
|
end
|
52
52
|
it 'should configure OpenIDConnect, SWD and Rack::OAuth2\'s http_client' do
|
53
53
|
[OpenIDConnect, SWD, WebFinger, Rack::OAuth2].each do |klass|
|
54
|
-
klass.http_client.
|
54
|
+
klass.http_client.ssl.verify.should be_falsy
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -53,4 +53,15 @@ describe Rack::OAuth2::Server::Authorize::Extension::CodeAndIdTokenAndToken do
|
|
53
53
|
expect { response }.to raise_error AttrRequired::AttrMissing, "'access_token', 'code', 'id_token' required."
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
context 'when error response' do
|
58
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
|
59
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Extension::CodeAndIdTokenAndToken::Request.new env }
|
60
|
+
|
61
|
+
it 'should set protocol_params_location = :fragment' do
|
62
|
+
expect { request.bad_request! }.to raise_error(Rack::OAuth2::Server::Authorize::BadRequest) { |e|
|
63
|
+
e.protocol_params_location.should == :fragment
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
56
67
|
end
|
@@ -50,4 +50,15 @@ describe Rack::OAuth2::Server::Authorize::Extension::CodeAndIdToken do
|
|
50
50
|
expect { response }.to raise_error AttrRequired::AttrMissing, "'id_token' required."
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
context 'when error response' do
|
55
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
|
56
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Extension::CodeAndIdToken::Request.new env }
|
57
|
+
|
58
|
+
it 'should set protocol_params_location = :fragment' do
|
59
|
+
expect { request.bad_request! }.to raise_error(Rack::OAuth2::Server::Authorize::BadRequest) { |e|
|
60
|
+
e.protocol_params_location.should == :fragment
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
53
64
|
end
|
@@ -51,4 +51,15 @@ describe Rack::OAuth2::Server::Authorize::Extension::IdTokenAndToken do
|
|
51
51
|
expect { response }.to raise_error AttrRequired::AttrMissing, "'id_token' required."
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
context 'when error response' do
|
56
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
|
57
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Extension::IdTokenAndToken::Request.new env }
|
58
|
+
|
59
|
+
it 'should set protocol_params_location = :fragment' do
|
60
|
+
expect { request.bad_request! }.to raise_error(Rack::OAuth2::Server::Authorize::BadRequest) { |e|
|
61
|
+
e.protocol_params_location.should == :fragment
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
54
65
|
end
|
@@ -62,7 +62,7 @@ describe Rack::OAuth2::Server::Authorize::Extension::IdToken do
|
|
62
62
|
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id&scope=openid") }
|
63
63
|
let(:request) { Rack::OAuth2::Server::Authorize::Extension::IdToken::Request.new env }
|
64
64
|
it do
|
65
|
-
request.openid_connect_request?.should
|
65
|
+
request.openid_connect_request?.should == true
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack::OAuth2::Server::Authorize::RequestWithConnectParams do
|
4
|
+
let(:base_params) do
|
5
|
+
{
|
6
|
+
client_id: 'client_id',
|
7
|
+
redirect_uri: 'https://client.example.com/callback'
|
8
|
+
}
|
9
|
+
end
|
10
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?#{base_params.to_query}&#{params.to_query}") }
|
11
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
|
12
|
+
subject { request }
|
13
|
+
|
14
|
+
describe 'prompt' do
|
15
|
+
context 'when a space-delimited string given' do
|
16
|
+
let(:params) do
|
17
|
+
{prompt: 'login consent'}
|
18
|
+
end
|
19
|
+
its(:prompt) { should == ['login', 'consent']}
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when a single string given' do
|
23
|
+
let(:params) do
|
24
|
+
{prompt: 'login'}
|
25
|
+
end
|
26
|
+
its(:prompt) { should == ['login']}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'max_age' do
|
31
|
+
context 'when numeric value given' do
|
32
|
+
let(:params) do
|
33
|
+
{max_age: '5'}
|
34
|
+
end
|
35
|
+
its(:max_age) { should == 5}
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when non-numeric string given' do
|
39
|
+
let(:params) do
|
40
|
+
{max_age: 'foo'}
|
41
|
+
end
|
42
|
+
its(:max_age) { should == 0}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
|
-
require '
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter 'spec'
|
5
|
+
end
|
2
6
|
|
3
7
|
require 'rspec'
|
8
|
+
require 'rspec/its'
|
4
9
|
require 'openid_connect'
|
5
10
|
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.expect_with :rspec do |c|
|
13
|
+
c.syntax = [:should, :expect]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
require 'helpers/crypto_spec_helper'
|
7
18
|
require 'helpers/webmock_helper'
|