Skip to content

Commit 9d87ff6

Browse files
committed
add a Wrapper for older algorithm
1 parent 9eb5051 commit 9d87ff6

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

lib/jwt/jwa.rb

+39-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,49 @@ def resolve(algorithm)
3030

3131
unless algorithm.is_a?(SigningAlgorithm)
3232
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm')
33-
algorithm.extend(SigningAlgorithm)
33+
return Wrapper.new(algorithm)
3434
end
3535

3636
algorithm
3737
end
3838
end
39+
40+
class Wrapper
41+
include SigningAlgorithm
42+
43+
def initialize(algorithm)
44+
@algorithm = algorithm
45+
end
46+
47+
def alg
48+
return @algorithm.alg if @algorithm.respond_to?(:alg)
49+
50+
super
51+
end
52+
53+
def valid_alg?(*args, **kwargs)
54+
return @algorithm.valid_alg?(*args, **kwargs) if @algorithm.respond_to?(:valid_alg?)
55+
56+
super
57+
end
58+
59+
def header(*args, **kwargs)
60+
return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)
61+
62+
super
63+
end
64+
65+
def sign(*args, **kwargs)
66+
return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)
67+
68+
super
69+
end
70+
71+
def verify(*args, **kwargs)
72+
return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)
73+
74+
super
75+
end
76+
end
3977
end
4078
end

lib/jwt/jwa/signing_algorithm.rb

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ def header(*)
2323
{ 'alg' => alg }
2424
end
2525

26+
def sign(*)
27+
raise EncodeError, 'Algorithm implementation is missing the sign method'
28+
end
29+
30+
def verify(*)
31+
raise DecodeError, 'Algorithm implementation is missing the verify method'
32+
end
33+
2634
def raise_verify_error!(message)
2735
raise(DecodeError.new(message).tap { |e| e.set_backtrace(caller(1)) })
2836
end

spec/jwt/jwt_spec.rb

+13-4
Original file line numberDiff line numberDiff line change
@@ -902,19 +902,30 @@ def header(*)
902902
context 'when class is not utilizing the ::JWT::JWA::SigningAlgorithm module' do
903903
let(:custom_algorithm) do
904904
Class.new do
905+
attr_reader :alg
906+
905907
def initialize(signature: 'custom_signature', alg: 'custom')
906908
@signature = signature
907909
@alg = alg
908910
end
909911

912+
def header(*)
913+
{ 'alg' => @alg, 'foo' => 'bar' }
914+
end
915+
910916
def sign(*)
911917
@signature
912918
end
919+
920+
def verify(*)
921+
true
922+
end
913923
end
914924
end
915925

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

@@ -937,9 +948,8 @@ def sign(*)
937948
end
938949
end
939950

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

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

961-
# This behaviour should be somehow nicer
962971
it 'raises error on decoding' do
963-
expect { JWT.decode(expected_token, 'secret', true, algorithm: custom_algorithm.new) }.to raise_error(NoMethodError)
972+
expect { JWT.decode(expected_token, 'secret', true, algorithm: custom_algorithm.new) }.to raise_error(JWT::DecodeError, /missing the verify method/)
964973
end
965974
end
966975
end

0 commit comments

Comments
 (0)