Skip to content

Commit

Permalink
add a Wrapper for older algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
MatteoPierro committed Aug 31, 2024
1 parent 9eb5051 commit 9d87ff6
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
40 changes: 39 additions & 1 deletion lib/jwt/jwa.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,49 @@ def resolve(algorithm)

unless algorithm.is_a?(SigningAlgorithm)
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm')
algorithm.extend(SigningAlgorithm)
return Wrapper.new(algorithm)
end

algorithm
end
end

class Wrapper
include SigningAlgorithm

def initialize(algorithm)
@algorithm = algorithm
end

def alg
return @algorithm.alg if @algorithm.respond_to?(:alg)

super
end

def valid_alg?(*args, **kwargs)
return @algorithm.valid_alg?(*args, **kwargs) if @algorithm.respond_to?(:valid_alg?)

super
end

def header(*args, **kwargs)
return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)

super
end

def sign(*args, **kwargs)
return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)

super
end

def verify(*args, **kwargs)
return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)

super
end
end
end
end
8 changes: 8 additions & 0 deletions lib/jwt/jwa/signing_algorithm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ def header(*)
{ 'alg' => alg }
end

def sign(*)
raise EncodeError, 'Algorithm implementation is missing the sign method'
end

def verify(*)
raise DecodeError, 'Algorithm implementation is missing the verify method'
end

def raise_verify_error!(message)
raise(DecodeError.new(message).tap { |e| e.set_backtrace(caller(1)) })
end
Expand Down
17 changes: 13 additions & 4 deletions spec/jwt/jwt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -902,19 +902,30 @@ def header(*)
context 'when class is not utilizing the ::JWT::JWA::SigningAlgorithm module' do
let(:custom_algorithm) do
Class.new do
attr_reader :alg

def initialize(signature: 'custom_signature', alg: 'custom')
@signature = signature
@alg = alg
end

def header(*)
{ 'alg' => @alg, 'foo' => 'bar' }
end

def sign(*)
@signature
end

def verify(*)
true
end
end
end

it 'emits a deprecation warning' do
expect { token }.to output("[DEPRECATION WARNING] Custom algorithms are required to include JWT::JWA::SigningAlgorithm\n").to_stderr
expect(JWT.decode(token, 'secret', true, algorithm: custom_algorithm.new)).to eq([payload, { 'alg' => 'custom', 'foo' => 'bar' }])
end
end

Expand All @@ -937,9 +948,8 @@ def sign(*)
end
end

# This behaviour should be somehow nicer
it 'raises an error on encoding' do
expect { token }.to raise_error(NoMethodError)
expect { token }.to raise_error(JWT::EncodeError, /missing the sign method/)
end

it 'allows decoding' do
Expand All @@ -958,9 +968,8 @@ def sign(*)
expect(token).to eq(expected_token)
end

# This behaviour should be somehow nicer
it 'raises error on decoding' do
expect { JWT.decode(expected_token, 'secret', true, algorithm: custom_algorithm.new) }.to raise_error(NoMethodError)
expect { JWT.decode(expected_token, 'secret', true, algorithm: custom_algorithm.new) }.to raise_error(JWT::DecodeError, /missing the verify method/)
end
end
end
Expand Down

0 comments on commit 9d87ff6

Please sign in to comment.