Skip to content

Commit 44fec9d

Browse files
committed
Enforce parentheses on method calls with arguments
Style/MethodCallWithArgsParentheses is off by default, so the codebase had drifted both ways: JWT.encode payload, nil, alg next to JWT.encode(payload, nil, alg), with the paren-less form concentrated in the older specs. Exempted rather than normalised: raise and fail, because raise Foo, 'msg' is about as idiomatic as paren-less Ruby gets, and enforcing parentheses there accounted for 67 of the 100 changed lines in lib, all of it in the claims and crypto files. The codebase is already mixed on this and stays that way. yield, which is a keyword and reads like one. The gemspec, because add_dependency 'base64' is the universal form and the whole file is a DSL. Metrics/BlockLength already excludes it. The RSpec matcher DSL, so expect(x).to eq(y) does not become expect(x).to(eq(y)). What is left in lib is four calls: three include? k and one unpack. Everything is rubocop -a output apart from five arrays in readme_examples_spec, where the added parentheses pushed the elements out to a 36 column hanging indent; those are collapsed onto one line.
1 parent 4a576f8 commit 44fec9d

21 files changed

Lines changed: 226 additions & 225 deletions

.rubocop.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,19 @@ Gemspec/DevelopmentDependencies:
2525

2626
Naming/PredicateMethod:
2727
Enabled: false
28+
29+
Style/MethodCallWithArgsParentheses:
30+
Enabled: true
31+
Exclude:
32+
- "*.gemspec"
33+
AllowedMethods:
34+
- raise
35+
- fail
36+
- yield
37+
- to
38+
- not_to
39+
- to_not
40+
- describe
41+
- context
42+
- it
43+
- specify

lib/jwt/jwa/hmac.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def fixed_length_secure_compare(a, b)
6969
def fixed_length_secure_compare(a, b)
7070
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
7171

72-
l = a.unpack "C#{a.bytesize}"
72+
l = a.unpack("C#{a.bytesize}")
7373

7474
res = 0
7575
b.each_byte { |byte| res |= byte ^ l.shift }

lib/jwt/jwk/ec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def members
5454

5555
def export(options = {})
5656
exported = parameters.clone
57-
exported.reject! { |k, _| EC_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
57+
exported.reject! { |k, _| EC_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true
5858
exported
5959
end
6060

lib/jwt/jwk/hmac.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def signing_key
4747
# See https://tools.ietf.org/html/rfc7517#appendix-A.3
4848
def export(options = {})
4949
exported = parameters.clone
50-
exported.reject! { |k, _| HMAC_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
50+
exported.reject! { |k, _| HMAC_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true
5151
exported
5252
end
5353

lib/jwt/jwk/rsa.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def verify_key
5050

5151
def export(options = {})
5252
exported = parameters.clone
53-
exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
53+
exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true
5454

5555
exported
5656
end

spec/integration/readme_examples_spec.rb

Lines changed: 52 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,64 +7,49 @@
77
let(:payload) { { data: 'test' } }
88

99
it 'NONE' do
10-
token = JWT.encode payload, nil, 'none'
11-
decoded_token = JWT.decode token, nil, false
12-
13-
expect(token).to eq 'eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.'
14-
expect(decoded_token).to eq [
15-
{ 'data' => 'test' },
16-
{ 'alg' => 'none' }
17-
]
10+
token = JWT.encode(payload, nil, 'none')
11+
decoded_token = JWT.decode(token, nil, false)
12+
13+
expect(token).to eq('eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.')
14+
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'none' }])
1815
end
1916

2017
it 'decodes with HMAC algorithm with secret key' do
21-
token = JWT.encode payload, 'my$ecretK3y', 'HS256'
22-
decoded_token = JWT.decode token, 'my$ecretK3y', false
23-
24-
expect(token).to eq 'eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y'
25-
expect(decoded_token).to eq [
26-
{ 'data' => 'test' },
27-
{ 'alg' => 'HS256' }
28-
]
18+
token = JWT.encode(payload, 'my$ecretK3y', 'HS256')
19+
decoded_token = JWT.decode(token, 'my$ecretK3y', false)
20+
21+
expect(token).to eq('eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y')
22+
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'HS256' }])
2923
end
3024

3125
it 'RSA' do
32-
rsa_private = OpenSSL::PKey::RSA.generate 2048
26+
rsa_private = OpenSSL::PKey::RSA.generate(2048)
3327
rsa_public = rsa_private.public_key
3428

35-
token = JWT.encode payload, rsa_private, 'RS256'
36-
decoded_token = JWT.decode token, rsa_public, true, algorithm: 'RS256'
29+
token = JWT.encode(payload, rsa_private, 'RS256')
30+
decoded_token = JWT.decode(token, rsa_public, true, algorithm: 'RS256')
3731

38-
expect(decoded_token).to eq [
39-
{ 'data' => 'test' },
40-
{ 'alg' => 'RS256' }
41-
]
32+
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'RS256' }])
4233
end
4334

4435
it 'ECDSA' do
4536
ecdsa_key = OpenSSL::PKey::EC.generate('prime256v1')
4637

47-
token = JWT.encode payload, ecdsa_key, 'ES256'
48-
decoded_token = JWT.decode token, ecdsa_key, true, algorithm: 'ES256'
38+
token = JWT.encode(payload, ecdsa_key, 'ES256')
39+
decoded_token = JWT.decode(token, ecdsa_key, true, algorithm: 'ES256')
4940

50-
expect(decoded_token).to eq [
51-
{ 'data' => 'test' },
52-
{ 'alg' => 'ES256' }
53-
]
41+
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'ES256' }])
5442
end
5543

5644
if Gem::Version.new(OpenSSL::VERSION) >= Gem::Version.new('2.1')
5745
it 'RSASSA-PSS' do
58-
rsa_private = OpenSSL::PKey::RSA.generate 2048
46+
rsa_private = OpenSSL::PKey::RSA.generate(2048)
5947
rsa_public = rsa_private.public_key
6048

61-
token = JWT.encode payload, rsa_private, 'PS256'
62-
decoded_token = JWT.decode token, rsa_public, true, algorithm: 'PS256'
49+
token = JWT.encode(payload, rsa_private, 'PS256')
50+
decoded_token = JWT.decode(token, rsa_public, true, algorithm: 'PS256')
6351

64-
expect(decoded_token).to eq [
65-
{ 'data' => 'test' },
66-
{ 'alg' => 'PS256' }
67-
]
52+
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'PS256' }])
6853
end
6954
end
7055
end
@@ -77,10 +62,10 @@
7762
exp = Time.now.to_i + (4 * 3600)
7863
exp_payload = { data: 'data', exp: exp }
7964

80-
token = JWT.encode exp_payload, hmac_secret, 'HS256'
65+
token = JWT.encode(exp_payload, hmac_secret, 'HS256')
8166

8267
expect do
83-
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
68+
JWT.decode(token, hmac_secret, true, algorithm: 'HS256')
8469
end.not_to raise_error
8570
end
8671

@@ -90,10 +75,10 @@
9075

9176
exp_payload = { data: 'data', exp: exp }
9277

93-
token = JWT.encode exp_payload, hmac_secret, 'HS256'
78+
token = JWT.encode(exp_payload, hmac_secret, 'HS256')
9479

9580
expect do
96-
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
81+
JWT.decode(token, hmac_secret, true, leeway: leeway, algorithm: 'HS256')
9782
end.not_to raise_error
9883
end
9984
end
@@ -102,21 +87,21 @@
10287
it 'without leeway' do
10388
nbf = Time.now.to_i - 3600
10489
nbf_payload = { data: 'data', nbf: nbf }
105-
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
90+
token = JWT.encode(nbf_payload, hmac_secret, 'HS256')
10691

10792
expect do
108-
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
93+
JWT.decode(token, hmac_secret, true, algorithm: 'HS256')
10994
end.not_to raise_error
11095
end
11196

11297
it 'with leeway' do
11398
nbf = Time.now.to_i + 10
11499
leeway = 30
115100
nbf_payload = { data: 'data', nbf: nbf }
116-
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
101+
token = JWT.encode(nbf_payload, hmac_secret, 'HS256')
117102

118103
expect do
119-
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
104+
JWT.decode(token, hmac_secret, true, leeway: leeway, algorithm: 'HS256')
120105
end.not_to raise_error
121106
end
122107
end
@@ -125,10 +110,10 @@
125110
iss = 'My Awesome Company Inc. or https://my.awesome.website/'
126111
iss_payload = { data: 'data', iss: iss }
127112

128-
token = JWT.encode iss_payload, hmac_secret, 'HS256'
113+
token = JWT.encode(iss_payload, hmac_secret, 'HS256')
129114

130115
expect do
131-
JWT.decode token, hmac_secret, true, iss: iss, algorithm: 'HS256'
116+
JWT.decode(token, hmac_secret, true, iss: iss, algorithm: 'HS256')
132117
end.not_to raise_error
133118
end
134119

@@ -137,21 +122,21 @@
137122
aud = %w[Young Old]
138123
aud_payload = { data: 'data', aud: aud }
139124

140-
token = JWT.encode aud_payload, hmac_secret, 'HS256'
125+
token = JWT.encode(aud_payload, hmac_secret, 'HS256')
141126

142127
expect do
143-
JWT.decode token, hmac_secret, true, aud: %w[Old Young], verify_aud: true, algorithm: 'HS256'
128+
JWT.decode(token, hmac_secret, true, aud: %w[Old Young], verify_aud: true, algorithm: 'HS256')
144129
end.not_to raise_error
145130
end
146131

147132
it 'string' do
148133
aud = 'Kids'
149134
aud_payload = { data: 'data', aud: aud }
150135

151-
token = JWT.encode aud_payload, hmac_secret, 'HS256'
136+
token = JWT.encode(aud_payload, hmac_secret, 'HS256')
152137

153138
expect do
154-
JWT.decode token, hmac_secret, true, aud: 'Kids', verify_aud: true, algorithm: 'HS256'
139+
JWT.decode(token, hmac_secret, true, aud: 'Kids', verify_aud: true, algorithm: 'HS256')
155140
end.not_to raise_error
156141
end
157142
end
@@ -163,10 +148,10 @@
163148
jti = Digest::MD5.hexdigest(jti_raw)
164149
jti_payload = { data: 'data', iat: iat, jti: jti }
165150

166-
token = JWT.encode jti_payload, hmac_secret, 'HS256'
151+
token = JWT.encode(jti_payload, hmac_secret, 'HS256')
167152

168153
expect do
169-
JWT.decode token, hmac_secret, true, verify_jti: true, algorithm: 'HS256'
154+
JWT.decode(token, hmac_secret, true, verify_jti: true, algorithm: 'HS256')
170155
end.not_to raise_error
171156
end
172157

@@ -175,21 +160,21 @@
175160
iat = Time.now.to_i
176161
iat_payload = { data: 'data', iat: iat }
177162

178-
token = JWT.encode iat_payload, hmac_secret, 'HS256'
163+
token = JWT.encode(iat_payload, hmac_secret, 'HS256')
179164

180165
expect do
181-
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
166+
JWT.decode(token, hmac_secret, true, verify_iat: true, algorithm: 'HS256')
182167
end.not_to raise_error
183168
end
184169

185170
it 'with leeway' do
186171
iat = Time.now.to_i - 7
187172
iat_payload = { data: 'data', iat: iat, leeway: 10 }
188173

189-
token = JWT.encode iat_payload, hmac_secret, 'HS256'
174+
token = JWT.encode(iat_payload, hmac_secret, 'HS256')
190175

191176
expect do
192-
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
177+
JWT.decode(token, hmac_secret, true, verify_iat: true, algorithm: 'HS256')
193178
end.not_to raise_error
194179
end
195180
end
@@ -198,43 +183,43 @@
198183
it 'with custom field' do
199184
payload = { data: 'test' }
200185

201-
token = JWT.encode payload, nil, 'none', typ: 'JWT'
202-
_, header = JWT.decode token, nil, false
186+
token = JWT.encode(payload, nil, 'none', typ: 'JWT')
187+
_, header = JWT.decode(token, nil, false)
203188

204-
expect(header['typ']).to eq 'JWT'
189+
expect(header['typ']).to eq('JWT')
205190
end
206191
end
207192

208193
it 'sub' do
209194
sub = 'Subject'
210195
sub_payload = { data: 'data', sub: sub }
211196

212-
token = JWT.encode sub_payload, hmac_secret, 'HS256'
197+
token = JWT.encode(sub_payload, hmac_secret, 'HS256')
213198

214199
expect do
215-
JWT.decode token, hmac_secret, true, { sub: sub, verify_sub: true, algorithm: 'HS256' }
200+
JWT.decode(token, hmac_secret, true, { sub: sub, verify_sub: true, algorithm: 'HS256' })
216201
end.not_to raise_error
217202

218203
expect do
219-
JWT.decode token, hmac_secret, true, { sub: 'sub', verify_sub: true, algorithm: 'HS256' }
204+
JWT.decode(token, hmac_secret, true, { sub: 'sub', verify_sub: true, algorithm: 'HS256' })
220205
end.to raise_error(JWT::InvalidSubError)
221206

222207
expect do
223-
JWT.decode token, hmac_secret, true, { 'sub' => 'sub', verify_sub: true, algorithm: 'HS256' }
208+
JWT.decode(token, hmac_secret, true, { 'sub' => 'sub', verify_sub: true, algorithm: 'HS256' })
224209
end.not_to raise_error
225210
end
226211

227212
it 'required_claims' do
228213
payload = { data: 'test' }
229214

230-
token = JWT.encode payload, hmac_secret, 'HS256'
215+
token = JWT.encode(payload, hmac_secret, 'HS256')
231216

232217
expect do
233-
JWT.decode token, hmac_secret, true, required_claims: ['exp'], algorithm: 'HS256'
218+
JWT.decode(token, hmac_secret, true, required_claims: ['exp'], algorithm: 'HS256')
234219
end.to raise_error(JWT::MissingRequiredClaim)
235220

236221
expect do
237-
JWT.decode token, hmac_secret, true, required_claims: ['data'], algorithm: 'HS256'
222+
JWT.decode(token, hmac_secret, true, required_claims: ['data'], algorithm: 'HS256')
238223
end.not_to raise_error
239224
end
240225

@@ -244,7 +229,7 @@
244229

245230
secrets = { issuers.first => hmac_secret, issuers.last => 'hmac_secret2' }
246231

247-
token = JWT.encode iss_payload, hmac_secret, 'HS256'
232+
token = JWT.encode(iss_payload, hmac_secret, 'HS256')
248233

249234
expect do
250235
# Add iss to the validation to check if the token has been manipulated

spec/jwt/claims/audience_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
it 'raises JWT::InvalidAudError' do
1717
expect do
1818
subject
19-
end.to raise_error JWT::InvalidAudError
19+
end.to raise_error(JWT::InvalidAudError)
2020
end
2121
end
2222

@@ -27,7 +27,7 @@
2727
it 'raises JWT::InvalidAudError' do
2828
expect do
2929
subject
30-
end.to raise_error JWT::InvalidAudError
30+
end.to raise_error(JWT::InvalidAudError)
3131
end
3232
end
3333

spec/jwt/claims/not_before_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
describe '#verify!' do
77
context 'when nbf is in the future' do
88
it 'raises JWT::ImmatureSignature' do
9-
expect { described_class.new(leeway: 0).verify!(context: SpecSupport::Token.new(payload: payload)) }.to raise_error JWT::ImmatureSignature
9+
expect { described_class.new(leeway: 0).verify!(context: SpecSupport::Token.new(payload: payload)) }.to raise_error(JWT::ImmatureSignature)
1010
end
1111
end
1212

spec/jwt/claims/numeric_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
let(:claims) { { claim => '1' } }
3131

3232
it 'raises error' do
33-
expect { subject }.to raise_error JWT::InvalidPayload
33+
expect { subject }.to raise_error(JWT::InvalidPayload)
3434
end
3535

3636
context 'and key is a string' do
3737
let(:claims) { { claim.to_s => '1' } }
3838

3939
it 'raises error' do
40-
expect { subject }.to raise_error JWT::InvalidPayload
40+
expect { subject }.to raise_error(JWT::InvalidPayload)
4141
end
4242
end
4343
end
@@ -46,15 +46,15 @@
4646
let(:claims) { { claim => Time.now } }
4747

4848
it 'raises error' do
49-
expect { subject }.to raise_error JWT::InvalidPayload
49+
expect { subject }.to raise_error(JWT::InvalidPayload)
5050
end
5151
end
5252

5353
context "when #{claim} payload is a string" do
5454
let(:claims) { { claim => '1' } }
5555

5656
it 'raises error' do
57-
expect { subject }.to raise_error JWT::InvalidPayload
57+
expect { subject }.to raise_error(JWT::InvalidPayload)
5858
end
5959
end
6060
end

0 commit comments

Comments
 (0)