From aea6da4543e4a8ea6ba81ce797533bf85e6d3940 Mon Sep 17 00:00:00 2001 From: "A.B" Date: Fri, 4 May 2018 12:39:06 -0400 Subject: [PATCH] improving code quality of jwt module --- lib/jwt.rb | 63 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/lib/jwt.rb b/lib/jwt.rb index 730a28cd..75db8379 100644 --- a/lib/jwt.rb +++ b/lib/jwt.rb @@ -22,42 +22,59 @@ def encode(payload, key, algorithm = 'HS256', header_fields = {}) encoder.segments end - def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder) + def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) raise(JWT::DecodeError, 'Nil JSON web token') unless jwt - merged_options = DEFAULT_OPTIONS.merge(custom_options) - - decoder = Decode.new jwt, verify - header, payload, signature, signing_input = decoder.decode_segments - decode_verify_signature(key, header, payload, signature, signing_input, merged_options, &keyfinder) if verify - - Verify.verify_claims(payload, merged_options) if verify + @jwt = jwt + @key = key + @verify = verify + @options = DEFAULT_OPTIONS.merge(options) + @header, + @payload, + @signature, + @signing_input = Decode.new(jwt, verify).decode_segments + if verify? + verify_signature(&keyfinder) + verify_claims + end - raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload + raise(JWT::DecodeError, 'Not enough or too many segments') unless @header && @payload - [payload, header] + [@payload, @header] end + private_class_method + def verify_signature(&keyfinder) + @key = find_key(&keyfinder) if keyfinder - def decode_verify_signature(key, header, payload, signature, signing_input, options, &keyfinder) - algo, key = signature_algorithm_and_key(header, payload, key, &keyfinder) + raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty? + raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless options_includes_algo_in_header? - raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms(options).empty? - raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless allowed_algorithms(options).include?(algo) - - Signature.verify(algo, key, signing_input, signature) + Signature.verify(@header['alg'], @key, @signing_input, @signature) end - def signature_algorithm_and_key(header, payload, key, &keyfinder) - key = (keyfinder.arity == 2 ? yield(header, payload) : yield(header)) if keyfinder + def find_key(&keyfinder) + key = (keyfinder.arity == 2 ? yield(@header, @payload) : yield(@header)) raise JWT::DecodeError, 'No verification key available' unless key - [header['alg'], key] + key end - def allowed_algorithms(options) - if options.key?(:algorithm) - [options[:algorithm]] + def allowed_algorithms + if @options.key?(:algorithm) + [@options[:algorithm]] else - options[:algorithms] || [] + @options[:algorithms] || [] end end + + def verify? + @verify + end + + def verify_claims + Verify.verify_claims(@payload, @options) + end + + def options_includes_algo_in_header? + allowed_algorithms.include? @header['alg'] + end end