From f7219a804e7c86a021cd073d169c3fbad2b02f02 Mon Sep 17 00:00:00 2001 From: Joakim Antman Date: Sat, 5 Sep 2026 21:44:55 +0300 Subject: [PATCH] Refactor JWT::JWK::Set#initialize The two construction paths that build keys from hashes had drifted: the JWKS document form skips a key whose kty is unsupported, the array form raises. That is easy to miss when the two are nested blocks in the middle of a case expression, and it is how the gap in #744 came about. Give each branch a named method, so what differs between them is visible in the branch itself. initialize now fits the metrics limits without the Metrics/CyclomaticComplexity exemption it has carried until now. No behaviour change. --- CHANGELOG.md | 1 + lib/jwt/jwk/set.rb | 39 +++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a781344..4efb1dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ **Fixes and enhancements:** +- Refactor `JWT::JWK::Set#initialize` so each construction path is a named method [#758](https://github.com/jwt/ruby-jwt/pull/758) ([@anakinj](https://github.com/anakinj)) - Fix rejection of unknown algorithms from JWKs for RFC compliance and pquip [#728](https://github.com/jwt/ruby-jwt/pull/728) - Fix the `Style/DirectiveScope` RuboCop offense failing the build [#752](https://github.com/jwt/ruby-jwt/pull/752) - Fix `JWT::JWK::Set` sharing its key collection with the set it was copied from [#751](https://github.com/jwt/ruby-jwt/pull/751) diff --git a/lib/jwt/jwk/set.rb b/lib/jwt/jwk/set.rb index c1dff7b5..e2414cfd 100644 --- a/lib/jwt/jwk/set.rb +++ b/lib/jwt/jwk/set.rb @@ -12,25 +12,14 @@ class Set attr_reader :keys - def initialize(jwks = nil, options = {}) # rubocop:disable Metrics/CyclomaticComplexity - jwks ||= {} - + def initialize(jwks = nil, options = {}) @keys = case jwks - when JWT::JWK::Set # Simple duplication - jwks.keys.dup - when JWT::JWK::KeyBase # Singleton - [jwks] - when Hash - jwks = jwks.transform_keys(&:to_sym) - [*jwks[:keys]].each_with_object([]) do |k, arr| - arr << JWT::JWK.new(k, nil, options) - rescue JWT::UnsupportedKeyType - nil - end - when Array - jwks.map { |k| JWT::JWK.new(k, nil, options) } - else - raise ArgumentError, 'Can only create new JWKS from Hash, Array and JWK' + when nil then [] + when JWT::JWK::Set then jwks.keys.dup + when JWT::JWK::KeyBase then [jwks] + when Hash then build_supported_keys(jwks.transform_keys(&:to_sym)[:keys], options) + when Array then build_keys(jwks, options) + else raise ArgumentError, 'Can only create new JWKS from Hash, Array and JWK' end end @@ -88,6 +77,20 @@ def ==(other) alias | union alias + union alias << add + + private + + def build_keys(keys, options) + [*keys].map { |key| JWT::JWK.new(key, nil, options) } + end + + def build_supported_keys(keys, options) + [*keys].each_with_object([]) do |key, arr| + arr << JWT::JWK.new(key, nil, options) + rescue JWT::UnsupportedKeyType + nil + end + end end end end