openid_connect 0.0.31 → 0.0.32
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/.gitignore +1 -1
- data/Gemfile.lock +34 -26
- data/README.rdoc +2 -2
- data/Rakefile +12 -4
- data/VERSION +1 -1
- data/lib/openid_connect/access_token.rb +8 -0
- data/lib/openid_connect/client/registrar.rb +217 -0
- data/lib/openid_connect/client.rb +4 -0
- data/lib/openid_connect/discovery/provider/config/response.rb +40 -5
- data/lib/openid_connect/exception.rb +9 -0
- data/lib/openid_connect/response_object/id_token.rb +6 -28
- data/lib/openid_connect/response_object/user_info/open_id.rb +22 -15
- data/lib/openid_connect/response_object.rb +0 -16
- data/lib/openid_connect.rb +14 -0
- data/openid_connect.gemspec +5 -1
- data/spec/mock_response/discovery/config.json +4 -4
- data/spec/mock_response/id_token.json +3 -3
- data/spec/openid_connect/access_token_spec.rb +46 -26
- data/spec/openid_connect/client/registrar_spec.rb +115 -0
- data/spec/openid_connect/discovery/provider/config/response_spec.rb +46 -0
- data/spec/openid_connect/discovery/provider/config_spec.rb +5 -5
- data/spec/openid_connect/response_object/id_token_spec.rb +32 -7
- data/spec/openid_connect/response_object/user_info/open_id_spec.rb +8 -0
- data/spec/openid_connect/response_object_spec.rb +4 -4
- data/spec/rack/oauth2/server/authorize/extension/code_and_id_token_spec.rb +2 -1
- data/spec/rack/oauth2/server/authorize/extension/id_token_and_token_spec.rb +10 -5
- data/spec/rack/oauth2/server/authorize/extension/id_token_spec.rb +8 -5
- data/spec/spec_helper.rb +7 -0
- metadata +124 -126
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openid_connect (0.0.
|
4
|
+
openid_connect (0.0.31)
|
5
5
|
activemodel (>= 3)
|
6
6
|
attr_required (>= 0.0.3)
|
7
7
|
json (>= 1.4.3)
|
@@ -15,34 +15,43 @@ PATH
|
|
15
15
|
GEM
|
16
16
|
remote: http://rubygems.org/
|
17
17
|
specs:
|
18
|
-
activemodel (3.1.
|
19
|
-
activesupport (= 3.1.
|
18
|
+
activemodel (3.1.3)
|
19
|
+
activesupport (= 3.1.3)
|
20
20
|
builder (~> 3.0.0)
|
21
21
|
i18n (~> 0.6)
|
22
|
-
activesupport (3.1.
|
22
|
+
activesupport (3.1.3)
|
23
23
|
multi_json (~> 1.0)
|
24
24
|
addressable (2.2.6)
|
25
25
|
attr_required (0.0.3)
|
26
26
|
bouncy-castle-java (1.5.0146.1)
|
27
27
|
builder (3.0.0)
|
28
|
+
configatron (2.8.4)
|
29
|
+
yamler (>= 0.1.0)
|
30
|
+
cover_me (1.2.0)
|
31
|
+
configatron
|
32
|
+
hashie
|
28
33
|
crack (0.3.1)
|
29
34
|
diff-lcs (1.1.3)
|
30
|
-
|
35
|
+
hashie (1.2.0)
|
36
|
+
httpclient (2.2.4)
|
31
37
|
i18n (0.6.0)
|
32
38
|
jruby-openssl (0.7.4)
|
33
39
|
bouncy-castle-java
|
34
|
-
json (1.6.
|
35
|
-
json
|
40
|
+
json (1.6.5)
|
41
|
+
json (1.6.5-java)
|
42
|
+
json-jwt (0.0.4)
|
43
|
+
activesupport (>= 2.3)
|
44
|
+
i18n
|
36
45
|
json (>= 1.4.3)
|
37
46
|
url_safe_base64
|
38
|
-
mail (2.
|
47
|
+
mail (2.4.0)
|
39
48
|
i18n (>= 0.4.0)
|
40
49
|
mime-types (~> 1.16)
|
41
50
|
treetop (~> 1.4.8)
|
42
|
-
mime-types (1.
|
43
|
-
multi_json (1.0.
|
44
|
-
polyglot (0.3.
|
45
|
-
rack (1.
|
51
|
+
mime-types (1.17.2)
|
52
|
+
multi_json (1.0.4)
|
53
|
+
polyglot (0.3.3)
|
54
|
+
rack (1.4.0)
|
46
55
|
rack-oauth2 (0.11.0)
|
47
56
|
activesupport (>= 2.3)
|
48
57
|
attr_required (>= 0.0.3)
|
@@ -50,17 +59,15 @@ GEM
|
|
50
59
|
i18n
|
51
60
|
json (>= 1.4.3)
|
52
61
|
rack (>= 1.1)
|
53
|
-
rake (0.9.2)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
rspec-
|
58
|
-
|
59
|
-
|
60
|
-
rspec-core (2.6.4)
|
61
|
-
rspec-expectations (2.6.0)
|
62
|
+
rake (0.9.2.2)
|
63
|
+
rspec (2.8.0)
|
64
|
+
rspec-core (~> 2.8.0)
|
65
|
+
rspec-expectations (~> 2.8.0)
|
66
|
+
rspec-mocks (~> 2.8.0)
|
67
|
+
rspec-core (2.8.0)
|
68
|
+
rspec-expectations (2.8.0)
|
62
69
|
diff-lcs (~> 1.1.2)
|
63
|
-
rspec-mocks (2.
|
70
|
+
rspec-mocks (2.8.0)
|
64
71
|
swd (0.0.7)
|
65
72
|
activesupport (>= 3)
|
66
73
|
attr_required (>= 0.0.3)
|
@@ -70,25 +77,26 @@ GEM
|
|
70
77
|
treetop (1.4.10)
|
71
78
|
polyglot
|
72
79
|
polyglot (>= 0.3.1)
|
73
|
-
tzinfo (0.3.
|
80
|
+
tzinfo (0.3.31)
|
74
81
|
url_safe_base64 (0.2.1)
|
75
82
|
validate_email (0.1.5)
|
76
83
|
activemodel (>= 3.0)
|
77
84
|
mail (>= 2.2.5)
|
78
85
|
validate_url (0.2.0)
|
79
86
|
activemodel (>= 3.0.0)
|
80
|
-
webmock (1.7.
|
81
|
-
addressable (
|
87
|
+
webmock (1.7.10)
|
88
|
+
addressable (~> 2.2, > 2.2.5)
|
82
89
|
crack (>= 0.1.7)
|
90
|
+
yamler (0.1.0)
|
83
91
|
|
84
92
|
PLATFORMS
|
85
93
|
java
|
86
94
|
ruby
|
87
95
|
|
88
96
|
DEPENDENCIES
|
97
|
+
cover_me (>= 1.2.0)
|
89
98
|
jruby-openssl (>= 0.7)
|
90
99
|
openid_connect!
|
91
100
|
rake (>= 0.8)
|
92
|
-
rcov (>= 0.9)
|
93
101
|
rspec (>= 2)
|
94
102
|
webmock (>= 1.6.2)
|
data/README.rdoc
CHANGED
@@ -16,12 +16,12 @@ OpenID Connect Server & Client Library
|
|
16
16
|
|
17
17
|
=== Provider
|
18
18
|
|
19
|
-
* Running on Heroku (
|
19
|
+
* Running on Heroku (http://connect-op.heroku.com)
|
20
20
|
* Source on GitHub (https://github.com/nov/openid_connect_sample)
|
21
21
|
|
22
22
|
=== Relying Party
|
23
23
|
|
24
|
-
* Running on Heroku (https://
|
24
|
+
* Running on Heroku (https://connect-rp.heroku.com)
|
25
25
|
* Source on GitHub (https://github.com/nov/openid_connect_sample_rp)
|
26
26
|
|
27
27
|
== Note on Patches/Pull Requests
|
data/Rakefile
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
-
require 'bundler
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
2
3
|
|
3
4
|
require 'rspec/core/rake_task'
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
if RUBY_VERSION >= '1.9'
|
8
|
+
require 'cover_me'
|
9
|
+
CoverMe.config do |c|
|
10
|
+
c.file_pattern = /(#{CoverMe.config.project.root}\/lib\/.+\.rb)/i
|
11
|
+
end
|
12
|
+
else
|
13
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
14
|
+
spec.rcov = true
|
15
|
+
spec.rcov_opts = ['-Ilib -Ispec --exclude spec,gems']
|
16
|
+
end
|
9
17
|
end
|
10
18
|
|
11
19
|
task :default => :spec
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.32
|
@@ -15,6 +15,14 @@ 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
|
+
|
18
26
|
private
|
19
27
|
|
20
28
|
def resource_request
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module OpenIDConnect
|
2
|
+
class Client
|
3
|
+
class Registrar
|
4
|
+
include ActiveModel::Validations, AttrRequired, AttrOptional
|
5
|
+
|
6
|
+
class RegistrationFailed < HttpError; end
|
7
|
+
|
8
|
+
singular_attributes = [
|
9
|
+
:type,
|
10
|
+
:client_id,
|
11
|
+
:client_secret,
|
12
|
+
:access_token,
|
13
|
+
:application_type,
|
14
|
+
:application_name,
|
15
|
+
:logo_url,
|
16
|
+
:token_endpoint_auth_type,
|
17
|
+
:policy_url,
|
18
|
+
:jwk_url,
|
19
|
+
:jwk_encryption_url,
|
20
|
+
:x509_url,
|
21
|
+
:x509_encryption_url,
|
22
|
+
:sector_identifier_url,
|
23
|
+
:user_id_type,
|
24
|
+
:require_signed_request_object,
|
25
|
+
]
|
26
|
+
plurar_attributes = [
|
27
|
+
: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
|
33
|
+
]
|
34
|
+
attr_required :endpoint
|
35
|
+
attr_optional *(singular_attributes + plurar_attributes)
|
36
|
+
|
37
|
+
plurar_attributes.each do |_attr_|
|
38
|
+
define_method "#{_attr_}_with_split" do
|
39
|
+
self.send("#{_attr_}_without_split").to_s.split(' ')
|
40
|
+
end
|
41
|
+
alias_method_chain _attr_, :split
|
42
|
+
end
|
43
|
+
|
44
|
+
validates :type, :presence => true
|
45
|
+
validates :client_id, :presence => {:if => lambda { |c| c.type.to_s == 'client_update' }}
|
46
|
+
validates :sector_identifier_url, :presence => {:if => :sector_identifier_required?}
|
47
|
+
|
48
|
+
validates :type, :inclusion => {:in => ['client_associate', 'client_update']}
|
49
|
+
validates :application_type, :inclusion => {:in => ['native', 'web']}, :allow_nil => true
|
50
|
+
validates :user_id_type, :inclusion => {:in => ['pairwise', 'public']}, :allow_nil => true
|
51
|
+
validates :token_endpoint_auth_type, :inclusion => {
|
52
|
+
:in => ['client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt']
|
53
|
+
}, :allow_nil => true
|
54
|
+
|
55
|
+
validates(
|
56
|
+
:logo_url,
|
57
|
+
:policy_url,
|
58
|
+
:jwk_url,
|
59
|
+
:jwk_encryption_url,
|
60
|
+
:x509_url,
|
61
|
+
:x509_encryption_url,
|
62
|
+
:sector_identifier_url,
|
63
|
+
:url => true, :allow_nil => true
|
64
|
+
)
|
65
|
+
|
66
|
+
validate :validate_contacts
|
67
|
+
validate :validate_redirect_uris
|
68
|
+
validate :validate_key_urls
|
69
|
+
validate :validate_signature_algorithms
|
70
|
+
validate :validate_encription_algorithms
|
71
|
+
|
72
|
+
def initialize(endpoint, attributes = {})
|
73
|
+
@endpoint = endpoint
|
74
|
+
optional_attributes.each do |_attr_|
|
75
|
+
self.send "#{_attr_}=", attributes[_attr_].try(:to_s)
|
76
|
+
end
|
77
|
+
attr_missing!
|
78
|
+
end
|
79
|
+
|
80
|
+
def sector_identifier
|
81
|
+
if valid_uri?(sector_identifier_url)
|
82
|
+
URI.parse(sector_identifier_url).host
|
83
|
+
else
|
84
|
+
hosts = Array(redirect_uris).collect do |redirect_uri|
|
85
|
+
if valid_uri?(redirect_uri, nil)
|
86
|
+
URI.parse(redirect_uri).host
|
87
|
+
else
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end.compact.uniq
|
91
|
+
if hosts.size == 1
|
92
|
+
hosts.first
|
93
|
+
else
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def as_json(options = {})
|
100
|
+
validate!
|
101
|
+
(optional_attributes - [:access_token]).inject({}) do |hash, _attr_|
|
102
|
+
value = self.send(_attr_)
|
103
|
+
hash.merge! _attr_ => case value
|
104
|
+
when Array
|
105
|
+
value.collect(&:to_s).join(' ')
|
106
|
+
else
|
107
|
+
value
|
108
|
+
end
|
109
|
+
end.delete_if do |key, value|
|
110
|
+
value.nil?
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def associate!
|
115
|
+
self.type = 'client_associate'
|
116
|
+
post!
|
117
|
+
end
|
118
|
+
|
119
|
+
def update!
|
120
|
+
self.type = 'client_update'
|
121
|
+
post!
|
122
|
+
end
|
123
|
+
|
124
|
+
def validate!
|
125
|
+
valid? or raise ValidationFailed.new(errors)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def sector_identifier_required?
|
131
|
+
user_id_type == 'pairwise' &&
|
132
|
+
sector_identifier.blank?
|
133
|
+
end
|
134
|
+
|
135
|
+
def valid_uri?(uri, schemes = ['http', 'https'])
|
136
|
+
# NOTE: specify nil for schemes to allow any schemes
|
137
|
+
URI::regexp(schemes).match(uri).present?
|
138
|
+
end
|
139
|
+
|
140
|
+
def validate_contacts
|
141
|
+
contacts.each do |contact|
|
142
|
+
EmailValidator.new.validate_each(self, :contacts, contact)
|
143
|
+
end
|
144
|
+
include_invalid = contacts.any? do |contact|
|
145
|
+
begin
|
146
|
+
mail = Mail::Address.new(contact)
|
147
|
+
mail.address != contact || mail.domain.split(".").length <= 1
|
148
|
+
rescue
|
149
|
+
:invalid
|
150
|
+
end
|
151
|
+
end
|
152
|
+
errors.add :contacts, 'includes invalid email' if include_invalid
|
153
|
+
end
|
154
|
+
|
155
|
+
def validate_redirect_uris
|
156
|
+
include_invalid = redirect_uris.any? do |redirect_uri|
|
157
|
+
!valid_uri?(redirect_uri, nil)
|
158
|
+
end
|
159
|
+
errors.add :redirect_uris, 'includes invalid URL' if include_invalid
|
160
|
+
end
|
161
|
+
|
162
|
+
def validate_key_urls
|
163
|
+
# TODO
|
164
|
+
end
|
165
|
+
|
166
|
+
def validate_signature_algorithms
|
167
|
+
# TODO
|
168
|
+
end
|
169
|
+
|
170
|
+
def validate_encription_algorithms
|
171
|
+
# TODO
|
172
|
+
end
|
173
|
+
|
174
|
+
def post!
|
175
|
+
handle_response do
|
176
|
+
http_client.post endpoint, as_json
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def http_client
|
181
|
+
case access_token
|
182
|
+
when nil
|
183
|
+
OpenIDConnect.http_client
|
184
|
+
when Rack::OAuth2::AccessToken::Bearer
|
185
|
+
access_token
|
186
|
+
else
|
187
|
+
Rack::OAuth2::AccessToken::Bearer.new(
|
188
|
+
:access_token => access_token
|
189
|
+
)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def handle_response
|
194
|
+
response = yield
|
195
|
+
case response.status
|
196
|
+
when 200..201
|
197
|
+
handle_success_response response
|
198
|
+
else
|
199
|
+
handle_error_response response
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def handle_success_response(response)
|
204
|
+
credentials = JSON.parse(response.body).with_indifferent_access
|
205
|
+
Client.new(
|
206
|
+
:identifier => credentials[:client_id],
|
207
|
+
:secret => credentials[:client_secret],
|
208
|
+
:expires_in => credentials[:expires_in]
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
def handle_error_response(response)
|
213
|
+
raise RegistrationFailed.new(response.status, 'Client Registration Failed', response)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -6,18 +6,53 @@ module OpenIDConnect
|
|
6
6
|
include AttrOptional
|
7
7
|
|
8
8
|
attr_reader :raw
|
9
|
-
attr_optional
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
attr_optional(
|
10
|
+
:version,
|
11
|
+
:issuer,
|
12
|
+
:authorization_endpoint,
|
13
|
+
:token_endpoint,
|
14
|
+
:user_info_endpoint,
|
15
|
+
:check_id_endpoint,
|
16
|
+
:refresh_session_endpoint,
|
17
|
+
:end_session_endpoint,
|
18
|
+
:jwk_url,
|
19
|
+
:jwk_encryption_url,
|
20
|
+
:x509_url,
|
21
|
+
:x509_encryption_ur,
|
22
|
+
:registration_endpoint,
|
23
|
+
:scopes_supported,
|
24
|
+
:response_types_supported,
|
25
|
+
:acrs_supported,
|
26
|
+
:user_id_types_supported,
|
27
|
+
:user_info_algs_supported,
|
28
|
+
:id_token_algs_supported,
|
29
|
+
:request_object_algs_supported,
|
30
|
+
:token_endpoint_auth_types_supported,
|
31
|
+
:token_endpoint_auth_algs_supported
|
32
|
+
)
|
14
33
|
|
15
34
|
def initialize(hash)
|
16
35
|
optional_attributes.each do |key|
|
17
36
|
self.send "#{key}=", hash[key]
|
18
37
|
end
|
38
|
+
@user_info_endpoint ||= hash[:userinfo_endpoint]
|
39
|
+
@user_info_algs_supported ||= hash[:userinfo_algs_supported]
|
40
|
+
@version ||= '3.0'
|
19
41
|
@raw = hash
|
20
42
|
end
|
43
|
+
|
44
|
+
def as_json(options = {})
|
45
|
+
hash = optional_attributes.inject({}) do |hash, _attr_|
|
46
|
+
hash.merge(
|
47
|
+
_attr_ => self.send(_attr_)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
hash[:userinfo_endpoint] = hash.delete(:user_info_endpoint)
|
51
|
+
hash[:userinfo_algs_supported] = hash.delete(:user_info_algs_supported)
|
52
|
+
hash.delete_if do |key, value|
|
53
|
+
value.nil?
|
54
|
+
end
|
55
|
+
end
|
21
56
|
end
|
22
57
|
end
|
23
58
|
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
module OpenIDConnect
|
2
2
|
class Exception < StandardError; end
|
3
3
|
|
4
|
+
class ValidationFailed < Exception
|
5
|
+
attr_reader :errors
|
6
|
+
|
7
|
+
def initialize(errors)
|
8
|
+
super errors.full_messages.to_sentence
|
9
|
+
@errors = errors
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
class HttpError < Exception
|
5
14
|
attr_accessor :status, :response
|
6
15
|
def initialize(status, message = nil, response = nil)
|
@@ -30,38 +30,16 @@ module OpenIDConnect
|
|
30
30
|
end
|
31
31
|
|
32
32
|
class << self
|
33
|
-
def
|
33
|
+
def decode(jwt_string, key_or_client)
|
34
34
|
attributes = case key_or_client
|
35
35
|
when Client
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
OpenIDConnect::AccessToken.new(
|
37
|
+
:client => key_or_client,
|
38
|
+
:access_token => jwt_string
|
39
|
+
).id_token!
|
39
40
|
else
|
40
|
-
JSON::JWT.decode(jwt_string, key_or_client)
|
41
|
+
new JSON::JWT.decode(jwt_string, key_or_client)
|
41
42
|
end
|
42
|
-
new attributes
|
43
|
-
end
|
44
|
-
|
45
|
-
def resource_request
|
46
|
-
res = yield
|
47
|
-
case res.status
|
48
|
-
when 200
|
49
|
-
JSON.parse(res.body).with_indifferent_access
|
50
|
-
when 400
|
51
|
-
raise BadRequest.new('Check Session Faild', res)
|
52
|
-
else
|
53
|
-
raise HttpError.new(res.status, 'Unknown HttpError', res)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def http_client
|
60
|
-
_http_client_ = HTTPClient.new(
|
61
|
-
:agent_name => "OpenIDConnect (#{VERSION})"
|
62
|
-
)
|
63
|
-
_http_client_.request_filter << Debugger::RequestFilter.new if OpenIDConnect.debugging?
|
64
|
-
_http_client_
|
65
43
|
end
|
66
44
|
end
|
67
45
|
end
|
@@ -2,28 +2,35 @@ module OpenIDConnect
|
|
2
2
|
class ResponseObject
|
3
3
|
module UserInfo
|
4
4
|
class OpenID < ResponseObject
|
5
|
-
attr_optional
|
5
|
+
attr_optional(
|
6
|
+
:user_id,
|
7
|
+
:name,
|
8
|
+
:given_name,
|
9
|
+
:family_name,
|
10
|
+
:middle_name,
|
11
|
+
:nickname,
|
12
|
+
:phone_number,
|
13
|
+
:verified,
|
14
|
+
:gender,
|
15
|
+
:zoneinfo,
|
16
|
+
:locale,
|
17
|
+
:birthday,
|
18
|
+
:updated_time,
|
19
|
+
:profile,
|
20
|
+
:picture,
|
21
|
+
:website,
|
22
|
+
:email,
|
23
|
+
:address
|
24
|
+
)
|
6
25
|
|
7
|
-
attr_optional :phone_number
|
8
|
-
|
9
|
-
attr_optional :verified, :gender, :zoneinfo, :locale
|
10
26
|
validates :verified, :inclusion => {:in => [true, false]}, :allow_nil => true
|
11
27
|
validates :gender, :inclusion => {:in => ['male', 'female']}, :allow_nil => true
|
12
28
|
validates :zoneinfo, :inclusion => {:in => TZInfo::TimezoneProxy.all.collect(&:name)}, :allow_nil => true
|
13
|
-
# TODO: validate locale
|
14
|
-
|
15
|
-
attr_optional :birthday, :updated_time
|
16
|
-
|
17
|
-
attr_optional :profile, :picture, :website
|
18
29
|
validates :profile, :picture, :website, :url => true, :allow_nil => true
|
19
|
-
|
20
|
-
attr_optional :email
|
21
30
|
validates :email, :email => true, :allow_nil => true
|
22
|
-
|
23
|
-
attr_optional :address
|
24
31
|
validate :validate_address
|
25
|
-
|
26
32
|
validate :require_at_least_one_attributes
|
33
|
+
# TODO: validate locale
|
27
34
|
|
28
35
|
def initialize(attributes = {})
|
29
36
|
super
|
@@ -33,7 +40,7 @@ module OpenIDConnect
|
|
33
40
|
end
|
34
41
|
|
35
42
|
def validate_address
|
36
|
-
errors.add :address, '
|
43
|
+
errors.add :address, address.errors.full_messages.join(', ') if address.present? && !address.valid?
|
37
44
|
end
|
38
45
|
|
39
46
|
def address=(hash_or_address)
|
@@ -1,23 +1,7 @@
|
|
1
|
-
require 'active_model'
|
2
|
-
require 'tzinfo'
|
3
|
-
require 'validate_url'
|
4
|
-
require 'validate_email'
|
5
|
-
require 'attr_required'
|
6
|
-
require 'attr_optional'
|
7
|
-
|
8
1
|
module OpenIDConnect
|
9
2
|
class ResponseObject
|
10
3
|
include ActiveModel::Validations, AttrRequired, AttrOptional
|
11
4
|
|
12
|
-
class ValidationFailed < Exception
|
13
|
-
attr_reader :errors
|
14
|
-
|
15
|
-
def initialize(errors)
|
16
|
-
super errors.full_messages.to_sentence
|
17
|
-
@errors = errors
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
5
|
def initialize(attributes = {})
|
22
6
|
all_attributes.each do |_attr_|
|
23
7
|
self.send :"#{_attr_}=", attributes[_attr_]
|
data/lib/openid_connect.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'logger'
|
3
3
|
require 'swd'
|
4
|
+
require 'active_model'
|
5
|
+
require 'tzinfo'
|
6
|
+
require 'validate_url'
|
7
|
+
require 'validate_email'
|
8
|
+
require 'attr_required'
|
9
|
+
require 'attr_optional'
|
4
10
|
require 'rack/oauth2'
|
5
11
|
require 'rack/oauth2/server/id_token_response'
|
6
12
|
|
@@ -43,6 +49,14 @@ module OpenIDConnect
|
|
43
49
|
self.debugging = original
|
44
50
|
end
|
45
51
|
self.debugging = false
|
52
|
+
|
53
|
+
def self.http_client
|
54
|
+
_http_client_ = HTTPClient.new(
|
55
|
+
:agent_name => "OpenIDConnect (#{VERSION})"
|
56
|
+
)
|
57
|
+
_http_client_.request_filter << Debugger::RequestFilter.new if OpenIDConnect.debugging?
|
58
|
+
_http_client_
|
59
|
+
end
|
46
60
|
end
|
47
61
|
|
48
62
|
require 'openid_connect/exception'
|
data/openid_connect.gemspec
CHANGED
@@ -20,7 +20,11 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_runtime_dependency "swd", ">= 0.0.6"
|
21
21
|
s.add_runtime_dependency "rack-oauth2", ">= 0.10.0"
|
22
22
|
s.add_development_dependency "rake", ">= 0.8"
|
23
|
-
|
23
|
+
if RUBY_VERSION >= '1.9'
|
24
|
+
s.add_development_dependency "cover_me", ">= 1.2.0"
|
25
|
+
else
|
26
|
+
s.add_development_dependency "rcov", ">= 0.9"
|
27
|
+
end
|
24
28
|
s.add_development_dependency "rspec", ">= 2"
|
25
29
|
s.add_development_dependency "webmock", ">= 1.6.2"
|
26
30
|
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
"issuer": "https://connect-op.heroku.com",
|
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
7
|
"check_id_endpoint": "https://connect-op.heroku.com/id_token",
|
8
8
|
"registration_endpoint": "https://connect-op.heroku.com/connect/client",
|
9
|
-
"scopes_supported": ["openid", "profile", "email", "address"
|
10
|
-
"
|
11
|
-
"
|
9
|
+
"scopes_supported": ["openid", "profile", "email", "address"],
|
10
|
+
"response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "id_token token"],
|
11
|
+
"user_id_types_supported": ["public", "pairwise"],
|
12
12
|
"x509_url": "https://connect-op.heroku.com/cert.pem"
|
13
13
|
}
|