Skip to content

Commit

Permalink
Extract claims validation into class
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesstonehill committed Jan 26, 2019
1 parent 6a4d62f commit b2315c8
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 15 deletions.
31 changes: 31 additions & 0 deletions lib/jwt/claims_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require_relative './error'

module JWT
class ClaimsValidator
INTEGER_CLAIMS = %i[
exp
]

def initialize(payload)
@payload = payload.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
end

def validate!
validate_int_claims

true
end

private

def validate_int_claims
INTEGER_CLAIMS.each do |claim|
validate_is_int(claim) if @payload.key?(claim)
end
end

def validate_is_int(claim)
raise InvalidPayload, "#{claim} claim must be an integer" unless @payload[:exp].is_a?(Integer)
end
end
end
21 changes: 6 additions & 15 deletions lib/jwt/encode.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# frozen_string_literal: true

require_relative './claims_validator'

# JWT::Encode module
module JWT
# Encoding logic for JWT
class Encode
ALG_NONE = 'none'.freeze
ALG_KEY = 'alg'.freeze
EXP_KEY = 'exp'.freeze
EXP_KEYS = [EXP_KEY, EXP_KEY.to_sym].freeze

def initialize(options)
@payload = options[:payload]
Expand All @@ -22,18 +22,6 @@ def segments

private

def validate_payload!
return unless @payload && @payload.is_a?(Hash)

validate_exp!
end

def validate_exp!
return if EXP_KEYS.all? { |key| !@payload.key?(key) || @payload[key].is_a?(Integer) }

raise InvalidPayload, 'exp claim must be an integer'
end

def encoded_header
@encoded_header ||= encode_header
end
Expand All @@ -55,7 +43,10 @@ def encode_header
end

def encode_payload
validate_payload!
if @payload && @payload.is_a?(Hash)
ClaimsValidator.new(@payload).validate!
end

encode(@payload)
end

Expand Down
33 changes: 33 additions & 0 deletions spec/jwt/claims_validator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'spec_helper'
require 'jwt/claims_validator'

RSpec.describe JWT::ClaimsValidator do
describe '#validate!' do
it 'returns true if the payload is valid' do
valid_payload = { 'exp' => 12345 }
subject = described_class.new(valid_payload)

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' })
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 })
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 })
expect { symbol.validate! }.to raise_error JWT::InvalidPayload

string = described_class.new({ 'exp' => true })
expect { string.validate! }.to raise_error JWT::InvalidPayload
end
end
end
end

0 comments on commit b2315c8

Please sign in to comment.