Skip to content

Commit

Permalink
Merge pull request #167 from excpt/master
Browse files Browse the repository at this point in the history
Fix rubocop code smells
  • Loading branch information
excpt authored Sep 17, 2016
2 parents 5f14f08 + 4de3018 commit 5e0de82
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 57 deletions.
74 changes: 33 additions & 41 deletions lib/jwt.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'base64'
require 'openssl'
require 'jwt/decode'
Expand All @@ -17,6 +18,17 @@ module JWT
'secp521r1' => 'ES512'
}.freeze

DEFAULT_OPTIONS = {
verify_expiration: true,
verify_not_before: true,
verify_iss: false,
verify_iat: false,
verify_jti: false,
verify_aud: false,
verify_sub: false,
leeway: 0
}.freeze

module_function

def sign(algorithm, msg, key)
Expand Down Expand Up @@ -73,7 +85,7 @@ def encoded_header(algorithm = 'HS256', header_fields = {})
end

def encoded_payload(payload)
raise InvalidPayload, "exp claim must be an integer" if payload['exp'] && payload['exp'].is_a?(Time)
raise InvalidPayload, 'exp claim must be an integer' if payload['exp'] && payload['exp'].is_a?(Time)
base64url_encode(encode_json(payload))
end

Expand All @@ -98,64 +110,48 @@ def encode(payload, key, algorithm = 'HS256', header_fields = {})
def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt

options = {
verify_expiration: true,
verify_not_before: true,
verify_iss: false,
verify_iat: false,
verify_jti: false,
verify_aud: false,
verify_sub: false,
leeway: 0
}

merged_options = options.merge(custom_options)
merged_options = DEFAULT_OPTIONS.merge(custom_options)

decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
decoder.decode_segments
end


def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt

options = {
verify_expiration: true,
verify_not_before: true,
verify_iss: false,
verify_iat: false,
verify_jti: false,
verify_aud: false,
verify_sub: false,
leeway: 0
}

merged_options = options.merge(custom_options)

merged_options = DEFAULT_OPTIONS.merge(custom_options)
decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
header, payload, signature, signing_input = decoder.decode_segments

if verify
algo, key = signature_algorithm_and_key(header, key, &keyfinder)
if merged_options[:algorithm] && algo != merged_options[:algorithm]
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm'
end
verify_signature(algo, key, signing_input, signature)
end

decode_verify_signature(key, header, signature, signing_input, merged_options, &keyfinder) if verify
decoder.verify

raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload

[payload, header]
end

def decode_verify_signature(key, header, signature, signing_input, options, &keyfinder)
algo, key = signature_algorithm_and_key(header, key, &keyfinder)
if options[:algorithm] && algo != options[:algorithm]
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm'
end
verify_signature(algo, key, signing_input, signature)
end

def signature_algorithm_and_key(header, key, &keyfinder)
key = yield(header) if keyfinder
[header['alg'], key]
end

def verify_signature(algo, key, signing_input, signature)
verify_signature_algo(algo, key, signing_input, signature)
rescue OpenSSL::PKey::PKeyError
raise JWT::VerificationError, 'Signature verification raised'
ensure
OpenSSL.errors.clear
end

def verify_signature_algo(algo, key, signing_input, signature)
if %w(HS256 HS384 HS512).include?(algo)
raise(JWT::VerificationError, 'Signature verification raised') unless secure_compare(signature, sign_hmac(algo, signing_input, key))
elsif %w(RS256 RS384 RS512).include?(algo)
Expand All @@ -165,10 +161,6 @@ def verify_signature(algo, key, signing_input, signature)
else
raise JWT::VerificationError, 'Algorithm not supported'
end
rescue OpenSSL::PKey::PKeyError
raise JWT::VerificationError, 'Signature verification raised'
ensure
OpenSSL.errors.clear
end

# From devise
Expand All @@ -179,7 +171,7 @@ def secure_compare(a, b)

res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
res == 0
res.zero?
end

def raw_to_asn1(signature, private_key)
Expand Down
5 changes: 3 additions & 2 deletions lib/jwt/decode.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'jwt/json'
require 'jwt/verify'

Expand Down Expand Up @@ -28,7 +29,7 @@ def decode_segments
def raw_segments(jwt, verify)
segments = jwt.split('.')
required_num_segments = verify ? [3] : [2, 3]
fail(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
raise(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
segments
end
private :raw_segments
Expand All @@ -47,7 +48,7 @@ def self.base64url_decode(str)

def verify
@options.each do |key, val|
next unless key.to_s.match(/verify/)
next unless key.to_s =~ /verify/

Verify.send(key, payload, @options) if val
end
Expand Down
1 change: 1 addition & 0 deletions lib/jwt/error.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module JWT
class DecodeError < StandardError; end
class VerificationError < DecodeError; end
Expand Down
1 change: 1 addition & 0 deletions lib/jwt/json.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'json'

module JWT
Expand Down
24 changes: 11 additions & 13 deletions lib/jwt/verify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,7 @@ def verify_aud
return unless (options_aud = extract_option(:aud))

if @payload['aud'].is_a?(Array)
if options_aud.is_a?(Array)
options_aud.each do |aud|
raise(
JWT::InvalidAudError,
'Invalid audience'
) unless @payload['aud'].include?(aud.to_s)
end
else
raise(
JWT::InvalidAudError,
'Invalid audience'
) unless @payload['aud'].include?(options_aud.to_s)
end
verify_aud_array(@payload['aud'], options_aud)
else
raise(
JWT::InvalidAudError,
Expand All @@ -42,6 +30,16 @@ def verify_aud
end
end

def verify_aud_array(audience, options_aud)
if options_aud.is_a?(Array)
options_aud.each do |aud|
raise(JWT::InvalidAudError, 'Invalid audience') unless audience.include?(aud.to_s)
end
else
raise(JWT::InvalidAudError, 'Invalid audience') unless audience.include?(options_aud.to_s)
end
end

def verify_expiration
return unless @payload.include?('exp')

Expand Down
3 changes: 2 additions & 1 deletion lib/jwt/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# encoding: utf-8
# frozen_string_literal: true

# Moments version builder module
module JWT
Expand All @@ -15,7 +16,7 @@ module VERSION
# tiny version
TINY = 6
# alpha, beta, etc. tag
PRE = nil
PRE = nil

# Build version string
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
Expand Down

0 comments on commit 5e0de82

Please sign in to comment.