json_web_token 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,84 +0,0 @@
1
- require 'json_web_token/format/base64_url'
2
-
3
- module JsonWebToken
4
- module Format
5
- describe Base64Url do
6
- context '#encode' do
7
- shared_examples_for 'w #decode' do
8
- it 'matches' do
9
- encoded = Base64Url.encode(str)
10
- expect(Base64Url.decode encoded).to eql str
11
- end
12
- end
13
-
14
- describe 'typical' do
15
- let(:str) { '{"typ":"JWT", "alg":"HS256"}' }
16
- it_behaves_like 'w #decode'
17
- end
18
-
19
- describe 'w whitespace' do
20
- let(:str) { '{"typ" :"JWT" , "alg" :"HS256" }' }
21
- it_behaves_like 'w #decode'
22
- end
23
-
24
- describe 'w line feed and carriage return' do
25
- let(:str) { '{"typ":"JWT",/n "a/rlg":"HS256"}' }
26
- it_behaves_like 'w #decode'
27
- end
28
-
29
- shared_examples_for 'given encoding' do
30
- it 'matches' do
31
- expect(Base64Url.encode str).to eql encoded
32
- expect(Base64Url.decode encoded).to eql str
33
- end
34
- end
35
-
36
- describe 'w no padding char' do
37
- let(:str) { '{"typ":"JWT", "alg":"none"}' }
38
- let(:encoded) { 'eyJ0eXAiOiJKV1QiLCAiYWxnIjoibm9uZSJ9'}
39
- it_behaves_like 'given encoding'
40
- end
41
-
42
- context 'w 1 padding char' do
43
- let(:str) { '{"typ":"JWT", "alg":"algorithm"}' }
44
-
45
- describe 'present' do
46
- let(:encoded) { 'eyJ0eXAiOiJKV1QiLCAiYWxnIjoiYWxnb3JpdGhtIn0='}
47
- it 'matches' do
48
- expect(Base64Url.decode encoded).to eql str
49
- end
50
- end
51
-
52
- describe 'removed' do
53
- let(:encoded) { 'eyJ0eXAiOiJKV1QiLCAiYWxnIjoiYWxnb3JpdGhtIn0'}
54
- it_behaves_like 'given encoding'
55
- end
56
- end
57
-
58
- context 'w 2 padding char' do
59
- let(:str) { '{"typ":"JWT", "alg":"HS256"}' }
60
-
61
- describe 'present' do
62
- let(:encoded) { 'eyJ0eXAiOiJKV1QiLCAiYWxnIjoiSFMyNTYifQ=='}
63
- it 'matches' do
64
- expect(Base64Url.decode encoded).to eql str
65
- end
66
- end
67
-
68
- describe 'removed' do
69
- let(:encoded) { 'eyJ0eXAiOiJKV1QiLCAiYWxnIjoiSFMyNTYifQ'}
70
- it_behaves_like 'given encoding'
71
- end
72
- end
73
-
74
- describe 'invalid encoding' do
75
- let(:encoded) { 'InR5cCI6IkpXVCIsICJhbGciOiJub25lI'}
76
- it 'raises' do
77
- expect { Base64Url.decode(encoded) }
78
- .to raise_error(RuntimeError, 'Invalid base64 string')
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,71 +0,0 @@
1
- require 'json_web_token/algorithm/rsa_util'
2
- require 'json_web_token/jwa'
3
- require 'support/ecdsa_key'
4
-
5
- module JsonWebToken
6
-
7
- RsaUtil = JsonWebToken::Algorithm::RsaUtil
8
-
9
- describe Jwa do
10
- let(:signing_input) { '{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}' }
11
- shared_examples_for 'w #verify?' do
12
- it 'true' do
13
- expect(Jwa.verify? mac, algorithm, verifying_key, signing_input).to be true
14
- end
15
- end
16
- context '#sign' do
17
- let(:mac) { Jwa.sign(algorithm, signing_key, signing_input) }
18
- describe 'HS256' do
19
- let(:algorithm) { 'HS256' }
20
- let(:signing_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
21
- let(:verifying_key) { signing_key }
22
- it_behaves_like 'w #verify?'
23
-
24
- it 'returns a 32-byte MAC' do
25
- expect(mac.bytesize).to eql 32
26
- end
27
- end
28
-
29
- describe 'RS256' do
30
- let(:algorithm) { 'RS256' }
31
- let(:path_to_keys) { 'spec/fixtures/rsa' }
32
- let(:signing_key) { RsaUtil.private_key(path_to_keys) }
33
- let(:verifying_key) { RsaUtil.public_key(path_to_keys) }
34
- it_behaves_like 'w #verify?'
35
-
36
- it 'returns a 256-byte MAC' do
37
- expect(mac.bytesize).to eql 256
38
- end
39
- end
40
-
41
- describe 'ES256' do
42
- let(:algorithm) { 'ES256' }
43
- it 'w #verify? true, returns a 64-byte MAC' do
44
- private_key = EcdsaKey.curve_new('256')
45
- public_key_str = EcdsaKey.public_key_str(private_key)
46
- public_key = EcdsaKey.public_key_new('256', public_key_str)
47
-
48
- mac = Jwa.sign(algorithm, private_key, signing_input)
49
- expect(Jwa.verify? mac, algorithm, public_key, signing_input).to be true
50
-
51
- expect(mac.bytesize).to eql 64
52
- end
53
- end
54
- end
55
-
56
- context 'param validation' do
57
- context 'w HS256 key' do
58
- let(:shared_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
59
- describe 'unrecognized algorithm' do
60
- ['HT256', 'HS257', '', nil].each do |elt|
61
- let(:algorithm) { "#{elt}" }
62
- it 'raises' do
63
- expect { Jwa.sign(algorithm, shared_key, signing_input) }
64
- .to raise_error(RuntimeError, 'Unrecognized algorithm')
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,119 +0,0 @@
1
- require 'json_web_token/jws'
2
- require 'support/ecdsa_key'
3
-
4
- module JsonWebToken
5
- describe Jws do
6
- context 'w payload' do
7
- let(:payload) { '{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}' }
8
- context '#sign' do
9
- shared_examples_for 'does #verify' do
10
- it 'w a jws' do
11
- jws = Jws.sign(header, payload, signing_key)
12
- expect(Jws.verify jws, algorithm, verifying_key).to include({ok: jws})
13
- end
14
- end
15
-
16
- context 'w HS256 keys' do
17
- let(:signing_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
18
- let(:verifying_key) { signing_key }
19
- context "w HS256 'alg' header parameter" do
20
- let(:header) { {alg: 'HS256'} }
21
- context 'w passing a matching algorithm to #verify' do
22
- let(:algorithm) { 'HS256' }
23
- it_behaves_like 'does #verify'
24
-
25
- describe 'w/o passing key to #verify' do
26
- it 'returns error' do
27
- jws = Jws.sign(header, payload, signing_key)
28
- expect(Jws.verify jws, algorithm, nil).to include({error: 'invalid'})
29
- end
30
- end
31
-
32
- describe 'w passing a changed key to #verify' do
33
- let(:changed_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9Z' }
34
- it 'returns error' do
35
- jws = Jws.sign(header, payload, signing_key)
36
- expect(Jws.verify jws, algorithm, changed_key).to include({error: 'invalid'})
37
- end
38
- end
39
- end
40
-
41
- describe 'w/o passing a matching algorithm to #verify' do
42
- let(:algorithm) { 'RS256' }
43
- it 'raises' do
44
- jws = Jws.sign(header, payload, signing_key)
45
- expect { Jws.verify(jws, algorithm, verifying_key) }
46
- .to raise_error(RuntimeError, "Algorithm not matching 'alg' header parameter")
47
- end
48
- end
49
- end
50
- end
51
-
52
- context "w ES256 'alg' header parameter" do
53
- let(:header) { {alg: 'ES256'} }
54
- describe 'w passing a matching algorithm to #verify' do
55
- let(:algorithm) { 'ES256' }
56
- it 'w a jws' do
57
- private_key = EcdsaKey.curve_new('256')
58
- public_key_str = EcdsaKey.public_key_str(private_key)
59
- public_key = EcdsaKey.public_key_new('256', public_key_str)
60
-
61
- jws = Jws.sign(header, payload, private_key)
62
- expect(Jws.verify jws, algorithm, public_key).to include({ok: jws})
63
- end
64
- end
65
- end
66
- end
67
-
68
- context 'header validation' do
69
- let(:signing_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
70
- describe "w/o a recognized 'alg' header parameter" do
71
- let(:header) { {alg: 'HS257'} }
72
- it 'raises' do
73
- expect { Jws.sign(header, payload, signing_key) }
74
- .to raise_error(RuntimeError, 'Unrecognized algorithm')
75
- end
76
- end
77
-
78
- describe "w/o a required 'alg' header parameter" do
79
- let(:header) { {typ: 'JWT'} }
80
- it 'raises' do
81
- expect { Jws.sign(header, payload, signing_key) }
82
- .to raise_error(RuntimeError, "Missing required 'alg' header parameter")
83
- end
84
- end
85
- end
86
-
87
- context '#unsecured_message' do
88
- context 'w valid header' do
89
- let(:header) { {alg: 'none'} }
90
- describe 'w passing a matching algorithm to #verify' do
91
- let(:algorithm) { 'none' }
92
- it 'w a jws' do
93
- jws = Jws.unsecured_message(header, payload)
94
- expect(Jws.verify jws, algorithm).to include({ok: jws})
95
- end
96
- end
97
-
98
- describe 'w/o passing a matching algorithm to #verify' do
99
- let(:algorithm) { 'HS256' }
100
- let(:verifying_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
101
- it 'raises' do
102
- jws = Jws.unsecured_message(header, payload)
103
- expect { Jws.verify(jws, algorithm, verifying_key) }
104
- .to raise_error(RuntimeError, "Algorithm not matching 'alg' header parameter")
105
- end
106
- end
107
- end
108
-
109
- describe 'w invalid header' do
110
- let(:header) { {alg: 'HS256'} }
111
- it 'raises' do
112
- expect { Jws.unsecured_message(header, payload) }
113
- .to raise_error(RuntimeError, "Invalid 'alg' header parameter")
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,142 +0,0 @@
1
- require 'json_web_token/jwt'
2
- require 'support/ecdsa_key'
3
- require 'support/plausible_jwt'
4
-
5
- module JsonWebToken
6
- describe Jwt do
7
- context '#sign' do
8
- shared_examples_for 'does #verify' do
9
- it 'w a claims set' do
10
- jwt = Jwt.sign(claims, sign_options)
11
- expect(Jwt.verify(jwt, verify_options)[:ok]).to include(claims)
12
- end
13
- end
14
-
15
- shared_examples_for 'return a jwt' do
16
- it 'that is plausible' do
17
- jwt = Jwt.sign(claims, sign_options)
18
- expect(plausible_message_signature? jwt).to be true
19
- end
20
- end
21
-
22
- context 'w claims' do
23
- let(:claims) { { iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true} }
24
- context 'w HS256 keys' do
25
- let(:signing_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
26
- let(:verifying_key) { signing_key }
27
- let(:verify_options) { {key: verifying_key} }
28
- describe 'default header' do
29
- let(:sign_options) { {key: signing_key} }
30
- it_behaves_like 'does #verify'
31
- it_behaves_like 'return a jwt'
32
- end
33
-
34
- describe 'w alg option' do
35
- let(:sign_options) { {alg: 'HS256', key: signing_key} }
36
- it_behaves_like 'does #verify'
37
- it_behaves_like 'return a jwt'
38
- end
39
-
40
- describe 'w alg: nil option' do
41
- let(:sign_options) { {alg: nil, key: signing_key} }
42
- it_behaves_like 'does #verify'
43
- it_behaves_like 'return a jwt'
44
- end
45
-
46
- describe "w alg empty string option" do
47
- let(:sign_options) { {alg: '', key: signing_key} }
48
- it_behaves_like 'does #verify'
49
- it_behaves_like 'return a jwt'
50
- end
51
-
52
- describe "w alg: 'none' option" do
53
- let(:sign_options) { {alg: 'none', key: signing_key} }
54
- it 'raises' do
55
- jwt = Jwt.sign(claims, sign_options)
56
- expect { Jwt.verify(jwt, verify_options) }
57
- .to raise_error(RuntimeError, "Algorithm not matching 'alg' header parameter")
58
- end
59
- end
60
- end
61
-
62
- describe 'w/o key w default header alg' do
63
- it 'raises' do
64
- expect { Jwt.sign(claims, {}) }
65
- .to raise_error(RuntimeError, 'Invalid shared key')
66
- end
67
- end
68
-
69
- describe 'w HS256 key changed' do
70
- let(:sign_options) { {alg: 'HS256', key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C'} }
71
- let(:changed_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9Z' }
72
- let(:verify_options) { {key: verifying_key} }
73
- it 'raises' do
74
- jwt = Jwt.sign(claims, sign_options)
75
- expect(Jwt.verify jwt, {key: changed_key}).to include(error: 'invalid')
76
- end
77
- end
78
-
79
- context "w ES256 'alg' header parameter" do
80
- let(:algorithm) { 'ES256' }
81
- describe 'w passing a matching algorithm to #verify' do
82
- it 'is verified and plausible' do
83
- private_key = EcdsaKey.curve_new('256')
84
- public_key_str = EcdsaKey.public_key_str(private_key)
85
- public_key = EcdsaKey.public_key_new('256', public_key_str)
86
-
87
- sign_options = {alg: algorithm, key: private_key}
88
- jwt = Jwt.sign(claims, sign_options)
89
-
90
- verify_options = {alg: algorithm, key: public_key}
91
- expect(Jwt.verify(jwt, verify_options)[:ok]).to eql claims
92
-
93
- expect(plausible_message_signature? jwt, 64).to be true
94
- end
95
- end
96
- end
97
-
98
- context 'w/o key' do
99
- context "w alg: 'none' header parameter" do
100
- let(:sign_options) { {alg: 'none'} }
101
- describe "w verify alg: 'none'" do
102
- let(:verify_options) { {alg: 'none'} }
103
- it 'verifies a plausible unsecured jws' do
104
- jwt = Jwt.sign(claims, sign_options)
105
- expect(Jwt.verify(jwt, verify_options)[:ok]).to include(claims)
106
- expect(plausible_unsecured_message? jwt).to be true
107
- end
108
- end
109
-
110
- describe 'w default verify alg' do
111
- it 'raises' do
112
- jwt = Jwt.sign(claims, sign_options)
113
- expect { Jwt.verify(jwt, {alg: nil}) }
114
- .to raise_error(RuntimeError, "Algorithm not matching 'alg' header parameter")
115
- end
116
- end
117
- end
118
- end
119
- end
120
-
121
- context 'param validation' do
122
- let(:options) { {key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C'} }
123
- shared_examples_for 'w/o claims' do
124
- it 'raises' do
125
- expect { Jwt.sign(claims, options) }
126
- .to raise_error(RuntimeError, 'Claims blank')
127
- end
128
- end
129
-
130
- describe 'w claims nil' do
131
- let(:claims) { nil }
132
- it_behaves_like 'w/o claims'
133
- end
134
-
135
- describe 'w claims an empty string' do
136
- let(:claims) { '' }
137
- it_behaves_like 'w/o claims'
138
- end
139
- end
140
- end
141
- end
142
- end
@@ -1,24 +0,0 @@
1
- require 'json_web_token/util'
2
-
3
- module JsonWebToken
4
- describe Util do
5
- describe '#constant_time_compare?' do
6
- it 'guards against empty or nil strings' do
7
- expect(Util.constant_time_compare? 'a', 'a').to be true
8
-
9
- expect(Util.constant_time_compare? 'a', 'b').to be false
10
- expect(Util.constant_time_compare? 'a', 'A').to be false
11
- expect(Util.constant_time_compare? '', '').to be false
12
- expect(Util.constant_time_compare? nil, nil).to be false
13
- end
14
- end
15
-
16
- describe '#symbolize_keys' do
17
- it 'returns a new hash with all keys converted to symbols' do
18
- original = {'a' => 0, 'b' => '2', c: '3'}
19
- expect(Util.symbolize_keys original).to include({a: 0, b: '2', c: '3'})
20
- expect(original).to eql original
21
- end
22
- end
23
- end
24
- end
@@ -1,47 +0,0 @@
1
- require 'json_web_token'
2
-
3
- describe JsonWebToken do
4
- context '#sign' do
5
- let(:claims) { { iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true} }
6
- shared_examples_for 'w #verify' do
7
- it 'w a claims set' do
8
- jwt = JsonWebToken.sign(claims, sign_options)
9
- expect(JsonWebToken.verify(jwt, verify_options)[:ok]).to include(claims)
10
- end
11
- end
12
-
13
- context 'w HS256 keys' do
14
- let(:signing_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C' }
15
- let(:verifying_key) { signing_key }
16
-
17
- describe 'default alg' do
18
- let(:sign_options) { {key: signing_key} }
19
- let(:verify_options) { {key: verifying_key} }
20
- it_behaves_like 'w #verify'
21
- end
22
-
23
- context "w 'alg' option" do
24
- describe 'HS256' do
25
- let(:sign_options) { {alg: 'HS256', key: signing_key} }
26
- let(:verify_options) { {alg: 'HS256', key: verifying_key} }
27
- it_behaves_like 'w #verify'
28
- end
29
-
30
- describe "w alg 'none'" do
31
- let(:sign_options) { {alg: 'none', key: signing_key} }
32
- let(:verify_options) { {alg: 'none', key: verifying_key} }
33
- it_behaves_like 'w #verify'
34
- end
35
- end
36
- end
37
- end
38
-
39
- context 'module alias JWT' do
40
- describe '#sign' do
41
- let(:claims) { { iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true} }
42
- it 'recognized' do
43
- expect(JsonWebToken.sign(claims, key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C')).to be
44
- end
45
- end
46
- end
47
- end