jwt 1.5.6 → 2.2.3

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.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +74 -0
  3. data/.gitignore +1 -1
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +95 -0
  6. data/.rubocop_todo.yml +191 -0
  7. data/.sourcelevel.yml +18 -0
  8. data/AUTHORS +101 -0
  9. data/Appraisals +10 -0
  10. data/CHANGELOG.md +349 -8
  11. data/Gemfile +2 -1
  12. data/README.md +225 -68
  13. data/Rakefile +4 -1
  14. data/lib/jwt.rb +14 -176
  15. data/lib/jwt/algos.rb +44 -0
  16. data/lib/jwt/algos/ecdsa.rb +35 -0
  17. data/lib/jwt/algos/eddsa.rb +23 -0
  18. data/lib/jwt/algos/hmac.rb +34 -0
  19. data/lib/jwt/algos/none.rb +15 -0
  20. data/lib/jwt/algos/ps.rb +43 -0
  21. data/lib/jwt/algos/rsa.rb +19 -0
  22. data/lib/jwt/algos/unsupported.rb +17 -0
  23. data/lib/jwt/base64.rb +19 -0
  24. data/lib/jwt/claims_validator.rb +35 -0
  25. data/lib/jwt/decode.rb +83 -31
  26. data/lib/jwt/default_options.rb +15 -0
  27. data/lib/jwt/encode.rb +69 -0
  28. data/lib/jwt/error.rb +6 -0
  29. data/lib/jwt/json.rb +10 -9
  30. data/lib/jwt/jwk.rb +51 -0
  31. data/lib/jwt/jwk/ec.rb +150 -0
  32. data/lib/jwt/jwk/hmac.rb +58 -0
  33. data/lib/jwt/jwk/key_base.rb +18 -0
  34. data/lib/jwt/jwk/key_finder.rb +62 -0
  35. data/lib/jwt/jwk/rsa.rb +115 -0
  36. data/lib/jwt/security_utils.rb +57 -0
  37. data/lib/jwt/signature.rb +39 -0
  38. data/lib/jwt/verify.rb +45 -53
  39. data/lib/jwt/version.rb +3 -3
  40. data/ruby-jwt.gemspec +6 -8
  41. metadata +39 -95
  42. data/.codeclimate.yml +0 -20
  43. data/.travis.yml +0 -13
  44. data/Manifest +0 -8
  45. data/spec/fixtures/certs/ec256-private.pem +0 -8
  46. data/spec/fixtures/certs/ec256-public.pem +0 -4
  47. data/spec/fixtures/certs/ec256-wrong-private.pem +0 -8
  48. data/spec/fixtures/certs/ec256-wrong-public.pem +0 -4
  49. data/spec/fixtures/certs/ec384-private.pem +0 -9
  50. data/spec/fixtures/certs/ec384-public.pem +0 -5
  51. data/spec/fixtures/certs/ec384-wrong-private.pem +0 -9
  52. data/spec/fixtures/certs/ec384-wrong-public.pem +0 -5
  53. data/spec/fixtures/certs/ec512-private.pem +0 -10
  54. data/spec/fixtures/certs/ec512-public.pem +0 -6
  55. data/spec/fixtures/certs/ec512-wrong-private.pem +0 -10
  56. data/spec/fixtures/certs/ec512-wrong-public.pem +0 -6
  57. data/spec/fixtures/certs/rsa-1024-private.pem +0 -15
  58. data/spec/fixtures/certs/rsa-1024-public.pem +0 -6
  59. data/spec/fixtures/certs/rsa-2048-private.pem +0 -27
  60. data/spec/fixtures/certs/rsa-2048-public.pem +0 -9
  61. data/spec/fixtures/certs/rsa-2048-wrong-private.pem +0 -27
  62. data/spec/fixtures/certs/rsa-2048-wrong-public.pem +0 -9
  63. data/spec/fixtures/certs/rsa-4096-private.pem +0 -51
  64. data/spec/fixtures/certs/rsa-4096-public.pem +0 -14
  65. data/spec/integration/readme_examples_spec.rb +0 -190
  66. data/spec/jwt/verify_spec.rb +0 -197
  67. data/spec/jwt_spec.rb +0 -240
  68. data/spec/spec_helper.rb +0 -31
data/spec/jwt_spec.rb DELETED
@@ -1,240 +0,0 @@
1
- require 'spec_helper'
2
- require 'jwt'
3
- require 'jwt/decode'
4
-
5
- describe JWT do
6
- let(:payload) { { 'user_id' => 'some@user.tld' } }
7
-
8
- let :data do
9
- {
10
- :secret => 'My$ecretK3y',
11
- :rsa_private => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-private.pem'))),
12
- :rsa_public => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-public.pem'))),
13
- :wrong_rsa_private => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))),
14
- :wrong_rsa_public => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))),
15
- 'ES256_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec256-private.pem'))),
16
- 'ES256_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec256-public.pem'))),
17
- 'ES384_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec384-private.pem'))),
18
- 'ES384_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec384-public.pem'))),
19
- 'ES512_private' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec512-private.pem'))),
20
- 'ES512_public' => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec512-public.pem'))),
21
- 'NONE' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.',
22
- 'HS256' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.tCGvlClld0lbQ3NZaH8y53n5RSBr3zlS4Oy5bXqvzZQ',
23
- 'HS384' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.sj1gc01SawlJSrPZgmveifJ8CzZRYAWjejWm4FRaGaAISESJ9Ncf12fCz2vHrITm',
24
- 'HS512' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.isjhsWMZpRQOWw6LKtlY4L6tMDNkLr0qZ3bQe_xRFXWhzVvJlkclTbLVa1J6Dlj2WyZ_I1jEobTaFMDoXPzwWg',
25
- 'RS256' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.u82QrhjZTtwve5akvfWS_4LPywbkb1Yp0nUwZJWtTW0ID7dY9rRiQF5KGj2UDLZotqRlUjyNQgE_hB5BBzICDQdCjQHQoYWE5n_D2wV4PMu7Qg3FVKoBFbf8ee6irodu10fgYxpUIZtvbWw52_6k6A9IoSLSzx_lCcxoVGdW90dUuKhBcZkDtY5WNuQg7MiDthupSL1-V4Y1jmT_7o8tLNGFiocyZfGNw4yGpEOGNvD5WePNit0xsnbj6dEquovUvSFKsMaQXp2PVDEkLOiLMcyk0RrHqrHw2eNSCquWTH8PhX5Up-CVmjQM5zF9ibkaiq8NyPtsy-7rgtbyVMqXBQ',
26
- 'RS384' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzM4NCJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.2_jPwOsUWJ-3r6lXMdJGPdhLNJQSSEmY2mrDXCwNJk-2YhMIqKAzJJCbyso_A1hS7BVkXmHt54RCcNJXroZBOgmGavCcYTPMaT6sCvVVvJJ_wn7jzKHNAJfL5nWeynTQIBWmL-m_v9QpZAgPALdeqjPRv4JHePZm23kvrUgQOxef2ldXv1l6IB3zfF72uEbk9T5pKBvgeeeQ46xm_HtkpXqMdqcTHawUXeXhuiWxuWfy9pAvhm8ivxwJhiQ15-sQNBlS9lG1_gQz1xaZ_Ou_n1nhNfGwpK5HeS0AgmqsqyCOvaGHeAuAOPZ_dSC3cFKu2AP7kc6_AKBgwJzh4agkXg',
27
- 'RS512' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJ1c2VyX2lkIjoic29tZUB1c2VyLnRsZCJ9.abwof7BqTvuLkN69OhEuFTP7vjGzfvAvooQdwIRne_a88MsjCq31n4UPvyIlY9_8u69rpU79RbMsrq_UZ6L85zP83EcyYI-HOfFZgYDAL3DJ7biBD99JTzyOsH_2i_E6yCkevjEX6uL_Am_C7jpWyePJQkYzTFni6mW4W1T9UobiVGA1tIZ-XOJDPHHxZkGu6W8lKW0UCsr9Ge2SCSlTs_LDSOa34gqMC5GP89unhLqSMqEMJ_Nm6Rj0rnmk87wBZM-b04LLteWuEU59QDNa4nMTjfXW74U4hX9n5EECDPQdQMecgxlUbFunAfZaoNzP4m7H4vux2FzYkjkXhdqnnw',
28
- 'ES256' => '',
29
- 'ES384' => '',
30
- 'ES512' => ''
31
- }
32
- end
33
-
34
- after(:each) do
35
- expect(OpenSSL.errors).to be_empty
36
- end
37
-
38
- context 'alg: NONE' do
39
- let(:alg) { 'none' }
40
-
41
- it 'should generate a valid token' do
42
- token = JWT.encode payload, nil, alg
43
-
44
- expect(token).to eq data['NONE']
45
- end
46
-
47
- it 'should decode a valid token' do
48
- jwt_payload, header = JWT.decode data['NONE'], nil, false
49
-
50
- expect(header['alg']).to eq alg
51
- expect(jwt_payload).to eq payload
52
- end
53
-
54
- it 'should display a better error message if payload exp is_a?(Time)' do
55
- payload['exp'] = Time.now
56
-
57
- expect do
58
- JWT.encode payload, nil, alg
59
- end.to raise_error JWT::InvalidPayload
60
- end
61
- end
62
-
63
- %w(HS256 HS384 HS512).each do |alg|
64
- context "alg: #{alg}" do
65
- it 'should generate a valid token' do
66
- token = JWT.encode payload, data[:secret], alg
67
-
68
- expect(token).to eq data[alg]
69
- end
70
-
71
- it 'should decode a valid token' do
72
- jwt_payload, header = JWT.decode data[alg], data[:secret]
73
-
74
- expect(header['alg']).to eq alg
75
- expect(jwt_payload).to eq payload
76
- end
77
-
78
- it 'wrong secret should raise JWT::DecodeError' do
79
- expect do
80
- JWT.decode data[alg], 'wrong_secret'
81
- end.to raise_error JWT::DecodeError
82
- end
83
-
84
- it 'wrong secret and verify = false should not raise JWT::DecodeError' do
85
- expect do
86
- JWT.decode data[alg], 'wrong_secret', false
87
- end.not_to raise_error
88
- end
89
- end
90
- end
91
-
92
- %w(RS256 RS384 RS512).each do |alg|
93
- context "alg: #{alg}" do
94
- it 'should generate a valid token' do
95
- token = JWT.encode payload, data[:rsa_private], alg
96
-
97
- expect(token).to eq data[alg]
98
- end
99
-
100
- it 'should decode a valid token' do
101
- jwt_payload, header = JWT.decode data[alg], data[:rsa_public]
102
-
103
- expect(header['alg']).to eq alg
104
- expect(jwt_payload).to eq payload
105
- end
106
-
107
- it 'wrong key should raise JWT::DecodeError' do
108
- key = OpenSSL::PKey.read File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))
109
-
110
- expect do
111
- JWT.decode data[alg], key
112
- end.to raise_error JWT::DecodeError
113
- end
114
-
115
- it 'wrong key and verify = false should not raise JWT::DecodeError' do
116
- key = OpenSSL::PKey.read File.read(File.join(CERT_PATH, 'rsa-2048-wrong-public.pem'))
117
-
118
- expect do
119
- JWT.decode data[alg], key, false
120
- end.not_to raise_error
121
- end
122
- end
123
- end
124
-
125
- %w(ES256 ES384 ES512).each do |alg|
126
- context "alg: #{alg}" do
127
- before(:each) do
128
- data[alg] = JWT.encode payload, data["#{alg}_private"], alg
129
- end
130
-
131
- let(:wrong_key) { OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'ec256-wrong-public.pem'))) }
132
-
133
- it 'should generate a valid token' do
134
- jwt_payload, header = JWT.decode data[alg], data["#{alg}_public"]
135
-
136
- expect(header['alg']).to eq alg
137
- expect(jwt_payload).to eq payload
138
- end
139
-
140
- it 'should decode a valid token' do
141
- jwt_payload, header = JWT.decode data[alg], data["#{alg}_public"]
142
-
143
- expect(header['alg']).to eq alg
144
- expect(jwt_payload).to eq payload
145
- end
146
-
147
- it 'wrong key should raise JWT::DecodeError' do
148
- expect do
149
- JWT.decode data[alg], wrong_key
150
- end.to raise_error JWT::DecodeError
151
- end
152
-
153
- it 'wrong key and verify = false should not raise JWT::DecodeError' do
154
- expect do
155
- JWT.decode data[alg], wrong_key, false
156
- end.not_to raise_error
157
- end
158
- end
159
- end
160
-
161
- context 'Invalid' do
162
- it 'algorithm should raise NotImplementedError' do
163
- expect do
164
- JWT.encode payload, 'secret', 'HS255'
165
- end.to raise_error NotImplementedError
166
- end
167
-
168
- it 'ECDSA curve_name should raise JWT::IncorrectAlgorithm' do
169
- key = OpenSSL::PKey::EC.new 'secp256k1'
170
- key.generate_key
171
-
172
- expect do
173
- JWT.encode payload, key, 'ES256'
174
- end.to raise_error JWT::IncorrectAlgorithm
175
-
176
- token = JWT.encode payload, data['ES256_private'], 'ES256'
177
- key.private_key = nil
178
-
179
- expect do
180
- JWT.decode token, key
181
- end.to raise_error JWT::IncorrectAlgorithm
182
- end
183
- end
184
-
185
- context 'Verify' do
186
- context 'algorithm' do
187
- it 'should raise JWT::IncorrectAlgorithm on missmatch' do
188
- token = JWT.encode payload, data[:secret], 'HS512'
189
-
190
- expect do
191
- JWT.decode token, data[:secret], true, algorithm: 'HS384'
192
- end.to raise_error JWT::IncorrectAlgorithm
193
-
194
- expect do
195
- JWT.decode token, data[:secret], true, algorithm: 'HS512'
196
- end.not_to raise_error
197
- end
198
- end
199
-
200
- context 'issuer claim' do
201
- let(:iss) { 'ruby-jwt-gem' }
202
- let(:invalid_token) { JWT.encode payload, data[:secret] }
203
-
204
- let :token do
205
- iss_payload = payload.merge(iss: iss)
206
- JWT.encode iss_payload, data[:secret]
207
- end
208
-
209
- it 'if verify_iss is set to false (default option) should not raise JWT::InvalidIssuerError' do
210
- expect do
211
- JWT.decode token, data[:secret], true, iss: iss
212
- end.not_to raise_error
213
- end
214
- end
215
- end
216
-
217
- context 'Base64' do
218
- it 'urlsafe replace + / with - _' do
219
- allow(Base64).to receive(:encode64) { 'string+with/non+url-safe/characters_' }
220
- expect(JWT.base64url_encode('foo')).to eq('string-with_non-url-safe_characters_')
221
- end
222
- end
223
-
224
- describe 'secure comparison' do
225
- it 'returns true if strings are equal' do
226
- expect(JWT.secure_compare('Foo', 'Foo')).to eq true
227
- end
228
-
229
- it 'returns false if either input is nil or empty' do
230
- [nil, ''].each do |bad|
231
- expect(JWT.secure_compare(bad, 'Foo')).to eq false
232
- expect(JWT.secure_compare('Foo', bad)).to eq false
233
- end
234
- end
235
-
236
- it 'retuns false if the strings are different' do
237
- expect(JWT.secure_compare('Foo', 'Bar')).to eq false
238
- end
239
- end
240
- end
data/spec/spec_helper.rb DELETED
@@ -1,31 +0,0 @@
1
- require 'rspec'
2
- require 'simplecov'
3
- require 'simplecov-json'
4
- require 'codeclimate-test-reporter'
5
-
6
- SimpleCov.configure do
7
- root File.join(File.dirname(__FILE__), '..')
8
- project_name 'Ruby JWT - Ruby JSON Web Token implementation'
9
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
10
- SimpleCov::Formatter::HTMLFormatter,
11
- SimpleCov::Formatter::JSONFormatter
12
- ])
13
-
14
- add_filter 'spec'
15
- end
16
-
17
- SimpleCov.start if ENV['COVERAGE']
18
- CodeClimate::TestReporter.start if ENV['CODECLIMATE_REPO_TOKEN']
19
-
20
- CERT_PATH = File.join(File.dirname(__FILE__), 'fixtures', 'certs')
21
-
22
- RSpec.configure do |config|
23
- config.expect_with :rspec do |c|
24
- c.syntax = [:should, :expect]
25
- end
26
-
27
- config.run_all_when_everything_filtered = true
28
- config.filter_run :focus
29
-
30
- config.order = 'random'
31
- end