Skip to content

Commit 9acab9c

Browse files
authored
Add utility functions to assist test skipping (jpadilla#563)
1 parent 8bffbb2 commit 9acab9c

File tree

7 files changed

+76
-163
lines changed

7 files changed

+76
-163
lines changed

tests/keys/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import os
33

4+
from jwt.algorithms import has_crypto
45
from jwt.utils import base64url_decode
56

67
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -22,10 +23,8 @@ def load_hmac_key():
2223
from cryptography.hazmat.primitives.asymmetric import ec
2324

2425
from jwt.algorithms import RSAAlgorithm
25-
26-
has_crypto = True
2726
except ImportError:
28-
has_crypto = False
27+
pass
2928

3029
if has_crypto:
3130

tests/test_algorithms.py

Lines changed: 32 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from jwt.utils import base64url_decode
99

1010
from .keys import load_hmac_key
11-
from .utils import key_path
11+
from .utils import crypto_required, key_path
1212

1313
try:
1414
from jwt.algorithms import (
@@ -19,10 +19,8 @@
1919
)
2020

2121
from .keys import load_ec_pub_key_p_521, load_rsa_pub_key
22-
23-
has_crypto = True
2422
except ImportError:
25-
has_crypto = False
23+
pass
2624

2725

2826
class TestAlgorithms:
@@ -133,45 +131,35 @@ def test_hmac_from_jwk_should_raise_exception_if_not_hmac_key(self):
133131
with pytest.raises(InvalidKeyError):
134132
algo.from_jwk(keyfile.read())
135133

136-
@pytest.mark.skipif(
137-
not has_crypto, reason="Not supported without cryptography library"
138-
)
134+
@crypto_required
139135
def test_rsa_should_parse_pem_public_key(self):
140136
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
141137

142138
with open(key_path("testkey2_rsa.pub.pem")) as pem_key:
143139
algo.prepare_key(pem_key.read())
144140

145-
@pytest.mark.skipif(
146-
not has_crypto, reason="Not supported without cryptography library"
147-
)
141+
@crypto_required
148142
def test_rsa_should_accept_pem_private_key_bytes(self):
149143
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
150144

151145
with open(key_path("testkey_rsa.priv"), "rb") as pem_key:
152146
algo.prepare_key(pem_key.read())
153147

154-
@pytest.mark.skipif(
155-
not has_crypto, reason="Not supported without cryptography library"
156-
)
148+
@crypto_required
157149
def test_rsa_should_accept_unicode_key(self):
158150
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
159151

160152
with open(key_path("testkey_rsa.priv")) as rsa_key:
161153
algo.prepare_key(rsa_key.read())
162154

163-
@pytest.mark.skipif(
164-
not has_crypto, reason="Not supported without cryptography library"
165-
)
155+
@crypto_required
166156
def test_rsa_should_reject_non_string_key(self):
167157
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
168158

169159
with pytest.raises(TypeError):
170160
algo.prepare_key(None)
171161

172-
@pytest.mark.skipif(
173-
not has_crypto, reason="Not supported without cryptography library"
174-
)
162+
@crypto_required
175163
def test_rsa_verify_should_return_false_if_signature_invalid(self):
176164
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
177165

@@ -194,9 +182,7 @@ def test_rsa_verify_should_return_false_if_signature_invalid(self):
194182
result = algo.verify(message, pub_key, sig)
195183
assert not result
196184

197-
@pytest.mark.skipif(
198-
not has_crypto, reason="Not supported without cryptography library"
199-
)
185+
@crypto_required
200186
def test_ec_jwk_public_and_private_keys_should_parse_and_verify(self):
201187
tests = {
202188
"P-256": ECAlgorithm.SHA256,
@@ -215,9 +201,7 @@ def test_ec_jwk_public_and_private_keys_should_parse_and_verify(self):
215201
signature = algo.sign(b"Hello World!", priv_key)
216202
assert algo.verify(b"Hello World!", pub_key, signature)
217203

218-
@pytest.mark.skipif(
219-
not has_crypto, reason="Not supported without cryptography library"
220-
)
204+
@crypto_required
221205
def test_ec_jwk_fails_on_invalid_json(self):
222206
algo = ECAlgorithm(ECAlgorithm.SHA512)
223207

@@ -278,9 +262,7 @@ def test_ec_jwk_fails_on_invalid_json(self):
278262
'"d": "dGVzdA=="}}'.format(curve, point["x"], point["y"])
279263
)
280264

281-
@pytest.mark.skipif(
282-
not has_crypto, reason="Not supported without cryptography library"
283-
)
265+
@crypto_required
284266
def test_rsa_jwk_public_and_private_keys_should_parse_and_verify(self):
285267
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
286268

@@ -293,9 +275,7 @@ def test_rsa_jwk_public_and_private_keys_should_parse_and_verify(self):
293275
signature = algo.sign(b"Hello World!", priv_key)
294276
assert algo.verify(b"Hello World!", pub_key, signature)
295277

296-
@pytest.mark.skipif(
297-
not has_crypto, reason="Not supported without cryptography library"
298-
)
278+
@crypto_required
299279
def test_rsa_private_key_to_jwk_works_with_from_jwk(self):
300280
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
301281

@@ -309,9 +289,7 @@ def test_rsa_private_key_to_jwk_works_with_from_jwk(self):
309289
== orig_key.private_numbers().public_numbers
310290
)
311291

312-
@pytest.mark.skipif(
313-
not has_crypto, reason="Not supported without cryptography library"
314-
)
292+
@crypto_required
315293
def test_rsa_public_key_to_jwk_works_with_from_jwk(self):
316294
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
317295

@@ -321,9 +299,7 @@ def test_rsa_public_key_to_jwk_works_with_from_jwk(self):
321299
parsed_key = algo.from_jwk(algo.to_jwk(orig_key))
322300
assert parsed_key.public_numbers() == orig_key.public_numbers()
323301

324-
@pytest.mark.skipif(
325-
not has_crypto, reason="Not supported without cryptography library"
326-
)
302+
@crypto_required
327303
def test_rsa_jwk_private_key_with_other_primes_is_invalid(self):
328304
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
329305

@@ -334,9 +310,7 @@ def test_rsa_jwk_private_key_with_other_primes_is_invalid(self):
334310

335311
algo.from_jwk(json.dumps(keydata))
336312

337-
@pytest.mark.skipif(
338-
not has_crypto, reason="Not supported without cryptography library"
339-
)
313+
@crypto_required
340314
def test_rsa_jwk_private_key_with_missing_values_is_invalid(self):
341315
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
342316

@@ -347,9 +321,7 @@ def test_rsa_jwk_private_key_with_missing_values_is_invalid(self):
347321

348322
algo.from_jwk(json.dumps(keydata))
349323

350-
@pytest.mark.skipif(
351-
not has_crypto, reason="Not supported without cryptography library"
352-
)
324+
@crypto_required
353325
def test_rsa_jwk_private_key_can_recover_prime_factors(self):
354326
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
355327

@@ -371,9 +343,7 @@ def test_rsa_jwk_private_key_can_recover_prime_factors(self):
371343
assert control_key.dmq1 == parsed_key.dmq1
372344
assert control_key.iqmp == parsed_key.iqmp
373345

374-
@pytest.mark.skipif(
375-
not has_crypto, reason="Not supported without cryptography library"
376-
)
346+
@crypto_required
377347
def test_rsa_jwk_private_key_with_missing_required_values_is_invalid(self):
378348
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
379349

@@ -384,9 +354,7 @@ def test_rsa_jwk_private_key_with_missing_required_values_is_invalid(self):
384354

385355
algo.from_jwk(json.dumps(keydata))
386356

387-
@pytest.mark.skipif(
388-
not has_crypto, reason="Not supported without cryptography library"
389-
)
357+
@crypto_required
390358
def test_rsa_jwk_raises_exception_if_not_a_valid_key(self):
391359
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
392360

@@ -398,9 +366,7 @@ def test_rsa_jwk_raises_exception_if_not_a_valid_key(self):
398366
with pytest.raises(InvalidKeyError):
399367
algo.from_jwk('{"kty": "RSA"}')
400368

401-
@pytest.mark.skipif(
402-
not has_crypto, reason="Not supported without cryptography library"
403-
)
369+
@crypto_required
404370
def test_rsa_to_jwk_returns_correct_values_for_public_key(self):
405371
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
406372

@@ -424,9 +390,7 @@ def test_rsa_to_jwk_returns_correct_values_for_public_key(self):
424390
}
425391
assert json.loads(key) == expected
426392

427-
@pytest.mark.skipif(
428-
not has_crypto, reason="Not supported without cryptography library"
429-
)
393+
@crypto_required
430394
def test_rsa_to_jwk_returns_correct_values_for_private_key(self):
431395
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
432396

@@ -483,55 +447,43 @@ def test_rsa_to_jwk_returns_correct_values_for_private_key(self):
483447
}
484448
assert json.loads(key) == expected
485449

486-
@pytest.mark.skipif(
487-
not has_crypto, reason="Not supported without cryptography library"
488-
)
450+
@crypto_required
489451
def test_rsa_to_jwk_raises_exception_on_invalid_key(self):
490452
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
491453

492454
with pytest.raises(InvalidKeyError):
493455
algo.to_jwk({"not": "a valid key"})
494456

495-
@pytest.mark.skipif(
496-
not has_crypto, reason="Not supported without cryptography library"
497-
)
457+
@crypto_required
498458
def test_rsa_from_jwk_raises_exception_on_invalid_key(self):
499459
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
500460

501461
with open(key_path("jwk_hmac.json")) as keyfile:
502462
with pytest.raises(InvalidKeyError):
503463
algo.from_jwk(keyfile.read())
504464

505-
@pytest.mark.skipif(
506-
not has_crypto, reason="Not supported without cryptography library"
507-
)
465+
@crypto_required
508466
def test_ec_should_reject_non_string_key(self):
509467
algo = ECAlgorithm(ECAlgorithm.SHA256)
510468

511469
with pytest.raises(TypeError):
512470
algo.prepare_key(None)
513471

514-
@pytest.mark.skipif(
515-
not has_crypto, reason="Not supported without cryptography library"
516-
)
472+
@crypto_required
517473
def test_ec_should_accept_pem_private_key_bytes(self):
518474
algo = ECAlgorithm(ECAlgorithm.SHA256)
519475

520476
with open(key_path("testkey_ec.priv"), "rb") as ec_key:
521477
algo.prepare_key(ec_key.read())
522478

523-
@pytest.mark.skipif(
524-
not has_crypto, reason="Not supported without cryptography library"
525-
)
479+
@crypto_required
526480
def test_ec_should_accept_ssh_public_key_bytes(self):
527481
algo = ECAlgorithm(ECAlgorithm.SHA256)
528482

529483
with open(key_path("testkey_ec_ssh.pub")) as ec_key:
530484
algo.prepare_key(ec_key.read())
531485

532-
@pytest.mark.skipif(
533-
not has_crypto, reason="Not supported without cryptography library"
534-
)
486+
@crypto_required
535487
def test_ec_verify_should_return_false_if_signature_invalid(self):
536488
algo = ECAlgorithm(ECAlgorithm.SHA256)
537489

@@ -552,9 +504,7 @@ def test_ec_verify_should_return_false_if_signature_invalid(self):
552504
result = algo.verify(message, pub_key, sig)
553505
assert not result
554506

555-
@pytest.mark.skipif(
556-
not has_crypto, reason="Not supported without cryptography library"
557-
)
507+
@crypto_required
558508
def test_ec_verify_should_return_false_if_signature_wrong_length(self):
559509
algo = ECAlgorithm(ECAlgorithm.SHA256)
560510

@@ -568,9 +518,7 @@ def test_ec_verify_should_return_false_if_signature_wrong_length(self):
568518
result = algo.verify(message, pub_key, sig)
569519
assert not result
570520

571-
@pytest.mark.skipif(
572-
not has_crypto, reason="Not supported without cryptography library"
573-
)
521+
@crypto_required
574522
def test_rsa_pss_sign_then_verify_should_return_true(self):
575523
algo = RSAPSSAlgorithm(RSAPSSAlgorithm.SHA256)
576524

@@ -586,9 +534,7 @@ def test_rsa_pss_sign_then_verify_should_return_true(self):
586534
result = algo.verify(message, pub_key, sig)
587535
assert result
588536

589-
@pytest.mark.skipif(
590-
not has_crypto, reason="Not supported without cryptography library"
591-
)
537+
@crypto_required
592538
def test_rsa_pss_verify_should_return_false_if_signature_invalid(self):
593539
algo = RSAPSSAlgorithm(RSAPSSAlgorithm.SHA256)
594540

@@ -643,9 +589,7 @@ def test_hmac_verify_should_return_true_for_test_vector(self):
643589
result = algo.verify(signing_input, key, signature)
644590
assert result
645591

646-
@pytest.mark.skipif(
647-
not has_crypto, reason="Not supported without cryptography library"
648-
)
592+
@crypto_required
649593
def test_rsa_verify_should_return_true_for_test_vector(self):
650594
"""
651595
This test verifies that RSA PKCS v1.5 verification works with a known
@@ -676,9 +620,7 @@ def test_rsa_verify_should_return_true_for_test_vector(self):
676620
result = algo.verify(signing_input, key, signature)
677621
assert result
678622

679-
@pytest.mark.skipif(
680-
not has_crypto, reason="Not supported without cryptography library"
681-
)
623+
@crypto_required
682624
def test_rsapss_verify_should_return_true_for_test_vector(self):
683625
"""
684626
This test verifies that RSA-PSS verification works with a known good
@@ -709,9 +651,7 @@ def test_rsapss_verify_should_return_true_for_test_vector(self):
709651
result = algo.verify(signing_input, key, signature)
710652
assert result
711653

712-
@pytest.mark.skipif(
713-
not has_crypto, reason="Not supported without cryptography library"
714-
)
654+
@crypto_required
715655
def test_ec_verify_should_return_true_for_test_vector(self):
716656
"""
717657
This test verifies that ECDSA verification works with a known good
@@ -740,9 +680,7 @@ def test_ec_verify_should_return_true_for_test_vector(self):
740680
assert result
741681

742682

743-
@pytest.mark.skipif(
744-
not has_crypto, reason="Not supported without cryptography>=2.6 library"
745-
)
683+
@crypto_required
746684
class TestEd25519Algorithms:
747685
hello_world_sig = b"Qxa47mk/azzUgmY2StAOguAd4P7YBLpyCfU3JdbaiWnXM4o4WibXwmIHvNYgN3frtE2fcyd8OYEaOiD/KiwkCg=="
748686
hello_world = b"Hello World!"

0 commit comments

Comments
 (0)