openid_connect 0.3.3 → 0.3.4

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 (40) hide show
  1. data/Gemfile +1 -9
  2. data/Gemfile.lock +8 -11
  3. data/Rakefile +10 -16
  4. data/VERSION +1 -1
  5. data/lib/openid_connect.rb +1 -1
  6. data/lib/openid_connect/access_token.rb +2 -2
  7. data/lib/openid_connect/client.rb +2 -2
  8. data/lib/openid_connect/client/registrar.rb +16 -15
  9. data/lib/openid_connect/discovery/principal.rb +5 -5
  10. data/lib/openid_connect/discovery/provider/config.rb +1 -1
  11. data/lib/openid_connect/discovery/provider/config/resource.rb +4 -3
  12. data/lib/openid_connect/discovery/provider/config/response.rb +41 -1
  13. data/lib/openid_connect/request_object/claimable.rb +2 -2
  14. data/lib/openid_connect/response_object/id_token.rb +1 -1
  15. data/lib/openid_connect/response_object/user_info/open_id.rb +5 -5
  16. data/lib/rack/oauth2/server/authorize/error_with_connect_ext.rb +7 -7
  17. data/lib/rack/oauth2/server/id_token_response.rb +1 -1
  18. data/openid_connect.gemspec +1 -5
  19. data/spec/mock_response/public_keys/jwk.json +7 -0
  20. data/spec/mock_response/public_keys/x509.pem +21 -0
  21. data/spec/openid_connect/access_token_spec.rb +23 -23
  22. data/spec/openid_connect/client/registrar_spec.rb +45 -45
  23. data/spec/openid_connect/client_spec.rb +12 -12
  24. data/spec/openid_connect/connect_object_spec.rb +6 -6
  25. data/spec/openid_connect/debugger/request_filter_spec.rb +1 -1
  26. data/spec/openid_connect/discovery/principal_spec.rb +5 -5
  27. data/spec/openid_connect/discovery/provider/config/response_spec.rb +265 -3
  28. data/spec/openid_connect/discovery/provider/config_spec.rb +11 -0
  29. data/spec/openid_connect/discovery/provider_spec.rb +3 -3
  30. data/spec/openid_connect/request_object_spec.rb +36 -36
  31. data/spec/openid_connect/response_object/id_token_spec.rb +26 -26
  32. data/spec/openid_connect/response_object/user_info/open_id_spec.rb +7 -7
  33. data/spec/rack/oauth2/server/authorize/extension/code_and_id_token_and_token_spec.rb +7 -7
  34. data/spec/rack/oauth2/server/authorize/extension/code_and_id_token_spec.rb +6 -6
  35. data/spec/rack/oauth2/server/authorize/extension/id_token_and_token_spec.rb +7 -7
  36. data/spec/rack/oauth2/server/authorize/extension/id_token_spec.rb +6 -6
  37. data/spec/rack/oauth2/server/token/authorization_code_spec.rb +14 -14
  38. data/spec/rack/oauth2/server/token/refresh_token_spec.rb +13 -13
  39. data/spec/spec_helper.rb +1 -3
  40. metadata +15 -11
data/Gemfile CHANGED
@@ -1,10 +1,2 @@
1
- source "http://rubygems.org"
2
-
3
- group :test do
4
- platforms :jruby do
5
- gem 'jruby-openssl', '>= 0.7'
6
- end
7
- end
8
-
9
- # Specify your gem's dependencies in openid_connect.gemspec
1
+ source :rubygems
10
2
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openid_connect (0.3.2)
4
+ openid_connect (0.3.4)
5
5
  activemodel (>= 3)
6
6
  attr_required (>= 0.0.5)
7
7
  json (>= 1.4.3)
@@ -23,8 +23,7 @@ GEM
23
23
  multi_json (~> 1.0)
24
24
  addressable (2.3.2)
25
25
  attr_required (0.0.5)
26
- bouncy-castle-java (1.5.0146.1)
27
- builder (3.0.3)
26
+ builder (3.0.4)
28
27
  configatron (2.9.1)
29
28
  yamler (>= 0.1.0)
30
29
  cover_me (1.2.0)
@@ -33,12 +32,11 @@ GEM
33
32
  crack (0.3.1)
34
33
  diff-lcs (1.1.3)
35
34
  hashie (1.2.0)
36
- httpclient (2.2.7)
35
+ httpclient (2.3.0.1)
37
36
  i18n (0.6.1)
38
- jruby-openssl (0.7.7)
39
- bouncy-castle-java (>= 1.5.0146.1)
40
37
  json (1.7.5)
41
- json-jwt (0.3.0)
38
+ json (1.7.5-java)
39
+ json-jwt (0.3.2)
42
40
  activesupport (>= 2.3)
43
41
  i18n
44
42
  json (>= 1.4.3)
@@ -51,7 +49,7 @@ GEM
51
49
  multi_json (1.3.6)
52
50
  polyglot (0.3.3)
53
51
  rack (1.4.1)
54
- rack-oauth2 (0.14.9)
52
+ rack-oauth2 (1.0.0)
55
53
  activesupport (>= 2.3)
56
54
  attr_required (>= 0.0.5)
57
55
  httpclient (>= 2.2.0.2)
@@ -67,13 +65,13 @@ GEM
67
65
  rspec-expectations (2.11.3)
68
66
  diff-lcs (~> 1.1.3)
69
67
  rspec-mocks (2.11.3)
70
- swd (0.2.0)
68
+ swd (0.2.1)
71
69
  activesupport (>= 3)
72
70
  attr_required (>= 0.0.5)
73
71
  httpclient (>= 2.2.1)
74
72
  i18n
75
73
  json (>= 1.4.3)
76
- treetop (1.4.10)
74
+ treetop (1.4.11)
77
75
  polyglot
78
76
  polyglot (>= 0.3.1)
79
77
  tzinfo (0.3.33)
@@ -94,7 +92,6 @@ PLATFORMS
94
92
 
95
93
  DEPENDENCIES
96
94
  cover_me (>= 1.2.0)
97
- jruby-openssl (>= 0.7)
98
95
  openid_connect!
99
96
  rake (>= 0.8)
100
97
  rspec (>= 2)
data/Rakefile CHANGED
@@ -4,22 +4,16 @@ Bundler::GemHelper.install_tasks
4
4
  require 'rspec/core/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- if RUBY_VERSION >= '1.9'
8
- namespace :cover_me do
9
- desc "Generates and opens code coverage report."
10
- task :report do
11
- require 'cover_me'
12
- CoverMe.complete!
13
- end
14
- end
15
- task :spec do
16
- Rake::Task['cover_me:report'].invoke
17
- end
18
- else
19
- RSpec::Core::RakeTask.new(:rcov) do |spec|
20
- spec.rcov = true
21
- spec.rcov_opts = ['-Ilib -Ispec --exclude spec,gems']
7
+ namespace :cover_me do
8
+ desc "Generates and opens code coverage report."
9
+ task :report do
10
+ require 'cover_me'
11
+ CoverMe.complete!
22
12
  end
23
13
  end
24
14
 
25
- task :default => :spec
15
+ task :spec do
16
+ Rake::Task['cover_me:report'].invoke
17
+ end
18
+
19
+ task default: :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.4
@@ -54,7 +54,7 @@ module OpenIDConnect
54
54
 
55
55
  def self.http_client
56
56
  _http_client_ = HTTPClient.new(
57
- :agent_name => "OpenIDConnect (#{VERSION})"
57
+ agent_name: "OpenIDConnect (#{VERSION})"
58
58
  )
59
59
  _http_client_.request_filter << Debugger::RequestFilter.new if debugging?
60
60
  http_config.try(:call, _http_client_)
@@ -10,7 +10,7 @@ module OpenIDConnect
10
10
 
11
11
  def user_info!(schema = :openid)
12
12
  hash = resource_request do
13
- get client.user_info_uri, :schema => schema
13
+ get client.user_info_uri, schema: schema
14
14
  end
15
15
  ResponseObject::UserInfo::OpenID.new hash
16
16
  end
@@ -21,7 +21,7 @@ module OpenIDConnect
21
21
  res = yield
22
22
  case res.status
23
23
  when 200
24
- JSON.parse(res.body, :symbolize_names => true)
24
+ JSON.parse res.body, symbolize_names: true
25
25
  when 400
26
26
  raise BadRequest.new('API Access Faild', res)
27
27
  when 401
@@ -26,10 +26,10 @@ module OpenIDConnect
26
26
  end
27
27
 
28
28
  def handle_success_response(response)
29
- token_hash = JSON.parse(response.body, :symbolize_names => true)
29
+ token_hash = JSON.parse response.body, symbolize_names: true
30
30
  case token_type = token_hash[:token_type].try(:downcase)
31
31
  when 'bearer'
32
- AccessToken.new token_hash.merge(:client => self)
32
+ AccessToken.new token_hash.merge(client: self)
33
33
  else
34
34
  raise Exception.new("Unexpected Token Type: #{token_type}")
35
35
  end
@@ -54,16 +54,16 @@ module OpenIDConnect
54
54
  alias_method_chain _attr_, :split
55
55
  end
56
56
 
57
- validates :type, :presence => true
58
- validates :client_id, :presence => {:if => lambda { |c| ['client_update', 'rotate_secret'].include?(c.type.to_s) }}
59
- validates :sector_identifier_url, :presence => {:if => :sector_identifier_required?}
57
+ validates :type, presence: true
58
+ validates :client_id, presence: {if: ->(c) { ['client_update', 'rotate_secret'].include?(c.type.to_s) }}
59
+ validates :sector_identifier_url, presence: {if: :sector_identifier_required?}
60
60
 
61
- validates :type, :inclusion => {:in => ['client_associate', 'rotate_secret', 'client_update']}
62
- validates :application_type, :inclusion => {:in => ['native', 'web']}, :allow_nil => true
63
- validates :user_id_type, :inclusion => {:in => ['pairwise', 'public']}, :allow_nil => true
64
- validates :token_endpoint_auth_type, :inclusion => {
65
- :in => ['client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt']
66
- }, :allow_nil => true
61
+ validates :type, inclusion: {in: ['client_associate', 'rotate_secret', 'client_update']}
62
+ validates :application_type, inclusion: {in: ['native', 'web']}, allow_nil: true
63
+ validates :user_id_type, inclusion: {in: ['pairwise', 'public']}, allow_nil: true
64
+ validates :token_endpoint_auth_type, inclusion: {
65
+ in: ['client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt']
66
+ }, allow_nil: true
67
67
 
68
68
  validates(
69
69
  :logo_url,
@@ -73,7 +73,8 @@ module OpenIDConnect
73
73
  :x509_url,
74
74
  :x509_encryption_url,
75
75
  :sector_identifier_url,
76
- :url => true, :allow_nil => true
76
+ url: true,
77
+ allow_nil: true
77
78
  )
78
79
 
79
80
  validate :validate_contacts
@@ -209,7 +210,7 @@ module OpenIDConnect
209
210
  access_token
210
211
  else
211
212
  Rack::OAuth2::AccessToken::Bearer.new(
212
- :access_token => access_token
213
+ access_token: access_token
213
214
  )
214
215
  end
215
216
  end
@@ -225,11 +226,11 @@ module OpenIDConnect
225
226
  end
226
227
 
227
228
  def handle_success_response(response)
228
- credentials = JSON.parse(response.body, :symbolize_names => true)
229
+ credentials = JSON.parse response.body, symbolize_names: true
229
230
  Client.new(
230
- :identifier => credentials[:client_id],
231
- :secret => credentials[:client_secret],
232
- :expires_in => credentials[:expires_in]
231
+ identifier: credentials[:client_id],
232
+ secret: credentials[:client_secret],
233
+ expires_in: credentials[:expires_in]
233
234
  )
234
235
  end
235
236
 
@@ -16,11 +16,11 @@ module OpenIDConnect
16
16
 
17
17
  def discover!(cache_options = {})
18
18
  SWD.discover!(
19
- :principal => identifier,
20
- :service => Provider::SERVICE_URI,
21
- :host => host,
22
- :port => port,
23
- :cache => cache_options
19
+ principal: identifier,
20
+ service: Provider::SERVICE_URI,
21
+ host: host,
22
+ port: port,
23
+ cache: cache_options
24
24
  )
25
25
  rescue SWD::Exception => e
26
26
  raise DiscoveryFailed.new(e.message)
@@ -4,7 +4,7 @@ module OpenIDConnect
4
4
  class Config
5
5
  def self.discover!(identifier, cache_options = {})
6
6
  principal = Principal.parse(identifier)
7
- Resource.new(principal.host).discover!(cache_options)
7
+ Resource.new(principal).discover!(cache_options)
8
8
  rescue SWD::Exception => e
9
9
  raise DiscoveryFailed.new(e.message)
10
10
  end
@@ -7,14 +7,15 @@ module OpenIDConnect
7
7
 
8
8
  class Expired < SWD::Resource::Expired; end
9
9
 
10
- def initialize(host)
11
- @host = host
10
+ def initialize(principal)
11
+ @host = principal.host
12
+ @port = principal.port unless [80, 443].include?(principal.port)
12
13
  @path ||= '/.well-known/openid-configuration'
13
14
  attr_missing!
14
15
  end
15
16
 
16
17
  def endpoint
17
- SWD.url_builder.build [nil, host, nil, path, nil, nil]
18
+ SWD.url_builder.build [nil, host, port, path, nil, nil]
18
19
  rescue URI::Error => e
19
20
  raise SWD::Exception.new(e.message)
20
21
  end
@@ -17,7 +17,7 @@ module OpenIDConnect
17
17
  :jwk_url,
18
18
  :jwk_encryption_url,
19
19
  :x509_url,
20
- :x509_encryption_ur,
20
+ :x509_encryption_url,
21
21
  :registration_endpoint,
22
22
  :scopes_supported,
23
23
  :response_types_supported,
@@ -52,6 +52,46 @@ module OpenIDConnect
52
52
  value.nil?
53
53
  end
54
54
  end
55
+
56
+ def signing_key
57
+ x509_public_key || jwk_public_key
58
+ end
59
+
60
+ def encryption_key
61
+ if x509_encryption_url
62
+ x509_public_key :for_encryption
63
+ elsif jwk_encryption_url
64
+ jwk_public_key :for_encryption
65
+ else
66
+ signing_key
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def x509_public_key(for_encryption = false)
73
+ endpoint = if for_encryption
74
+ x509_encryption_url || x509_url
75
+ else
76
+ x509_url
77
+ end
78
+ if endpoint
79
+ cert = OpenSSL::X509::Certificate.new OpenIDConnect.http_client.get_content(endpoint)
80
+ cert.public_key
81
+ end
82
+ end
83
+
84
+ def jwk_public_key(for_encryption = false)
85
+ endpoint = if for_encryption
86
+ jwk_encryption_url || jwk_url
87
+ else
88
+ jwk_url
89
+ end
90
+ if endpoint
91
+ jwk_set = JSON.parse OpenIDConnect.http_client.get_content(endpoint), symbolize_names: true
92
+ JSON::JWK.decode jwk_set[:keys].first
93
+ end
94
+ end
55
95
  end
56
96
  end
57
97
  end
@@ -15,11 +15,11 @@ module OpenIDConnect
15
15
  _claims_[key] = case value
16
16
  when :optional, :voluntary
17
17
  {
18
- :essential => false
18
+ essential: false
19
19
  }
20
20
  when :required, :essential
21
21
  {
22
- :essential => true
22
+ essential: true
23
23
  }
24
24
  else
25
25
  value
@@ -40,7 +40,7 @@ module OpenIDConnect
40
40
  public_key = JSON::JWK.decode jwk
41
41
  user_id_base_string = case public_key
42
42
  when OpenSSL::PKey::RSA
43
- [jwk[:mod], jwk[:exp]].join
43
+ [jwk[:mod], jwk[:xpo]].join
44
44
  when OpenSSL::PKey::EC
45
45
  raise NotImplementedError.new('Not Implemented Yet')
46
46
  else
@@ -24,11 +24,11 @@ module OpenIDConnect
24
24
  :phone_number
25
25
  )
26
26
 
27
- validates :email_verified, :inclusion => {:in => [true, false]}, :allow_nil => true
28
- validates :gender, :inclusion => {:in => ['male', 'female']}, :allow_nil => true
29
- validates :zoneinfo, :inclusion => {:in => TZInfo::TimezoneProxy.all.collect(&:name)}, :allow_nil => true
30
- validates :profile, :picture, :website, :url => true, :allow_nil => true
31
- validates :email, :email => true, :allow_nil => true
27
+ validates :email_verified, inclusion: {in: [true, false]}, allow_nil: true
28
+ validates :gender, inclusion: {in: ['male', 'female']}, allow_nil: true
29
+ validates :zoneinfo, inclusion: {in: TZInfo::TimezoneProxy.all.collect(&:name)}, allow_nil: true
30
+ validates :profile, :picture, :website, url: true, allow_nil: true
31
+ validates :email, email: true, allow_nil: true
32
32
  validate :validate_address
33
33
  validate :require_at_least_one_attributes
34
34
  # TODO: validate locale
@@ -4,13 +4,13 @@ module Rack
4
4
  class Authorize
5
5
  module ErrorWithConnectExt
6
6
  DEFAULT_DESCRIPTION = {
7
- :invalid_redirect_uri => 'The redirect_uri in the request does not match any of pre-registered redirect_uris.',
8
- :interaction_required => 'End-User interaction required.',
9
- :login_required => 'End-User authentication required.',
10
- :session_selection_required => 'The End-User is required to select a session at the Authorization Server.',
11
- :consent_required => 'End-User consent required.',
12
- :invalid_request_uri => 'The request_uri in the request returns an error or invalid data.',
13
- :invalid_openid_request_object => 'The request parameter contains an invalid OpenID Request Object.'
7
+ invalid_redirect_uri: 'The redirect_uri in the request does not match any of pre-registered redirect_uris.',
8
+ interaction_required: 'End-User interaction required.',
9
+ login_required: 'End-User authentication required.',
10
+ session_selection_required: 'The End-User is required to select a session at the Authorization Server.',
11
+ consent_required: 'End-User consent required.',
12
+ invalid_request_uri: 'The request_uri in the request returns an error or invalid data.',
13
+ invalid_openid_request_object: 'The request parameter contains an invalid OpenID Request Object.'
14
14
  }
15
15
 
16
16
  def self.included(klass)
@@ -9,7 +9,7 @@ module Rack::OAuth2::Server
9
9
 
10
10
  def protocol_params_with_id_token
11
11
  protocol_params_without_id_token.merge(
12
- :id_token => id_token
12
+ id_token: id_token
13
13
  )
14
14
  end
15
15
  alias_method_chain :protocol_params, :id_token
@@ -20,11 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency "swd", ">= 0.1.2"
21
21
  s.add_runtime_dependency "rack-oauth2", ">= 0.14.2"
22
22
  s.add_development_dependency "rake", ">= 0.8"
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
28
23
  s.add_development_dependency "rspec", ">= 2"
29
24
  s.add_development_dependency "webmock", ">= 1.6.2"
25
+ s.add_development_dependency "cover_me", ">= 1.2.0"
30
26
  end
@@ -0,0 +1,7 @@
1
+ {
2
+ "keys": [{
3
+ "alg": "RSA",
4
+ "xpo": "AQAB",
5
+ "mod": "u4liYNFzgsRr1ERdUY7CY6r4nefi3RzIhK5fdPgdZSMEEflACWAuJu21_TcDpbZ1-6Kbq7zShFsVTAnBkWdO7EP1Rsn11fZpi9m_zEq_uRY-4RpNwp3S9xSdoQ4F3-js1EMaDQ6km0-c0gvr_TyhFqDj_6w_Bb0vFptfGXwfKewPPnhsi7GJ62ihZ32PzxOvEIYcaoXr9xaeudYD3BzWSDmjKGA7PMaEuBhScdUAoibCmsKB-yAGsz2amHnUhcl4B_EBs6wk65Y7ge0ZQJUOGPdUQL49VuALKmr7cMhHKh5KuQmPAi_20K2uZL_EFDaObDWZrclx98s0DmfTRKINtw"
6
+ }]
7
+ }
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDeDCCAmACCQDFeFSXWEnHxDANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJK
3
+ UDEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB1NoaWJ1eWExITAfBgNVBAoMGElu
4
+ dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAwwDTm92MRwwGgYJKoZIhvcN
5
+ AQkBFg1ub3ZAbWF0YWtlLmpwMB4XDTExMDkxMzEzMjIzNFoXDTEyMDkxMjEzMjIz
6
+ NFowfjELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdTaGli
7
+ dXlhMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDDAKBgNVBAMM
8
+ A05vdjEcMBoGCSqGSIb3DQEJARYNbm92QG1hdGFrZS5qcDCCASIwDQYJKoZIhvcN
9
+ AQEBBQADggEPADCCAQoCggEBAKSsm7NFmh1P8uHB8Vm5vFs4+uh7XMhZ+xYd5/vf
10
+ ak17ucjWt9DEWCGH0g8HvSVXNSVKBsONcqtkrXRgSeNB8YnIYxPmKKX7twefEJYC
11
+ b06FG1g+IJkwxoDBsUMbb9RJ9snnWsp0O97A6SCvtdiSQ2Oeab3/jwokkPTo8WS4
12
+ lRipQpQ7rOOP7r9t+9G/SDdiYhDhfmuyQamkxGCz6V2qClg0pyTaJ6+/bS9E+4ri
13
+ ZjtZe9OaDt2NE0PiDS2Oo5yhv0abL8rxjZ8D/aTL3D9aYSrFmddKH7roSRkafCMU
14
+ C/UX80/OzrxdEQUjtVO94dPWD/nKK1g7JyiIuk280aTeWA8CAwEAATANBgkqhkiG
15
+ 9w0BAQsFAAOCAQEAdiNDw9z6U8lIF0NWVObeGqoxn/MSp/W5S56ts3agw0meqc1J
16
+ gUPkncXbpjZ/wX0Y3pupmGBIO0XAHPhjyCu3HhplhaVxSNqKEg9wB3huYaMZ2Kbi
17
+ +Wy77hLO2hOYk8vI/ok5oW0lhhpA0o4GzbyV4SA3nZgT0u8YXC7cqAHqI9KsBU5z
18
+ 62mjlptCR/b10xTlC13AtbdDM6s1hWP9XpDrm6Kxgfu7nKQ1Q31ag1Ukm9Gw8qcl
19
+ ILxZxqbqGy/q1C+6ObTmGtiVbJTs+W8u5BPg9S49O6qIhVN5wWCT4lRrlpXpYA3a
20
+ TTVBULB1g7Iod2g+kF0qAXnwqGvZ5LOgwFfmcw==
21
+ -----END CERTIFICATE-----