openid_connect 0.6.1 → 0.7.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.rdoc +3 -1
  4. data/VERSION +1 -1
  5. data/lib/openid_connect/access_token.rb +1 -2
  6. data/lib/openid_connect/client.rb +2 -6
  7. data/lib/openid_connect/client/registrar.rb +59 -123
  8. data/lib/openid_connect/discovery.rb +0 -2
  9. data/lib/openid_connect/discovery/provider.rb +3 -1
  10. data/lib/openid_connect/discovery/provider/config/response.rb +57 -78
  11. data/lib/openid_connect/request_object.rb +1 -8
  12. data/lib/openid_connect/request_object/{user_info.rb → userinfo.rb} +0 -0
  13. data/lib/openid_connect/response_object/id_token.rb +1 -1
  14. data/lib/openid_connect/response_object/userinfo.rb +3 -0
  15. data/lib/openid_connect/response_object/{user_info → userinfo}/open_id.rb +7 -6
  16. data/lib/openid_connect/response_object/{user_info → userinfo}/open_id/address.rb +0 -0
  17. data/openid_connect.gemspec +2 -2
  18. data/spec/helpers/webmock_helper.rb +2 -1
  19. data/spec/mock_response/discovery/config.json +3 -2
  20. data/spec/mock_response/public_keys/{jwk.json → jwks.json} +1 -1
  21. data/spec/mock_response/{user_info → userinfo}/openid.json +0 -0
  22. data/spec/openid_connect/access_token_spec.rb +7 -6
  23. data/spec/openid_connect/client/registrar_spec.rb +82 -207
  24. data/spec/openid_connect/client_spec.rb +2 -2
  25. data/spec/openid_connect/discovery/provider/config/response_spec.rb +53 -286
  26. data/spec/openid_connect/discovery/provider/config_spec.rb +11 -12
  27. data/spec/openid_connect/discovery/provider_spec.rb +1 -1
  28. data/spec/openid_connect/request_object_spec.rb +4 -4
  29. data/spec/openid_connect/response_object/id_token_spec.rb +4 -4
  30. data/spec/openid_connect/response_object/user_info/open_id_spec.rb +1 -0
  31. metadata +17 -20
  32. data/Gemfile.lock +0 -102
  33. data/lib/openid_connect/response_object/user_info.rb +0 -3
  34. data/spec/mock_response/public_keys/x509.pem +0 -21
@@ -19,11 +19,11 @@ describe OpenIDConnect::Client do
19
19
  end
20
20
  its(:authorization_uri) { should include 'https://server.example.com/oauth2/authorize' }
21
21
  its(:authorization_uri) { should include 'scope=openid' }
22
- its(:user_info_uri) { should == 'https://server.example.com/user_info' }
22
+ its(:userinfo_uri) { should == 'https://server.example.com/userinfo' }
23
23
  end
24
24
 
25
25
  context 'otherwise' do
26
- [:authorization_uri, :user_info_uri].each do |endpoint|
26
+ [:authorization_uri, :userinfo_uri].each do |endpoint|
27
27
  describe endpoint do
28
28
  it do
29
29
  expect { client.send endpoint }.to raise_error 'No Host Info'
@@ -4,311 +4,78 @@ describe OpenIDConnect::Discovery::Provider::Config::Response do
4
4
  let :instance do
5
5
  OpenIDConnect::Discovery::Provider::Config::Response.new attributes
6
6
  end
7
- let :attributes do
8
- {}
7
+ let :jwks_uri do
8
+ 'https://server.example.com/jwks.json'
9
9
  end
10
-
11
- describe '#as_json' do
12
- subject {
13
- instance.as_json
10
+ let :minimum_attributes do
11
+ {
12
+ issuer: 'https://server.example.com',
13
+ jwks_uri: jwks_uri,
14
+ response_types_supported: [
15
+ :code, :id_token, 'token id_token'
16
+ ],
17
+ subject_types_supported: [
18
+ :public, :pairwise
19
+ ],
20
+ id_token_signing_alg_values_supported: [
21
+ :RS256
22
+ ]
14
23
  }
24
+ end
25
+ let :attributes do
26
+ minimum_attributes
27
+ end
28
+ subject { instance }
15
29
 
16
- context 'when no attributes given' do
17
- it do
18
- should == {version: '3.0'}
19
- end
30
+ context 'when required attributes missing' do
31
+ let :attributes do
32
+ {}
20
33
  end
34
+ it { should_not be_valid }
35
+ end
21
36
 
22
- context 'when user_info_endpoint given' do
37
+ describe '#as_json' do
38
+ subject { instance.as_json }
39
+ it { should == minimum_attributes }
40
+ end
41
+
42
+ describe '#validate!' do
43
+ context 'when required attributes missing' do
23
44
  let :attributes do
24
- {user_info_endpoint: 'https://server.example.com/user_info'}
45
+ {}
25
46
  end
26
47
  it do
27
- should include :userinfo_endpoint
28
- end
29
- it do
30
- should_not include :user_info_endpoint
48
+ expect do
49
+ instance.validate!
50
+ end.to raise_error OpenIDConnect::ValidationFailed
31
51
  end
32
52
  end
33
53
 
34
- [
35
- :user_info_signing_alg_values_supported,
36
- :user_info_encryption_alg_values_supported,
37
- :user_info_encryption_enc_values_supported
38
- ].each do |key|
39
- context "when #{key} given" do
40
- let :attributes do
41
- {key => [:x, :y]}
42
- end
43
- it do
44
- should include key.to_s.sub('user_info', 'userinfo').to_sym
45
- end
46
- it do
47
- should_not include key
48
- end
54
+ context 'otherwise' do
55
+ it do
56
+ expect do
57
+ instance.validate!
58
+ end.not_to raise_error OpenIDConnect::ValidationFailed
49
59
  end
50
60
  end
51
61
  end
52
62
 
53
- describe '#signing_key and #encryption_key' do
54
- subject { config }
55
- let(:config) { instance }
56
- let(:attributes) do
57
- {
58
- x509_url: x509_url,
59
- x509_encryption_url: x509_encryption_url,
60
- jwk_url: jwk_url,
61
- jwk_encryption_url: jwk_encryption_url
62
- }.delete_if do |key, value|
63
- value.nil?
64
- end
65
- end
66
- let(:x509_url) { nil }
67
- let(:x509_encryption_url) { nil }
68
- let(:jwk_url) { nil }
69
- let(:jwk_encryption_url) { nil }
70
-
71
- context 'when x509_url is given' do
72
- let(:x509_url) { 'http://provider.example.com/x509.pem' }
73
-
74
- context 'when x509_encryption_url is given' do
75
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
76
-
77
- it 'should fetch signing_key from x509_url' do
78
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
79
- config.signing_key
80
- end
81
- end
82
-
83
- it 'should fetch encryption_key from x509_encryption_url' do
84
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
85
- config.encryption_key
86
- end
87
- end
88
- end
89
-
90
- context 'when jwk_encryption_url is given' do
91
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
92
-
93
- it 'should fetch signing_key from x509_url' do
94
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
95
- config.signing_key
96
- end
97
- end
98
-
99
- it 'should fetch encryption_key from jwk_encryption_url' do
100
- mock_json :get, jwk_encryption_url, 'public_keys/jwk' do
101
- config.encryption_key
102
- end
103
- end
104
- end
105
-
106
- context 'when both x509_encryption_url and jwk_encryption_url are given' do
107
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
108
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
109
-
110
- it 'should fetch signing_key from x509_url' do
111
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
112
- config.signing_key
113
- end
114
- end
115
-
116
- it 'should fetch encryption_key from x509_encryption_url' do
117
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
118
- config.encryption_key
119
- end
120
- end
121
- end
122
-
123
- context 'when neither x509_encryption_url nor jwk_encryption_url are given' do
124
- it 'should fetch signing_key from x509_url' do
125
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
126
- config.signing_key
127
- end
128
- end
129
-
130
- it 'should fetch encryption_key from x509_encryption_url' do
131
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
132
- config.encryption_key
133
- end
134
- end
135
- end
136
- end
137
-
138
- context 'when jwk_url is given' do
139
- let(:jwk_url) { 'http://provider.example.com/jwk.json' }
140
-
141
- context 'when x509_encryption_url is given' do
142
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
143
-
144
- it 'should fetch signing_key from jwk_url' do
145
- mock_json :get, jwk_url, 'public_keys/jwk' do
146
- config.signing_key
147
- end
148
- end
149
-
150
- it 'should fetch encryption_key from x509_encryption_url' do
151
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
152
- config.encryption_key
153
- end
154
- end
155
- end
156
-
157
- context 'when jwk_encryption_url is given' do
158
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
159
-
160
- it 'should fetch signing_key from jwk_url' do
161
- mock_json :get, jwk_url, 'public_keys/jwk' do
162
- config.signing_key
163
- end
164
- end
165
-
166
- it 'should fetch encryption_key from jwk_encryption_url' do
167
- mock_json :get, jwk_encryption_url, 'public_keys/jwk' do
168
- config.encryption_key
169
- end
170
- end
171
- end
172
-
173
- context 'when both x509_encryption_url and jwk_encryption_url are given' do
174
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
175
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
176
-
177
- it 'should fetch signing_key from jwk_url' do
178
- mock_json :get, jwk_url, 'public_keys/jwk' do
179
- config.signing_key
180
- end
181
- end
182
-
183
- it 'should fetch encryption_key from x509_encryption_url' do
184
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
185
- config.encryption_key
186
- end
187
- end
188
- end
189
-
190
- context 'when neither x509_encryption_url nor jwk_encryption_url are given' do
191
- it 'should fetch signing_key from jwk_url' do
192
- mock_json :get, jwk_url, 'public_keys/jwk' do
193
- config.signing_key
194
- end
195
- end
196
-
197
- it 'should fetch encryption_key from x509_encryption_url' do
198
- mock_json :get, jwk_url, 'public_keys/jwk' do
199
- config.encryption_key
200
- end
201
- end
202
- end
203
- end
204
-
205
- context 'when both x509_url and jwk_url are given' do
206
- let(:x509_url) { 'http://provider.example.com/cert.pem' }
207
- let(:jwk_url) { 'http://provider.example.com/jwk.json' }
208
-
209
- context 'when x509_encryption_url is given' do
210
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
211
-
212
- it 'should fetch signing_key from x509_url' do
213
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
214
- config.signing_key
215
- end
216
- end
217
-
218
- it 'should fetch encryption_key from x509_encryption_url' do
219
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
220
- config.encryption_key
221
- end
222
- end
223
- end
224
-
225
- context 'when jwk_encryption_url is given' do
226
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
227
-
228
- it 'should fetch signing_key from x509_url' do
229
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
230
- config.signing_key
231
- end
232
- end
233
-
234
- it 'should fetch encryption_key from jwk_encryption_url' do
235
- mock_json :get, jwk_encryption_url, 'public_keys/jwk' do
236
- config.encryption_key
237
- end
238
- end
239
- end
240
-
241
- context 'when both x509_encryption_url and jwk_encryption_url are given' do
242
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
243
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
244
-
245
- it 'should fetch signing_key from x509_url' do
246
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
247
- config.signing_key
248
- end
249
- end
250
-
251
- it 'should fetch encryption_key from x509_encryption_url' do
252
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
253
- config.encryption_key
254
- end
255
- end
256
- end
257
-
258
- context 'when neither x509_encryption_url nor jwk_encryption_url are given' do
259
- it 'should fetch signing_key from x509_url' do
260
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
261
- config.signing_key
262
- end
263
- end
264
-
265
- it 'should fetch encryption_key from x509_url' do
266
- mock_json :get, x509_url, 'public_keys/x509', format: :pem do
267
- config.encryption_key
268
- end
269
- end
63
+ describe '#jwks' do
64
+ it do
65
+ jwks = mock_json :get, jwks_uri, 'public_keys/jwks' do
66
+ instance.jwks
270
67
  end
68
+ jwks.should be_instance_of JSON::JWK::Set
271
69
  end
70
+ end
272
71
 
273
- context 'when neither x509_url nor jwk_url are given' do
274
- context 'when x509_encryption_url is given' do
275
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
276
- its(:signing_key) { should be_nil }
277
-
278
- it 'should fetch encryption_key from x509_encryption_url' do
279
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
280
- config.encryption_key
281
- end
282
- end
283
- end
284
-
285
- context 'when jwk_encryption_url is given' do
286
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
287
- its(:signing_key) { should be_nil }
288
-
289
- it 'should fetch encryption_key from jwk_encryption_url' do
290
- mock_json :get, jwk_encryption_url, 'public_keys/jwk' do
291
- config.encryption_key
292
- end
293
- end
294
- end
295
-
296
- context 'when both x509_encryption_url and jwk_encryption_url are given' do
297
- let(:x509_encryption_url) { 'http://provider.example.com/x509_encryption.pem' }
298
- let(:jwk_encryption_url) { 'http://provider.example.com/jwk_encryption.json' }
299
- its(:signing_key) { should be_nil }
300
-
301
- it 'should fetch encryption_key from x509_encryption_url' do
302
- mock_json :get, x509_encryption_url, 'public_keys/x509', format: :pem do
303
- config.encryption_key
304
- end
305
- end
306
- end
307
-
308
- context 'when neither x509_encryption_url nor jwk_encryption_url are given' do
309
- its(:signing_key) { should be_nil }
310
- its(:encryption_key) { should be_nil }
72
+ describe '#public_keys' do
73
+ it do
74
+ public_keys = mock_json :get, jwks_uri, 'public_keys/jwks' do
75
+ instance.public_keys
311
76
  end
77
+ public_keys.should be_instance_of Array
78
+ public_keys.first.should be_instance_of OpenSSL::PKey::RSA
312
79
  end
313
80
  end
314
81
  end
@@ -2,28 +2,27 @@ require 'spec_helper'
2
2
 
3
3
  describe OpenIDConnect::Discovery::Provider::Config do
4
4
  let(:provider) { 'https://connect-op.heroku.com' }
5
- let(:endpoint) { "https://connect-op.heroku.com/.well-known/openid-configuration" }
5
+ let(:endpoint) { 'https://connect-op.heroku.com/.well-known/openid-configuration' }
6
6
 
7
7
  describe 'discover!' do
8
8
  it 'should setup given attributes' do
9
9
  mock_json :get, endpoint, 'discovery/config' do
10
10
  config = OpenIDConnect::Discovery::Provider::Config.discover! provider
11
11
  config.should be_instance_of OpenIDConnect::Discovery::Provider::Config::Response
12
- config.version.should == '3.0'
13
12
  config.issuer.should == 'https://connect-op.heroku.com'
14
13
  config.authorization_endpoint.should == 'https://connect-op.heroku.com/authorizations/new'
15
14
  config.token_endpoint.should == 'https://connect-op.heroku.com/access_tokens'
16
- config.user_info_endpoint.should == 'https://connect-op.heroku.com/user_info'
17
- config.refresh_session_endpoint.should be_nil
15
+ config.userinfo_endpoint.should == 'https://connect-op.heroku.com/userinfo'
16
+ config.check_session_endpoint.should be_nil
18
17
  config.end_session_endpoint.should be_nil
19
- config.jwk_url.should be_nil
20
- config.x509_url.should == 'https://connect-op.heroku.com/cert.pem'
18
+ config.jwks_uri.should == 'https://connect-op.heroku.com/jwks.json'
21
19
  config.registration_endpoint.should == 'https://connect-op.heroku.com/connect/client'
22
- config.scopes_supported.should == ["openid", "profile", "email", "address"]
23
- config.response_types_supported.should == ["code", "token", "id_token", "code token", "code id_token", "id_token token"]
20
+ config.scopes_supported.should == ['openid', 'profile', 'email', 'address']
21
+ config.response_types_supported.should == ['code', 'token', 'id_token', 'code token', 'code id_token', 'id_token token']
24
22
  config.acr_values_supported.should be_nil
25
- config.subject_types_supported.should == ["public", "pairwise"]
26
- config.claims_supported.should == ["sub", "iss", "name", "email"]
23
+ config.subject_types_supported.should == ['public', 'pairwise']
24
+ config.claims_supported.should == ['sub', 'iss', 'name', 'email']
25
+ config.id_token_signing_alg_values_supported.should == ['RS256']
27
26
  end
28
27
  end
29
28
 
@@ -40,7 +39,7 @@ describe OpenIDConnect::Discovery::Provider::Config do
40
39
 
41
40
  context 'when OP identifier includes custom port' do
42
41
  let(:provider) { 'https://connect-op.heroku.com:8080' }
43
- let(:endpoint) { "https://connect-op.heroku.com:8080/.well-known/openid-configuration" }
42
+ let(:endpoint) { 'https://connect-op.heroku.com:8080/.well-known/openid-configuration' }
44
43
 
45
44
  it 'should construct well-known URI with given port' do
46
45
  mock_json :get, endpoint, 'discovery/config' do
@@ -51,7 +50,7 @@ describe OpenIDConnect::Discovery::Provider::Config do
51
50
 
52
51
  context 'when OP identifier includes path' do
53
52
  let(:provider) { 'https://connect.openid4.us/abop' }
54
- let(:endpoint) { "https://connect.openid4.us/abop/.well-known/openid-configuration" }
53
+ let(:endpoint) { 'https://connect.openid4.us/abop/.well-known/openid-configuration' }
55
54
 
56
55
  it 'should construct well-known URI with given port' do
57
56
  mock_json :get, endpoint, 'discovery/config' do
@@ -6,7 +6,7 @@ describe OpenIDConnect::Discovery::Provider do
6
6
  let(:endpoint) { "https://#{host}/.well-known/webfinger" }
7
7
  let(:query) do
8
8
  {
9
- rel: OpenIDConnect::Discovery::REL_VALUE,
9
+ rel: OpenIDConnect::Discovery::Provider::Issuer::REL_VALUE,
10
10
  resource: resource
11
11
  }
12
12
  end
@@ -93,15 +93,15 @@ describe OpenIDConnect::RequestObject do
93
93
 
94
94
  describe '#required?' do
95
95
  it do
96
- request_object.user_info.required?(:name).should be_true
97
- request_object.user_info.optional?(:name).should be_false
96
+ request_object.userinfo.required?(:name).should be_true
97
+ request_object.userinfo.optional?(:name).should be_false
98
98
  end
99
99
  end
100
100
 
101
101
  describe '#optional' do
102
102
  it do
103
- request_object.user_info.required?(:email).should be_false
104
- request_object.user_info.optional?(:email).should be_true
103
+ request_object.userinfo.required?(:email).should be_false
104
+ request_object.userinfo.optional?(:email).should be_true
105
105
  end
106
106
  end
107
107
  end