openid_connect 0.2.1 → 0.2.2
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.
- data/.travis.yml +1 -2
- data/Gemfile.lock +1 -2
- data/VERSION +1 -1
- data/lib/openid_connect/access_token.rb +0 -8
- data/lib/openid_connect/client.rb +1 -6
- data/lib/openid_connect/client/registrar.rb +19 -7
- data/lib/openid_connect/discovery/principal.rb +1 -4
- data/lib/openid_connect/discovery/provider/config/response.rb +0 -1
- data/lib/openid_connect/response_object/id_token.rb +3 -11
- data/spec/mock_response/client/registered.json +1 -1
- data/spec/mock_response/client/rotated.json +5 -0
- data/spec/mock_response/client/updated.json +1 -3
- data/spec/mock_response/discovery/config.json +0 -1
- data/spec/openid_connect/access_token_spec.rb +0 -14
- data/spec/openid_connect/client/registrar_spec.rb +28 -5
- data/spec/openid_connect/client_spec.rb +1 -2
- data/spec/openid_connect/discovery/principal_spec.rb +1 -3
- data/spec/openid_connect/discovery/provider/config_spec.rb +0 -1
- data/spec/openid_connect/response_object/id_token_spec.rb +7 -32
- metadata +3 -4
- data/lib/openid_connect/discovery/principal/xri.rb +0 -15
- data/spec/openid_connect/discovery/principal/xri_spec.rb +0 -5
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openid_connect (0.2.
|
4
|
+
openid_connect (0.2.1)
|
5
5
|
activemodel (>= 3)
|
6
6
|
attr_required (>= 0.0.5)
|
7
7
|
json (>= 1.4.3)
|
@@ -38,7 +38,6 @@ GEM
|
|
38
38
|
jruby-openssl (0.7.7)
|
39
39
|
bouncy-castle-java (>= 1.5.0146.1)
|
40
40
|
json (1.7.3)
|
41
|
-
json (1.7.3-java)
|
42
41
|
json-jwt (0.0.7)
|
43
42
|
activesupport (>= 2.3)
|
44
43
|
i18n
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
@@ -15,14 +15,6 @@ module OpenIDConnect
|
|
15
15
|
ResponseObject::UserInfo::OpenID.new hash
|
16
16
|
end
|
17
17
|
|
18
|
-
def id_token!
|
19
|
-
client.check_id_uri
|
20
|
-
hash = resource_request do
|
21
|
-
get client.check_id_uri
|
22
|
-
end
|
23
|
-
ResponseObject::IdToken.new hash
|
24
|
-
end
|
25
|
-
|
26
18
|
private
|
27
19
|
|
28
20
|
def resource_request
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module OpenIDConnect
|
2
2
|
class Client < Rack::OAuth2::Client
|
3
|
-
attr_optional :
|
3
|
+
attr_optional :user_info_endpoint, :expires_in
|
4
4
|
|
5
5
|
def initialize(attributes = {})
|
6
6
|
super
|
7
7
|
@user_info_endpoint ||= '/user_info'
|
8
|
-
@check_id_endpoint ||= '/id_token'
|
9
8
|
end
|
10
9
|
|
11
10
|
def authorization_uri(params = {})
|
@@ -14,10 +13,6 @@ module OpenIDConnect
|
|
14
13
|
super
|
15
14
|
end
|
16
15
|
|
17
|
-
def check_id_uri
|
18
|
-
absolute_uri_for check_id_endpoint
|
19
|
-
end
|
20
|
-
|
21
16
|
def user_info_uri
|
22
17
|
absolute_uri_for user_info_endpoint
|
23
18
|
end
|
@@ -22,14 +22,21 @@ module OpenIDConnect
|
|
22
22
|
:sector_identifier_url,
|
23
23
|
:user_id_type,
|
24
24
|
:require_signed_request_object,
|
25
|
+
:userinfo_signed_response_alg,
|
26
|
+
:userinfo_encrypted_response_alg,
|
27
|
+
:userinfo_encrypted_response_enc,
|
28
|
+
:userinfo_encrypted_response_int,
|
29
|
+
:id_token_signed_response_alg,
|
30
|
+
:id_token_encrypted_response_alg,
|
31
|
+
:id_token_encrypted_response_enc,
|
32
|
+
:id_token_encrypted_response_int,
|
33
|
+
:default_max_age,
|
34
|
+
:require_auth_time,
|
35
|
+
:default_acr
|
25
36
|
]
|
26
37
|
plurar_attributes = [
|
27
38
|
:contacts,
|
28
|
-
:redirect_uris
|
29
|
-
:userinfo_signed_response_algs,
|
30
|
-
:userinfo_encrypted_response_algs,
|
31
|
-
:id_token_signed_response_algs,
|
32
|
-
:id_token_encrypted_response_algs
|
39
|
+
:redirect_uris
|
33
40
|
]
|
34
41
|
attr_required :endpoint
|
35
42
|
attr_optional *(singular_attributes + plurar_attributes)
|
@@ -48,10 +55,10 @@ module OpenIDConnect
|
|
48
55
|
end
|
49
56
|
|
50
57
|
validates :type, :presence => true
|
51
|
-
validates :client_id, :presence => {:if => lambda { |c| c.type.to_s
|
58
|
+
validates :client_id, :presence => {:if => lambda { |c| ['client_update', 'rotate_secret'].include?(c.type.to_s) }}
|
52
59
|
validates :sector_identifier_url, :presence => {:if => :sector_identifier_required?}
|
53
60
|
|
54
|
-
validates :type, :inclusion => {:in => ['client_associate', 'client_update']}
|
61
|
+
validates :type, :inclusion => {:in => ['client_associate', 'rotate_secret', 'client_update']}
|
55
62
|
validates :application_type, :inclusion => {:in => ['native', 'web']}, :allow_nil => true
|
56
63
|
validates :user_id_type, :inclusion => {:in => ['pairwise', 'public']}, :allow_nil => true
|
57
64
|
validates :token_endpoint_auth_type, :inclusion => {
|
@@ -127,6 +134,11 @@ module OpenIDConnect
|
|
127
134
|
post!
|
128
135
|
end
|
129
136
|
|
137
|
+
def rotate_secret!
|
138
|
+
self.type = 'rotate_secret'
|
139
|
+
post!
|
140
|
+
end
|
141
|
+
|
130
142
|
def update!
|
131
143
|
self.type = 'client_update'
|
132
144
|
post!
|
@@ -6,8 +6,6 @@ module OpenIDConnect
|
|
6
6
|
def self.parse(identifier)
|
7
7
|
raise InvalidIdentifier.new('Identifier Required') if identifier.blank?
|
8
8
|
type = case identifier
|
9
|
-
when /^(=|@|!)/
|
10
|
-
XRI
|
11
9
|
when /@/
|
12
10
|
Email
|
13
11
|
else
|
@@ -31,5 +29,4 @@ module OpenIDConnect
|
|
31
29
|
end
|
32
30
|
|
33
31
|
require 'openid_connect/discovery/principal/email'
|
34
|
-
require 'openid_connect/discovery/principal/uri'
|
35
|
-
require 'openid_connect/discovery/principal/xri'
|
32
|
+
require 'openid_connect/discovery/principal/uri'
|
@@ -6,7 +6,7 @@ module OpenIDConnect
|
|
6
6
|
class InvalidToken < Exception; end
|
7
7
|
|
8
8
|
attr_required :iss, :user_id, :aud, :exp, :iat
|
9
|
-
attr_optional :acr, :auth_time, :nonce
|
9
|
+
attr_optional :acr, :auth_time, :nonce, :at_hash
|
10
10
|
|
11
11
|
def initialize(attributes = {})
|
12
12
|
super
|
@@ -25,16 +25,8 @@ module OpenIDConnect
|
|
25
25
|
|
26
26
|
include JWTnizable
|
27
27
|
class << self
|
28
|
-
def decode(jwt_string,
|
29
|
-
|
30
|
-
when Client
|
31
|
-
OpenIDConnect::AccessToken.new(
|
32
|
-
:client => key_or_client,
|
33
|
-
:access_token => jwt_string
|
34
|
-
).id_token!
|
35
|
-
else
|
36
|
-
new JSON::JWT.decode(jwt_string, key_or_client)
|
37
|
-
end
|
28
|
+
def decode(jwt_string, key)
|
29
|
+
new JSON::JWT.decode(jwt_string, key)
|
38
30
|
end
|
39
31
|
end
|
40
32
|
end
|
@@ -4,7 +4,6 @@
|
|
4
4
|
"authorization_endpoint": "https://connect-op.heroku.com/authorizations/new",
|
5
5
|
"token_endpoint": "https://connect-op.heroku.com/access_tokens",
|
6
6
|
"userinfo_endpoint": "https://connect-op.heroku.com/user_info",
|
7
|
-
"check_id_endpoint": "https://connect-op.heroku.com/id_token",
|
8
7
|
"registration_endpoint": "https://connect-op.heroku.com/connect/client",
|
9
8
|
"scopes_supported": ["openid", "profile", "email", "address"],
|
10
9
|
"response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "id_token token"],
|
@@ -97,18 +97,4 @@ describe OpenIDConnect::AccessToken do
|
|
97
97
|
it_behaves_like :access_token_error_handling
|
98
98
|
end
|
99
99
|
end
|
100
|
-
|
101
|
-
describe '#id_token!' do
|
102
|
-
it 'should return OpenIDConnect::ResponseObject::UserInfo::OpenID' do
|
103
|
-
mock_json :get, client.check_id_uri, 'id_token', :HTTP_AUTHORIZATION => 'Bearer access_token' do
|
104
|
-
access_token.id_token!.should be_a OpenIDConnect::ResponseObject::IdToken
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe 'error handling' do
|
109
|
-
let(:endpoint) { client.check_id_uri }
|
110
|
-
let(:request) { access_token.id_token! }
|
111
|
-
it_behaves_like :access_token_error_handling
|
112
|
-
end
|
113
|
-
end
|
114
100
|
end
|
@@ -224,7 +224,7 @@ describe OpenIDConnect::Client::Registrar do
|
|
224
224
|
} do
|
225
225
|
client = instance.associate!
|
226
226
|
client.should be_instance_of OpenIDConnect::Client
|
227
|
-
client.identifier.should == '
|
227
|
+
client.identifier.should == 'client.example.com'
|
228
228
|
client.secret.should == 'client_secret'
|
229
229
|
client.expires_in.should == 3600
|
230
230
|
end
|
@@ -255,13 +255,13 @@ describe OpenIDConnect::Client::Registrar do
|
|
255
255
|
mock_json :post, endpoint, 'client/updated', :params => {
|
256
256
|
:type => 'client_update',
|
257
257
|
:client_id => 'client.example.com',
|
258
|
-
:client_secret => 'client_secret'
|
258
|
+
:client_secret => 'client_secret',
|
259
|
+
:application_name => 'New Name'
|
259
260
|
} do
|
261
|
+
instance.application_name = 'New Name'
|
260
262
|
client = instance.update!
|
261
263
|
client.should be_instance_of OpenIDConnect::Client
|
262
|
-
client.identifier.should == '
|
263
|
-
client.secret.should == 'new_client_secret'
|
264
|
-
client.expires_in.should == 3600
|
264
|
+
client.identifier.should == 'client.example.com'
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
@@ -280,6 +280,29 @@ describe OpenIDConnect::Client::Registrar do
|
|
280
280
|
end
|
281
281
|
end
|
282
282
|
|
283
|
+
describe '#rotate_secret!' do
|
284
|
+
let(:attributes) do
|
285
|
+
{
|
286
|
+
:client_id => 'client.example.com',
|
287
|
+
:client_secret => 'client_secret'
|
288
|
+
}
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should return OpenIDConnect::Client' do
|
292
|
+
mock_json :post, endpoint, 'client/rotated', :params => {
|
293
|
+
:type => 'rotate_secret',
|
294
|
+
:client_id => 'client.example.com',
|
295
|
+
:client_secret => 'client_secret'
|
296
|
+
} do
|
297
|
+
client = instance.rotate_secret!
|
298
|
+
client.should be_instance_of OpenIDConnect::Client
|
299
|
+
client.identifier.should == 'client.example.com'
|
300
|
+
client.secret.should == 'new_client_secret'
|
301
|
+
client.expires_in.should == 3600
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
283
306
|
describe '#validate!' do
|
284
307
|
context 'when valid' do
|
285
308
|
it do
|
@@ -19,12 +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(:check_id_uri) { should == 'https://server.example.com/id_token' }
|
23
22
|
its(:user_info_uri) { should == 'https://server.example.com/user_info' }
|
24
23
|
end
|
25
24
|
|
26
25
|
context 'otherwise' do
|
27
|
-
[:authorization_uri, :
|
26
|
+
[:authorization_uri, :user_info_uri].each do |endpoint|
|
28
27
|
describe endpoint do
|
29
28
|
it do
|
30
29
|
expect { client.send endpoint }.should raise_error 'No Host Info'
|
@@ -5,9 +5,7 @@ describe OpenIDConnect::Discovery::Principal do
|
|
5
5
|
{
|
6
6
|
'server.example.com' => OpenIDConnect::Discovery::Principal::URI,
|
7
7
|
'http://server.example.com' => OpenIDConnect::Discovery::Principal::URI,
|
8
|
-
'nov@server.example.com' => OpenIDConnect::Discovery::Principal::Email
|
9
|
-
'=nov' => OpenIDConnect::Discovery::Principal::XRI,
|
10
|
-
'@nov' => OpenIDConnect::Discovery::Principal::XRI
|
8
|
+
'nov@server.example.com' => OpenIDConnect::Discovery::Principal::Email
|
11
9
|
}.each do |input, klass|
|
12
10
|
describe input do
|
13
11
|
it do
|
@@ -14,7 +14,6 @@ describe OpenIDConnect::Discovery::Provider::Config do
|
|
14
14
|
config.authorization_endpoint.should == 'https://connect-op.heroku.com/authorizations/new'
|
15
15
|
config.token_endpoint.should == 'https://connect-op.heroku.com/access_tokens'
|
16
16
|
config.user_info_endpoint.should == 'https://connect-op.heroku.com/user_info'
|
17
|
-
config.check_id_endpoint.should == 'https://connect-op.heroku.com/id_token'
|
18
17
|
config.refresh_session_endpoint.should be_nil
|
19
18
|
config.end_session_endpoint.should be_nil
|
20
19
|
config.jwk_url.should be_nil
|
@@ -19,7 +19,7 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
19
19
|
describe 'attributes' do
|
20
20
|
subject { klass }
|
21
21
|
its(:required_attributes) { should == [:iss, :user_id, :aud, :exp, :iat] }
|
22
|
-
its(:optional_attributes) { should == [:acr, :auth_time, :nonce] }
|
22
|
+
its(:optional_attributes) { should == [:acr, :auth_time, :nonce, :at_hash] }
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#verify!' do
|
@@ -150,37 +150,12 @@ describe OpenIDConnect::ResponseObject::IdToken do
|
|
150
150
|
end
|
151
151
|
|
152
152
|
describe '.decode' do
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
its(key) { should == attributes[key] }
|
159
|
-
end
|
160
|
-
its(:exp) { should == attributes[:exp].to_i }
|
161
|
-
end
|
162
|
-
|
163
|
-
context 'when client is given' do
|
164
|
-
let :client do
|
165
|
-
OpenIDConnect::Client.new(
|
166
|
-
:identifier => 'client_id',
|
167
|
-
:secret => 'client_secret',
|
168
|
-
:host => 'server.example.com'
|
169
|
-
)
|
170
|
-
end
|
171
|
-
subject do
|
172
|
-
mock_json :get, client.check_id_uri, 'id_token', :HTTP_AUTHORIZATION => 'Bearer access_token' do
|
173
|
-
@subject = klass.decode id_token.to_jwt(private_key), client
|
174
|
-
end
|
175
|
-
@subject
|
176
|
-
end
|
177
|
-
let(:attributes) { required_attributes }
|
178
|
-
let(:ext) { 1303852880 }
|
179
|
-
it { should be_a klass }
|
180
|
-
[:iss, :user_id, :aud].each do |key|
|
181
|
-
its(key) { should == attributes[key] }
|
182
|
-
end
|
183
|
-
its(:exp) { should == attributes[:exp].to_i }
|
153
|
+
subject { klass.decode id_token.to_jwt(private_key), public_key }
|
154
|
+
let(:attributes) { required_attributes }
|
155
|
+
it { should be_a klass }
|
156
|
+
[:iss, :user_id, :aud].each do |key|
|
157
|
+
its(key) { should == attributes[key] }
|
184
158
|
end
|
159
|
+
its(:exp) { should == attributes[:exp].to_i }
|
185
160
|
end
|
186
161
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openid_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -246,7 +246,6 @@ files:
|
|
246
246
|
- lib/openid_connect/discovery/principal.rb
|
247
247
|
- lib/openid_connect/discovery/principal/email.rb
|
248
248
|
- lib/openid_connect/discovery/principal/uri.rb
|
249
|
-
- lib/openid_connect/discovery/principal/xri.rb
|
250
249
|
- lib/openid_connect/discovery/provider.rb
|
251
250
|
- lib/openid_connect/discovery/provider/config.rb
|
252
251
|
- lib/openid_connect/discovery/provider/config/resource.rb
|
@@ -276,6 +275,7 @@ files:
|
|
276
275
|
- spec/mock_response/access_token/invalid_json.json
|
277
276
|
- spec/mock_response/access_token/mac.json
|
278
277
|
- spec/mock_response/client/registered.json
|
278
|
+
- spec/mock_response/client/rotated.json
|
279
279
|
- spec/mock_response/client/updated.json
|
280
280
|
- spec/mock_response/discovery/config.json
|
281
281
|
- spec/mock_response/discovery/swd.json
|
@@ -292,7 +292,6 @@ files:
|
|
292
292
|
- spec/openid_connect/debugger/request_filter_spec.rb
|
293
293
|
- spec/openid_connect/discovery/principal/email_spec.rb
|
294
294
|
- spec/openid_connect/discovery/principal/uri_spec.rb
|
295
|
-
- spec/openid_connect/discovery/principal/xri_spec.rb
|
296
295
|
- spec/openid_connect/discovery/principal_spec.rb
|
297
296
|
- spec/openid_connect/discovery/provider/config/response_spec.rb
|
298
297
|
- spec/openid_connect/discovery/provider/config_spec.rb
|
@@ -342,6 +341,7 @@ test_files:
|
|
342
341
|
- spec/mock_response/access_token/invalid_json.json
|
343
342
|
- spec/mock_response/access_token/mac.json
|
344
343
|
- spec/mock_response/client/registered.json
|
344
|
+
- spec/mock_response/client/rotated.json
|
345
345
|
- spec/mock_response/client/updated.json
|
346
346
|
- spec/mock_response/discovery/config.json
|
347
347
|
- spec/mock_response/discovery/swd.json
|
@@ -358,7 +358,6 @@ test_files:
|
|
358
358
|
- spec/openid_connect/debugger/request_filter_spec.rb
|
359
359
|
- spec/openid_connect/discovery/principal/email_spec.rb
|
360
360
|
- spec/openid_connect/discovery/principal/uri_spec.rb
|
361
|
-
- spec/openid_connect/discovery/principal/xri_spec.rb
|
362
361
|
- spec/openid_connect/discovery/principal_spec.rb
|
363
362
|
- spec/openid_connect/discovery/provider/config/response_spec.rb
|
364
363
|
- spec/openid_connect/discovery/provider/config_spec.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module OpenIDConnect
|
2
|
-
module Discovery
|
3
|
-
class Principal
|
4
|
-
class XRI < Principal
|
5
|
-
def initialize(identifier)
|
6
|
-
@identifier = identifier
|
7
|
-
end
|
8
|
-
|
9
|
-
def discover!(cache_options = {})
|
10
|
-
raise NotImplementedError.new('XRI is not supported yet')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|