From 2bcd0c61f03f402273895499b1b7cc77f490ae4b Mon Sep 17 00:00:00 2001 From: nov Date: Wed, 14 Sep 2022 10:09:30 +0900 Subject: [PATCH 01/26] github actions --- .github/workflows/spec.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/spec.yml diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml new file mode 100644 index 0000000..67e0456 --- /dev/null +++ b/.github/workflows/spec.yml @@ -0,0 +1,30 @@ +name: Spec + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + spec: + strategy: + matrix: + os: ['ubuntu-20.04'] + ruby-version: ['2.6', '2.7', '3.0', '3.1'] + # ubuntu 22.04 only supports ssl 3 and thus only ruby 3.1 + include: + - os: 'ubuntu-22.04' + ruby-version: '3.1' + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + - name: Run Specs + run: bundle exec rake spec From 9256db00df3efc46a2aabc04b5736f6093b9e976 Mon Sep 17 00:00:00 2001 From: nov Date: Wed, 14 Sep 2022 10:24:23 +0900 Subject: [PATCH 02/26] goodbye travis --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 848ef6b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -before_install: - - gem install bundler - -rvm: - - 2.6.10 - - 2.7.6 - - 3.0.4 - - 3.1.2 \ No newline at end of file From 16d564879dbbc2e863ba0a0fa223969838ba1940 Mon Sep 17 00:00:00 2001 From: Nov Matake Date: Wed, 14 Sep 2022 10:27:26 +0900 Subject: [PATCH 03/26] Update README.rdoc remove travis badge on readme --- README.rdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rdoc b/README.rdoc index a6c4f13..17eff6a 100644 --- a/README.rdoc +++ b/README.rdoc @@ -2,8 +2,6 @@ OpenID Connect Server & Client Library -{}[https://travis-ci.org/nov/openid_connect] - == Installation gem install openid_connect From 17cc91eead594e6ce67f2db522d911b8db652743 Mon Sep 17 00:00:00 2001 From: nov Date: Fri, 23 Sep 2022 12:49:46 +0900 Subject: [PATCH 04/26] support JSON::JWK::Set::Fetcher for JWKS caching --- .../discovery/provider/config/response.rb | 5 ++++ .../response_object/id_token.rb | 11 +++++-- openid_connect.gemspec | 2 +- .../public_keys/jwks_with_private_key.json | 8 +++++ .../mock_response/public_keys/private_key.pem | 27 +++++++++++++++++ .../response_object/id_token_spec.rb | 29 +++++++++++++++++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 spec/mock_response/public_keys/jwks_with_private_key.json create mode 100644 spec/mock_response/public_keys/private_key.pem diff --git a/lib/openid_connect/discovery/provider/config/response.rb b/lib/openid_connect/discovery/provider/config/response.rb index 88ab403..fefaf99 100644 --- a/lib/openid_connect/discovery/provider/config/response.rb +++ b/lib/openid_connect/discovery/provider/config/response.rb @@ -87,6 +87,11 @@ def jwks JSON::JWK::Set.new @jwks[:keys] end + def jwk(kid) + @jwks ||= {} + @jwks[kid] ||= JSON::JWK::Set::Fetcher.fetch(jwks_uri, kid: kid) + end + def public_keys @public_keys ||= jwks.collect(&:to_key) end diff --git a/lib/openid_connect/response_object/id_token.rb b/lib/openid_connect/response_object/id_token.rb index d4622b1..e06e677 100644 --- a/lib/openid_connect/response_object/id_token.rb +++ b/lib/openid_connect/response_object/id_token.rb @@ -63,11 +63,16 @@ def left_half_hash_of(string, hash_length) end class << self - def decode(jwt_string, key) - if key == :self_issued + def decode(jwt_string, key_or_config) + case key_or_config + when :self_issued decode_self_issued jwt_string + when OpenIDConnect::Discovery::Provider::Config::Response + jwt = JSON::JWT.decode jwt_string, :skip_verification + jwt.verify! key_or_config.jwk(jwt.kid) + new jwt else - new JSON::JWT.decode jwt_string, key + new JSON::JWT.decode jwt_string, key_or_config end end diff --git a/openid_connect.gemspec b/openid_connect.gemspec index a706870..bf948cd 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency "activemodel" s.add_runtime_dependency "validate_url" s.add_runtime_dependency "validate_email" - s.add_runtime_dependency "json-jwt", ">= 1.5.0" + s.add_runtime_dependency "json-jwt", ">= 1.15.0" s.add_runtime_dependency "swd", ">= 1.0.0" s.add_runtime_dependency "webfinger", ">= 1.0.1" s.add_runtime_dependency "rack-oauth2", ">= 1.6.1" diff --git a/spec/mock_response/public_keys/jwks_with_private_key.json b/spec/mock_response/public_keys/jwks_with_private_key.json new file mode 100644 index 0000000..32345d7 --- /dev/null +++ b/spec/mock_response/public_keys/jwks_with_private_key.json @@ -0,0 +1,8 @@ +{ + "keys": [{ + "kty": "RSA", + "e": "AQAB", + "n": "vWr1S4T0jBnYU9PIpUYxT48Ca8HK8aitbmqbTM3t3Zzl1GNpIlyePnwXSL6SgNcVbeRhTfvXZUzH4pP8HzPJdpUHnAeYyCzjz9UNykdFCp2YW676wpLDzMkaU7bYLJxGjZlpHU-UJVIm5KX9-NfMyGbFUOuw4AY-OWp8GxrqwAF4U6bJ86TpO24wMxmgm0Vl72aRMGVJkRz66YLYOPNVjXjOI4bUuxg_o3Px5QASxvDCawMeLR3pLCoQcLAZn6WZx7nX3Wu6QzcY0QCqhqUAeY49QRT83Jdg7WUsNa2Rbegi3jJGJf-t9hEcJPmrI6q9zl6WArUueQHS-XUQWq5ptw", + "kid": "DCmKamGtkGAWz-uujePOp-UeATAeT4fi3KouR78r44I" + }] +} \ No newline at end of file diff --git a/spec/mock_response/public_keys/private_key.pem b/spec/mock_response/public_keys/private_key.pem new file mode 100644 index 0000000..f49ec79 --- /dev/null +++ b/spec/mock_response/public_keys/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvWr1S4T0jBnYU9PIpUYxT48Ca8HK8aitbmqbTM3t3Zzl1GNp +IlyePnwXSL6SgNcVbeRhTfvXZUzH4pP8HzPJdpUHnAeYyCzjz9UNykdFCp2YW676 +wpLDzMkaU7bYLJxGjZlpHU+UJVIm5KX9+NfMyGbFUOuw4AY+OWp8GxrqwAF4U6bJ +86TpO24wMxmgm0Vl72aRMGVJkRz66YLYOPNVjXjOI4bUuxg/o3Px5QASxvDCawMe +LR3pLCoQcLAZn6WZx7nX3Wu6QzcY0QCqhqUAeY49QRT83Jdg7WUsNa2Rbegi3jJG +Jf+t9hEcJPmrI6q9zl6WArUueQHS+XUQWq5ptwIDAQABAoIBAHvDWBUJAVRNSsiy +90XuECggk/9ed0Dg6rjblS9g2kvTyWO1tKsMAyVmpTwVsNnYLxtHfsCajcmVmoEU +Gkc06iy+AWPUnuIkWpGgbss9OAJQqI03Toc1qBO1TqtmK+cyEPNSSpkpNu4PuHPr +dX9TWW2ToNdXuJEX4y5WwlJfiwT6kPdK86IKpPCql1+X/N2nKbn+5OWHTDuW3jLF +H4UoJlUU77VgPedQLF9xr9NXGZbgYdTtsg3GU3k7/xhcetNq22Dtr8vYnX8LcIsZ +9VW+KBRGOwgXTMLuj25VxkFUsJejEoq5+WyHTsSsa4w8Fxyc50GPfZJKh8J2jHiG +8weJUNECgYEA5CoQmUz+8saVg1IwnEgZBSMF1rthMgvuDPhD8PJNaugUCyo9tg0O +AXo9EMOUHmr2vCN8h2MZZuuW0D5np/Z9T102N99mJU6tVMSabBPDUTfxThq4xY48 +VZvS6EOzSomeEbrIDciJghqJIvPxEoqLXY3Zg7kDef7YiqybhZFdlS8CgYEA1IbH +MHKfcL+LAo88y4tgOe6Wn8FRG1K7MHvdR+KErgxBg63I9zmolPsyznjNVKpB9syt +zqkDxBg/jTIctgeziMQNSODQoqRKcgEDePwcu+wBvuV+LJFJoIWFrvIPyZ5yKzeb +Vm1lRMgQfoeAQE4nVYAJG+oTTsFTdEtrHkOW4fkCgYEAsNHcnUFrTvARDH1UiLjj +EvUKYFhEwck3CbwYwxC0aIZEikaJHp3NXd3Cl0xKbKxOXI1Pw4hMNlObQ/Uo1aUT +hb7h9rjda0omz8uxNNK4CihFjFbvHMLXBS1GbJOSzdAKvQi4Yt4nmrk/z+Omzsyp +pq34hLmL9S5H2Ghd+kwmbycCgYBiC1N1PEvl3depdJ8dX80irLj8NljOfBozQdFR +ymRfTvQiZVfjBcyJ/mDv87b2Kh2IV+CPCFXebzlSUB4CtAbVP2zJhD176sMVWPZb +KCOxZi1f/ct5kAUhcre7f5xc7SXKXjrhYlJnqsxBMw2tnOB0hz6sjA4gNPvlGK3w +JkpDMQKBgQCgPoqSjmbroWC9oq5iDwRtx6f6fJG7CE91ZFJulunQj6YWOC3zNHEa +XvPPGM8fZpJS4e8LiPClkk8nsOoC50neEVGZeEuhdP6m6WNPN3SlP7bXozHOJTh0 +mHrk2bUHFlQn8f5KWfLQbdyKBzs7WqCRTOR/gIbfxBlUOs0BN37xhw== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/spec/openid_connect/response_object/id_token_spec.rb b/spec/openid_connect/response_object/id_token_spec.rb index 1aa8809..26238ba 100644 --- a/spec/openid_connect/response_object/id_token_spec.rb +++ b/spec/openid_connect/response_object/id_token_spec.rb @@ -251,6 +251,35 @@ its(:exp) { should == attributes[:exp].to_i } its(:raw_attributes) { should be_instance_of JSON::JWS } + context 'when IdP config is given' do + subject { klass.decode id_token.to_jwt(private_key), idp_config } + let(:jwks) do + jwk_str = File.read(File.join(__dir__, '../../mock_response/public_keys/jwks_with_private_key.json')) + jwk = JSON::JWK::Set.new JSON.parse(jwk_str) + end + let(:private_key) do + OpenSSL::PKey::RSA.new( + File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem')) + ).to_jwk + end + let(:idp_config) do + OpenIDConnect::Discovery::Provider::Config::Response.new( + issuer: attributes[:issuer], + authorization_endpoint: File.join(attributes[:iss], 'authorize'), + jwks_uri: File.join(attributes[:iss], 'jwks'), + response_types_supported: ['code'], + subject_types_supported: ['public'], + id_token_signing_alg_values_supported: ['RS256'] + ) + end + + it do + mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do + should + end + end + end + context 'when self-issued' do context 'when valid' do let(:self_issued) do From a54a2b90b402fe7b4ae653e4d1c23565f136d035 Mon Sep 17 00:00:00 2001 From: nov Date: Fri, 23 Sep 2022 12:51:33 +0900 Subject: [PATCH 05/26] v1.4.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6261a05..e21e727 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.1 \ No newline at end of file +1.4.0 \ No newline at end of file From c4dab9879c67fbcaaeb2e2c7d741c5bbf42a3f7d Mon Sep 17 00:00:00 2001 From: nov Date: Fri, 23 Sep 2022 13:20:48 +0900 Subject: [PATCH 06/26] spec when kid is not given --- .../response_object/id_token_spec.rb | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/spec/openid_connect/response_object/id_token_spec.rb b/spec/openid_connect/response_object/id_token_spec.rb index 26238ba..388b303 100644 --- a/spec/openid_connect/response_object/id_token_spec.rb +++ b/spec/openid_connect/response_object/id_token_spec.rb @@ -257,11 +257,6 @@ jwk_str = File.read(File.join(__dir__, '../../mock_response/public_keys/jwks_with_private_key.json')) jwk = JSON::JWK::Set.new JSON.parse(jwk_str) end - let(:private_key) do - OpenSSL::PKey::RSA.new( - File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem')) - ).to_jwk - end let(:idp_config) do OpenIDConnect::Discovery::Provider::Config::Response.new( issuer: attributes[:issuer], @@ -273,9 +268,33 @@ ) end - it do - mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do - should + context 'when id_token has kid' do + let(:private_key) do + OpenSSL::PKey::RSA.new( + File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem')) + ).to_jwk + end + + it do + mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do + should be_a klass + end + end + end + + context 'otherwise' do + let(:private_key) do + OpenSSL::PKey::RSA.new( + File.read(File.join(__dir__, '../../mock_response/public_keys/private_key.pem')) + ) + end + + it do + mock_json :get, idp_config.jwks_uri, 'public_keys/jwks_with_private_key' do + expect do + should + end.to raise_error JSON::JWK::Set::KidNotFound + end end end end From c594f6367ebcf48813599f1d6b0d6140116c972f Mon Sep 17 00:00:00 2001 From: nov Date: Sat, 1 Oct 2022 20:58:18 +0900 Subject: [PATCH 07/26] action --- .github/workflows/spec.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml index 67e0456..f6b6fda 100644 --- a/.github/workflows/spec.yml +++ b/.github/workflows/spec.yml @@ -2,6 +2,8 @@ name: Spec on: push: + branches: + - master pull_request: permissions: From 05995496be23d676e972ede214b457518869f63c Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 00:03:09 +0900 Subject: [PATCH 08/26] restrict swd & webfinger version newer version of them are using faraday, and this gem isn't ready for that. --- openid_connect.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openid_connect.gemspec b/openid_connect.gemspec index bf948cd..bfa2ff3 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -18,8 +18,8 @@ Gem::Specification.new do |s| s.add_runtime_dependency "validate_url" s.add_runtime_dependency "validate_email" s.add_runtime_dependency "json-jwt", ">= 1.15.0" - s.add_runtime_dependency "swd", ">= 1.0.0" - s.add_runtime_dependency "webfinger", ">= 1.0.1" + s.add_runtime_dependency "swd", "~> 1.3" + s.add_runtime_dependency "webfinger", "~> 1.2" s.add_runtime_dependency "rack-oauth2", ">= 1.6.1" if Gem.ruby_version >= Gem::Version.create(3.1) # TODO: From d8adfef4d6e0a73c14d70827ab2916075be3fa07 Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 00:04:45 +0900 Subject: [PATCH 09/26] v1.4.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e21e727..13175fd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.0 \ No newline at end of file +1.4.1 \ No newline at end of file From b9b310f5d1d0767aa3b65e92288e8eb44bfd797e Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 01:15:32 +0900 Subject: [PATCH 10/26] restrict rack-oauth2 version newer rack-oauth2 uses faraday v2 --- openid_connect.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openid_connect.gemspec b/openid_connect.gemspec index bfa2ff3..0708d4d 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency "json-jwt", ">= 1.15.0" s.add_runtime_dependency "swd", "~> 1.3" s.add_runtime_dependency "webfinger", "~> 1.2" - s.add_runtime_dependency "rack-oauth2", ">= 1.6.1" + s.add_runtime_dependency "rack-oauth2", "~> 1.21" if Gem.ruby_version >= Gem::Version.create(3.1) # TODO: # remove "net-smtp" dependency after mail gem 2.8+ (which supports ruby 3.1+) released. From 83b84596cae1e33d8d0d4b82eeda2a33727a6145 Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 01:16:13 +0900 Subject: [PATCH 11/26] v1.4.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 13175fd..c9929e3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.1 \ No newline at end of file +1.4.2 \ No newline at end of file From ad02a186c15d0be5aa9d037152a0829622c9910f Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 17:04:25 +0900 Subject: [PATCH 12/26] replace httpclient with faraday v2 --- lib/openid_connect.rb | 21 +++++------- lib/openid_connect/debugger.rb | 3 -- lib/openid_connect/debugger/request_filter.rb | 28 ---------------- .../discovery/provider/config/response.rb | 2 +- lib/openid_connect/request_object.rb | 2 +- openid_connect.gemspec | 12 ++++--- spec/helpers/webmock_helper.rb | 8 ++++- spec/openid_connect/client/registrar_spec.rb | 2 +- .../debugger/request_filter_spec.rb | 33 ------------------- spec/openid_connect_spec.rb | 4 +-- 10 files changed, 28 insertions(+), 87 deletions(-) delete mode 100644 lib/openid_connect/debugger.rb delete mode 100644 lib/openid_connect/debugger/request_filter.rb delete mode 100644 spec/openid_connect/debugger/request_filter_spec.rb diff --git a/lib/openid_connect.rb b/lib/openid_connect.rb index 9effa24..ec7bde6 100644 --- a/lib/openid_connect.rb +++ b/lib/openid_connect.rb @@ -1,5 +1,7 @@ require 'json' require 'logger' +require 'faraday' +require 'faraday/follow_redirects' require 'swd' require 'webfinger' require 'active_model' @@ -64,17 +66,13 @@ def self.debug(&block) self.debugging = false def self.http_client - _http_client_ = HTTPClient.new( - agent_name: "OpenIDConnect (#{VERSION})" - ) - - # NOTE: httpclient gem seems stopped maintaining root certtificate set, use OS default. - _http_client_.ssl_config.clear_cert_store - _http_client_.ssl_config.cert_store.set_default_paths - - _http_client_.request_filter << Debugger::RequestFilter.new if debugging? - http_config.try(:call, _http_client_) - _http_client_ + Faraday.new(headers: {user_agent: "OpenIDConnect (#{VERSION})"}) do |faraday| + faraday.request :url_encoded + faraday.request :json + faraday.response :logger, OpenIDConnect.logger, {bodies: true} if debugging? + faraday.adapter Faraday.default_adapter + http_config&.call(faraday) + end end def self.http_config(&block) @sub_protocols.each do |klass| @@ -100,4 +98,3 @@ def self.validate_discovery_issuer require 'openid_connect/jwtnizable' require 'openid_connect/connect_object' require 'openid_connect/discovery' -require 'openid_connect/debugger' diff --git a/lib/openid_connect/debugger.rb b/lib/openid_connect/debugger.rb deleted file mode 100644 index bd33915..0000000 --- a/lib/openid_connect/debugger.rb +++ /dev/null @@ -1,3 +0,0 @@ -Dir[File.dirname(__FILE__) + '/debugger/*.rb'].each do |file| - require file -end \ No newline at end of file diff --git a/lib/openid_connect/debugger/request_filter.rb b/lib/openid_connect/debugger/request_filter.rb deleted file mode 100644 index f3b0476..0000000 --- a/lib/openid_connect/debugger/request_filter.rb +++ /dev/null @@ -1,28 +0,0 @@ -module OpenIDConnect - module Debugger - class RequestFilter - # Callback called in HTTPClient (before sending a request) - # request:: HTTP::Message - def filter_request(request) - started = "======= [OpenIDConnect] HTTP REQUEST STARTED =======" - log started, request.dump - end - - # Callback called in HTTPClient (after received a response) - # request:: HTTP::Message - # response:: HTTP::Message - def filter_response(request, response) - finished = "======= [OpenIDConnect] HTTP REQUEST FINISHED =======" - log '-' * 50, response.dump, finished - end - - private - - def log(*outputs) - outputs.each do |output| - OpenIDConnect.logger.info output - end - end - end - end -end \ No newline at end of file diff --git a/lib/openid_connect/discovery/provider/config/response.rb b/lib/openid_connect/discovery/provider/config/response.rb index fefaf99..6590582 100644 --- a/lib/openid_connect/discovery/provider/config/response.rb +++ b/lib/openid_connect/discovery/provider/config/response.rb @@ -82,7 +82,7 @@ def validate! def jwks @jwks ||= JSON.parse( - OpenIDConnect.http_client.get_content(jwks_uri) + OpenIDConnect.http_client.get(jwks_uri).body ).with_indifferent_access JSON::JWK::Set.new @jwks[:keys] end diff --git a/lib/openid_connect/request_object.rb b/lib/openid_connect/request_object.rb index a52dd71..2487cce 100644 --- a/lib/openid_connect/request_object.rb +++ b/lib/openid_connect/request_object.rb @@ -25,7 +25,7 @@ def decode(jwt_string, key = nil) end def fetch(request_uri, key = nil) - jwt_string = OpenIDConnect.http_client.get_content(request_uri) + jwt_string = OpenIDConnect.http_client.get(request_uri).body decode jwt_string, key end end diff --git a/openid_connect.gemspec b/openid_connect.gemspec index 0708d4d..d99db85 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -17,14 +17,16 @@ Gem::Specification.new do |s| s.add_runtime_dependency "activemodel" s.add_runtime_dependency "validate_url" s.add_runtime_dependency "validate_email" - s.add_runtime_dependency "json-jwt", ">= 1.15.0" - s.add_runtime_dependency "swd", "~> 1.3" - s.add_runtime_dependency "webfinger", "~> 1.2" - s.add_runtime_dependency "rack-oauth2", "~> 1.21" + s.add_runtime_dependency 'faraday', '~> 2.0' + s.add_runtime_dependency 'faraday-follow_redirects' + s.add_runtime_dependency "json-jwt", ">= 1.16" + s.add_runtime_dependency "swd", "~> 2.0" + s.add_runtime_dependency "webfinger", "~> 2.0" + s.add_runtime_dependency "rack-oauth2", "~> 2.0" if Gem.ruby_version >= Gem::Version.create(3.1) # TODO: # remove "net-smtp" dependency after mail gem 2.8+ (which supports ruby 3.1+) released. - # ref.) https://rubygems.org/gems/mailhttps://github.com/mikel/mail + # ref.) https://rubygems.org/gems/mail s.add_runtime_dependency "net-smtp" end s.add_development_dependency "rake" diff --git a/spec/helpers/webmock_helper.rb b/spec/helpers/webmock_helper.rb index b08def6..ff0887b 100644 --- a/spec/helpers/webmock_helper.rb +++ b/spec/helpers/webmock_helper.rb @@ -32,7 +32,13 @@ def request_for(method, options = {}) def response_for(response_file, options = {}) response = {} - response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', "#{response_file}.#{options[:format] || :json}")) + format = options[:format] || :json + if format == :json + response[:headers] = { + 'Content-Type': 'application/json' + } + end + response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', "#{response_file}.#{format}")) if options[:status] response[:status] = options[:status] end diff --git a/spec/openid_connect/client/registrar_spec.rb b/spec/openid_connect/client/registrar_spec.rb index 3a1dfea..eda15e3 100644 --- a/spec/openid_connect/client/registrar_spec.rb +++ b/spec/openid_connect/client/registrar_spec.rb @@ -253,7 +253,7 @@ end context 'otherwise' do - it { should be_instance_of HTTPClient } + it { should be_instance_of Faraday::Connection } end end end diff --git a/spec/openid_connect/debugger/request_filter_spec.rb b/spec/openid_connect/debugger/request_filter_spec.rb deleted file mode 100644 index fd4d967..0000000 --- a/spec/openid_connect/debugger/request_filter_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe OpenIDConnect::Debugger::RequestFilter do - let(:resource_endpoint) { 'https://example.com/resources' } - let(:request) { HTTP::Message.new_request(:get, URI.parse(resource_endpoint)) } - let(:response) { HTTP::Message.new_response({hello: 'world'}.to_json) } - let(:request_filter) { OpenIDConnect::Debugger::RequestFilter.new } - - describe '#filter_request' do - it 'should log request' do - [ - "======= [OpenIDConnect] HTTP REQUEST STARTED =======", - request.dump - ].each do |output| - expect(OpenIDConnect.logger).to receive(:info).with output - end - request_filter.filter_request(request) - end - end - - describe '#filter_response' do - it 'should log response' do - [ - "--------------------------------------------------", - response.dump, - "======= [OpenIDConnect] HTTP REQUEST FINISHED =======" - ].each do |output| - expect(OpenIDConnect.logger).to receive(:info).with output - end - request_filter.filter_response(request, response) - end - end -end \ No newline at end of file diff --git a/spec/openid_connect_spec.rb b/spec/openid_connect_spec.rb index 1c238dd..a3a3134 100644 --- a/spec/openid_connect_spec.rb +++ b/spec/openid_connect_spec.rb @@ -46,12 +46,12 @@ context 'with http_config' do before do OpenIDConnect.http_config do |config| - config.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE + config.ssl.verify = false end end it 'should configure OpenIDConnect, SWD and Rack::OAuth2\'s http_client' do [OpenIDConnect, SWD, WebFinger, Rack::OAuth2].each do |klass| - klass.http_client.ssl_config.verify_mode.should == OpenSSL::SSL::VERIFY_NONE + klass.http_client.ssl.verify.should be_falsy end end end From c45cd09a57c1cd116a31085472308ea07b985f31 Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 17:09:38 +0900 Subject: [PATCH 13/26] v2.0.0.rc1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c9929e3..3d8469a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.2 \ No newline at end of file +2.0.0.rc1 \ No newline at end of file From e594af66d576d2afe96beccba96eedfb4aa1699a Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 17:12:58 +0900 Subject: [PATCH 14/26] changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..dd03b16 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +## [Unreleased] + +## [2.0.0.rc1] - 2022-10-09 + +### Added + +- start recording CHANGELOG + +### Changed + +- replace httpclient with faraday v2 by @nov in https://github.com/nov/openid_connect/pull/75 \ No newline at end of file From 69bf87c7338fe72362a6c824ceb49173cc92d9e1 Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 17:42:08 +0900 Subject: [PATCH 15/26] v2.0.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3d8469a..359a5b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0.rc1 \ No newline at end of file +2.0.0 \ No newline at end of file From 16207787f9f92cec1dc3e829c846a4f0ed61732e Mon Sep 17 00:00:00 2001 From: nov Date: Sun, 9 Oct 2022 17:43:14 +0900 Subject: [PATCH 16/26] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd03b16..09aa37e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## [Unreleased] -## [2.0.0.rc1] - 2022-10-09 +## [2.0.0] - 2022-10-09 ### Added From ac71875f05ea7103da0be95b53007d9a2bb0986c Mon Sep 17 00:00:00 2001 From: nov Date: Mon, 10 Oct 2022 01:07:04 +0900 Subject: [PATCH 17/26] mTLS access token close #56 --- lib/openid_connect/access_token.rb | 11 ++++++++++- lib/openid_connect/access_token/mtls.rb | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 lib/openid_connect/access_token/mtls.rb diff --git a/lib/openid_connect/access_token.rb b/lib/openid_connect/access_token.rb index 1e35899..e86ee99 100644 --- a/lib/openid_connect/access_token.rb +++ b/lib/openid_connect/access_token.rb @@ -15,6 +15,13 @@ def userinfo!(params = {}) ResponseObject::UserInfo.new hash end + def to_mtls(attributes = {}) + (required_attributes + optional_attributes).each do |key| + attributes[key] = self.send(key) + end + MTLS.new attributes + end + private def resource_request @@ -33,4 +40,6 @@ def resource_request end end end -end \ No newline at end of file +end + +require 'openid_connect/access_token/mtls' \ No newline at end of file diff --git a/lib/openid_connect/access_token/mtls.rb b/lib/openid_connect/access_token/mtls.rb new file mode 100644 index 0000000..850a716 --- /dev/null +++ b/lib/openid_connect/access_token/mtls.rb @@ -0,0 +1,9 @@ +module OpenIDConnect + class AccessToken::MTLS < AccessToken + def initialize(attributes = {}) + super + http_client.ssl.client_key = attributes[:private_key] || client.private_key + http_client.ssl.client_cert = attributes[:certificate] || client.certificate + end + end +end \ No newline at end of file From 4f3801a2cc87f447ed264e6c4afe07e0113649a4 Mon Sep 17 00:00:00 2001 From: nov Date: Mon, 10 Oct 2022 11:34:08 +0900 Subject: [PATCH 18/26] v2.1.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 359a5b9..50aea0e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 \ No newline at end of file +2.1.0 \ No newline at end of file From ea6d5853fd9341183faee9373241a92e63621bd6 Mon Sep 17 00:00:00 2001 From: nov Date: Mon, 10 Oct 2022 11:35:16 +0900 Subject: [PATCH 19/26] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09aa37e..e7f2147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## [Unreleased] +## [2.1.0] - 2022-10-10 + +### Changed + +- mTLS access token by @nov in https://github.com/nov/openid_connect/pull/76 + ## [2.0.0] - 2022-10-09 ### Added From fee6e2eaec8fd88a4f444272a2acb16c18744622 Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 11 Oct 2022 15:42:52 +0900 Subject: [PATCH 20/26] automatic json response decoding --- lib/openid_connect.rb | 1 + lib/openid_connect/access_token.rb | 2 +- lib/openid_connect/client.rb | 4 +--- lib/openid_connect/client/registrar.rb | 2 +- .../discovery/provider/config/response.rb | 4 +--- spec/mock_response/errors/unknown.json | 4 +++- spec/openid_connect/client_spec.rb | 10 ---------- 7 files changed, 8 insertions(+), 19 deletions(-) diff --git a/lib/openid_connect.rb b/lib/openid_connect.rb index ec7bde6..0ecf2de 100644 --- a/lib/openid_connect.rb +++ b/lib/openid_connect.rb @@ -69,6 +69,7 @@ def self.http_client Faraday.new(headers: {user_agent: "OpenIDConnect (#{VERSION})"}) do |faraday| faraday.request :url_encoded faraday.request :json + faraday.response :json faraday.response :logger, OpenIDConnect.logger, {bodies: true} if debugging? faraday.adapter Faraday.default_adapter http_config&.call(faraday) diff --git a/lib/openid_connect/access_token.rb b/lib/openid_connect/access_token.rb index e86ee99..2b08dfa 100644 --- a/lib/openid_connect/access_token.rb +++ b/lib/openid_connect/access_token.rb @@ -28,7 +28,7 @@ def resource_request res = yield case res.status when 200 - JSON.parse(res.body).with_indifferent_access + res.body.with_indifferent_access when 400 raise BadRequest.new('API Access Faild', res) when 401 diff --git a/lib/openid_connect/client.rb b/lib/openid_connect/client.rb index 75747d6..f325d78 100644 --- a/lib/openid_connect/client.rb +++ b/lib/openid_connect/client.rb @@ -26,7 +26,7 @@ def setup_required_scope(scopes) end def handle_success_response(response) - token_hash = JSON.parse(response.body).with_indifferent_access + token_hash = response.body.with_indifferent_access token_type = (@forced_token_type || token_hash[:token_type]).try(:downcase) case token_type when 'bearer' @@ -34,8 +34,6 @@ def handle_success_response(response) else raise Exception.new("Unexpected Token Type: #{token_type}") end - rescue JSON::ParserError - raise Exception.new("Unknown Token Type") end end end diff --git a/lib/openid_connect/client/registrar.rb b/lib/openid_connect/client/registrar.rb index 1da22c8..3969572 100644 --- a/lib/openid_connect/client/registrar.rb +++ b/lib/openid_connect/client/registrar.rb @@ -170,7 +170,7 @@ def handle_response end def handle_success_response(response) - credentials = JSON.parse(response.body).with_indifferent_access + credentials = response.body.with_indifferent_access Client.new( identifier: credentials[:client_id], secret: credentials[:client_secret], diff --git a/lib/openid_connect/discovery/provider/config/response.rb b/lib/openid_connect/discovery/provider/config/response.rb index 6590582..60697c7 100644 --- a/lib/openid_connect/discovery/provider/config/response.rb +++ b/lib/openid_connect/discovery/provider/config/response.rb @@ -81,9 +81,7 @@ def validate! end def jwks - @jwks ||= JSON.parse( - OpenIDConnect.http_client.get(jwks_uri).body - ).with_indifferent_access + @jwks ||= OpenIDConnect.http_client.get(jwks_uri).body.with_indifferent_access JSON::JWK::Set.new @jwks[:keys] end diff --git a/spec/mock_response/errors/unknown.json b/spec/mock_response/errors/unknown.json index 854f2de..32dcbae 100644 --- a/spec/mock_response/errors/unknown.json +++ b/spec/mock_response/errors/unknown.json @@ -1 +1,3 @@ -Fuckin Unknown Error \ No newline at end of file +{ + "unknown": "unknown" +} \ No newline at end of file diff --git a/spec/openid_connect/client_spec.rb b/spec/openid_connect/client_spec.rb index a095128..1e48cae 100644 --- a/spec/openid_connect/client_spec.rb +++ b/spec/openid_connect/client_spec.rb @@ -162,16 +162,6 @@ end end - context 'when invalid JSON is returned' do - it 'should raise OpenIDConnect::Exception' do - mock_json :post, client.token_endpoint, 'access_token/invalid_json', request_header: header_params, params: protocol_params do - expect do - access_token - end.to raise_error OpenIDConnect::Exception, 'Unknown Token Type' - end - end - end - context 'otherwise' do it 'should raise Unexpected Token Type exception' do mock_json :post, client.token_endpoint, 'access_token/mac', request_header: header_params, params: protocol_params do From 5622c125729f5118aee081c1396cd5615514fb73 Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 11 Oct 2022 15:50:42 +0900 Subject: [PATCH 21/26] require rack-oauth2 v2.2+ --- openid_connect.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openid_connect.gemspec b/openid_connect.gemspec index d99db85..4023cc3 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency "json-jwt", ">= 1.16" s.add_runtime_dependency "swd", "~> 2.0" s.add_runtime_dependency "webfinger", "~> 2.0" - s.add_runtime_dependency "rack-oauth2", "~> 2.0" + s.add_runtime_dependency "rack-oauth2", "~> 2.2" if Gem.ruby_version >= Gem::Version.create(3.1) # TODO: # remove "net-smtp" dependency after mail gem 2.8+ (which supports ruby 3.1+) released. From 45668541caf74df9f20fc420c7c26f715cc27a9a Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 11 Oct 2022 15:50:54 +0900 Subject: [PATCH 22/26] v2.2.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 50aea0e..e3a4f19 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 \ No newline at end of file +2.2.0 \ No newline at end of file From 5d5fbdd52420e3b9ad0c5aba3f609c3085548451 Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 11 Oct 2022 15:51:58 +0900 Subject: [PATCH 23/26] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f2147..7bf2421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## [Unreleased] +## [2.2.0] - 2022-10-11 + +### Changed + +- automatic json response decoding by @nov in https://github.com/nov/openid_connect/pull/77 + ## [2.1.0] - 2022-10-10 ### Changed From 514cc808d1f77b7bcf97c00987b7d3cc73ba5f10 Mon Sep 17 00:00:00 2001 From: nov Date: Sat, 15 Oct 2022 18:20:24 +0900 Subject: [PATCH 24/26] set faraday logger at last, so that faraday-jwt can be logged as JWT string --- lib/openid_connect.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/openid_connect.rb b/lib/openid_connect.rb index 0ecf2de..0ad7b16 100644 --- a/lib/openid_connect.rb +++ b/lib/openid_connect.rb @@ -70,9 +70,9 @@ def self.http_client faraday.request :url_encoded faraday.request :json faraday.response :json - faraday.response :logger, OpenIDConnect.logger, {bodies: true} if debugging? faraday.adapter Faraday.default_adapter http_config&.call(faraday) + faraday.response :logger, OpenIDConnect.logger, {bodies: true} if debugging? end end def self.http_config(&block) From b441ff72b75f778da32c14ac5053f0d25fcacfda Mon Sep 17 00:00:00 2001 From: nov Date: Wed, 18 Jan 2023 10:41:22 +0900 Subject: [PATCH 25/26] mail gem 2.8 is out --- openid_connect.gemspec | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openid_connect.gemspec b/openid_connect.gemspec index 4023cc3..9c63588 100644 --- a/openid_connect.gemspec +++ b/openid_connect.gemspec @@ -23,12 +23,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency "swd", "~> 2.0" s.add_runtime_dependency "webfinger", "~> 2.0" s.add_runtime_dependency "rack-oauth2", "~> 2.2" - if Gem.ruby_version >= Gem::Version.create(3.1) - # TODO: - # remove "net-smtp" dependency after mail gem 2.8+ (which supports ruby 3.1+) released. - # ref.) https://rubygems.org/gems/mail - s.add_runtime_dependency "net-smtp" - end s.add_development_dependency "rake" s.add_development_dependency "rspec" s.add_development_dependency "rspec-its" From 2fdafc3802aca1967790b079cb4e58ce5c4e9c93 Mon Sep 17 00:00:00 2001 From: nov Date: Mon, 23 Jan 2023 15:34:44 +0900 Subject: [PATCH 26/26] add ruby 3.2 to the target, and remove older rubies --- .github/workflows/spec.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml index f6b6fda..19509fb 100644 --- a/.github/workflows/spec.yml +++ b/.github/workflows/spec.yml @@ -13,12 +13,11 @@ jobs: spec: strategy: matrix: - os: ['ubuntu-20.04'] - ruby-version: ['2.6', '2.7', '3.0', '3.1'] - # ubuntu 22.04 only supports ssl 3 and thus only ruby 3.1 + os: ['ubuntu-20.04', 'ubuntu-22.04'] + ruby-version: ['3.1', '3.2'] include: - - os: 'ubuntu-22.04' - ruby-version: '3.1' + - os: 'ubuntu-20.04' + ruby-version: '3.0' runs-on: ${{ matrix.os }} steps: