From 9f9913eed07e6dd5f2b938de331a3bb4054f624b Mon Sep 17 00:00:00 2001 From: James Stonehill Date: Sat, 26 Jan 2019 14:00:57 +0000 Subject: [PATCH] Validate iat and nbf claims like we are doing for exp --- lib/jwt/claims_validator.rb | 6 ++++-- spec/jwt/claims_validator_spec.rb | 28 ++++++++++++++++++++-------- spec/jwt_spec.rb | 31 +++++++++++-------------------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/lib/jwt/claims_validator.rb b/lib/jwt/claims_validator.rb index 5e2ad573..8891adfb 100644 --- a/lib/jwt/claims_validator.rb +++ b/lib/jwt/claims_validator.rb @@ -4,7 +4,9 @@ module JWT class ClaimsValidator INTEGER_CLAIMS = %i[ exp - ] + iat + nbf + ].freeze def initialize(payload) @payload = payload.each_with_object({}) { |(k, v), h| h[k.to_sym] = v } @@ -25,7 +27,7 @@ def validate_int_claims end def validate_is_int(claim) - raise InvalidPayload, "#{claim} claim must be an integer" unless @payload[:exp].is_a?(Integer) + raise InvalidPayload, "#{claim} claim must be an Integer but it is a #{@payload[claim].class}" unless @payload[claim].is_a?(Integer) end end end diff --git a/spec/jwt/claims_validator_spec.rb b/spec/jwt/claims_validator_spec.rb index 4436ee42..b5a04379 100644 --- a/spec/jwt/claims_validator_spec.rb +++ b/spec/jwt/claims_validator_spec.rb @@ -10,24 +10,36 @@ expect(subject.validate!).to eq(true) end - context "exp validation" do - it 'raises an error when the value of the exp claim is a string' do - subject = described_class.new({ exp: '1' }) + shared_examples_for 'an integer claim' do |claim| + it "raises an error when the value of the #{claim} claim is a string" do + subject = described_class.new({ claim => '1' }) expect { subject.validate! }.to raise_error JWT::InvalidPayload end - it 'raises an error when the value of the exp claim is a Time object' do - subject = described_class.new({ exp: Time.now }) + it "raises an error when the value of the #{claim} claim is a Time object" do + subject = described_class.new({ claim => Time.now }) expect { subject.validate! }.to raise_error JWT::InvalidPayload end - it 'validates the exp when the exp key is either a string or a symbol' do - symbol = described_class.new({ exp: true }) + it "validates the #{claim} claim when the key is either a string or a symbol" do + symbol = described_class.new({ claim.to_sym => true }) expect { symbol.validate! }.to raise_error JWT::InvalidPayload - string = described_class.new({ 'exp' => true }) + string = described_class.new({ claim.to_s => true }) expect { string.validate! }.to raise_error JWT::InvalidPayload end end + + context 'exp claim' do + it_should_behave_like 'an integer claim', :exp + end + + context 'iat claim' do + it_should_behave_like 'an integer claim', :iat + end + + context 'nbf claim' do + it_should_behave_like 'an integer claim', :nbf + end end end diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index 17c9ae36..1592c731 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -60,30 +60,21 @@ end context 'payload validation' do - subject { JWT.encode(payload, nil, 'none') } - let(:payload) { { 'exp' => exp } } + it 'validates the payload with the ClaimsValidator if the payload is a hash' do + validator = double() + expect(JWT::ClaimsValidator).to receive(:new) { validator } + expect(validator).to receive(:validate!) { true } - context 'when exp is given as a non Integer' do - let(:exp) { Time.now.to_i.to_s } - it 'raises an JWT::InvalidPayload error' do - expect { subject }.to raise_error(JWT::InvalidPayload, 'exp claim must be an integer') - end - end - - context 'when exp is given as an Integer' do - let(:exp) { 1234 } - - it 'encodes the payload' do - expect(subject).to be_a(String) - end + payload = {} + JWT.encode payload, "secret", JWT::Algos::Hmac::SUPPORTED.sample end - context 'when the key for exp is a symbol' do - let(:payload) { { :exp => 'NotAInteger' } } + it 'does not validate the payload if it is not present' do + validator = double() + expect(JWT::ClaimsValidator).not_to receive(:new) { validator } - it 'raises an JWT::InvalidPayload error' do - expect { subject }.to raise_error(JWT::InvalidPayload, 'exp claim must be an integer') - end + payload = nil + JWT.encode payload, "secret", JWT::Algos::Hmac::SUPPORTED.sample end end