Skip to content

Commit 527fec2

Browse files
Raise exception when required cryptography dependency is missing (#963)
* Raise exception when required cryptography dependency is missing * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add tests for `MissingCryptographyError` * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 18a50be commit 527fec2

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

jwt/api_jwk.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
from typing import Any
66

77
from .algorithms import get_default_algorithms, has_crypto, requires_cryptography
8-
from .exceptions import InvalidKeyError, PyJWKError, PyJWKSetError, PyJWTError
8+
from .exceptions import (
9+
InvalidKeyError,
10+
MissingCryptographyError,
11+
PyJWKError,
12+
PyJWKSetError,
13+
PyJWTError,
14+
)
915
from .types import JWKDict
1016

1117

@@ -50,7 +56,9 @@ def __init__(self, jwk_data: JWKDict, algorithm: str | None = None) -> None:
5056
raise InvalidKeyError(f"Unsupported kty: {kty}")
5157

5258
if not has_crypto and algorithm in requires_cryptography:
53-
raise PyJWKError(f"{algorithm} requires 'cryptography' to be installed.")
59+
raise MissingCryptographyError(
60+
f"{algorithm} requires 'cryptography' to be installed."
61+
)
5462

5563
self.algorithm_name = algorithm
5664

@@ -96,7 +104,9 @@ def __init__(self, keys: list[JWKDict]) -> None:
96104
for key in keys:
97105
try:
98106
self.keys.append(PyJWK(key))
99-
except PyJWTError:
107+
except PyJWTError as error:
108+
if isinstance(error, MissingCryptographyError):
109+
raise error
100110
# skip unusable keys
101111
continue
102112

jwt/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class PyJWKError(PyJWTError):
5858
pass
5959

6060

61+
class MissingCryptographyError(PyJWKError):
62+
pass
63+
64+
6165
class PyJWKSetError(PyJWTError):
6266
pass
6367

tests/test_api_jwk.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
from jwt.algorithms import has_crypto
66
from jwt.api_jwk import PyJWK, PyJWKSet
7-
from jwt.exceptions import InvalidKeyError, PyJWKError, PyJWKSetError
7+
from jwt.exceptions import (
8+
InvalidKeyError,
9+
MissingCryptographyError,
10+
PyJWKError,
11+
PyJWKSetError,
12+
)
813

914
from .utils import crypto_required, key_path, no_crypto_required
1015

@@ -212,9 +217,14 @@ def test_missing_crypto_library_good_error_message(self):
212217
PyJWK({"kty": "dummy"}, algorithm="RS256")
213218
assert "cryptography" in str(exc.value)
214219

220+
@no_crypto_required
221+
def test_missing_crypto_library_raises_missing_cryptography_error(self):
222+
with pytest.raises(MissingCryptographyError):
223+
PyJWK({"kty": "dummy"}, algorithm="RS256")
224+
215225

216-
@crypto_required
217226
class TestPyJWKSet:
227+
@crypto_required
218228
def test_should_load_keys_from_jwk_data_dict(self):
219229
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
220230

@@ -236,6 +246,7 @@ def test_should_load_keys_from_jwk_data_dict(self):
236246
assert jwk.key_id == "keyid-abc123"
237247
assert jwk.public_key_use == "sig"
238248

249+
@crypto_required
239250
def test_should_load_keys_from_jwk_data_json_string(self):
240251
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
241252

@@ -257,6 +268,7 @@ def test_should_load_keys_from_jwk_data_json_string(self):
257268
assert jwk.key_id == "keyid-abc123"
258269
assert jwk.public_key_use == "sig"
259270

271+
@crypto_required
260272
def test_keyset_should_index_by_kid(self):
261273
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
262274

@@ -279,6 +291,7 @@ def test_keyset_should_index_by_kid(self):
279291
with pytest.raises(KeyError):
280292
_ = jwk_set["this-kid-does-not-exist"]
281293

294+
@crypto_required
282295
def test_keyset_with_unknown_alg(self):
283296
# first keyset with unusable key and usable key
284297
with open(key_path("jwk_keyset_with_unknown_alg.json")) as keyfile:
@@ -296,12 +309,19 @@ def test_keyset_with_unknown_alg(self):
296309
with pytest.raises(PyJWKSetError):
297310
_ = PyJWKSet.from_json(jwks_text)
298311

312+
@crypto_required
299313
def test_invalid_keys_list(self):
300314
with pytest.raises(PyJWKSetError) as err:
301315
PyJWKSet(keys="string") # type: ignore
302316
assert str(err.value) == "Invalid JWK Set value"
303317

318+
@crypto_required
304319
def test_empty_keys_list(self):
305320
with pytest.raises(PyJWKSetError) as err:
306321
PyJWKSet(keys=[])
307322
assert str(err.value) == "The JWK Set did not contain any keys"
323+
324+
@no_crypto_required
325+
def test_missing_crypto_library_raises_when_required(self):
326+
with pytest.raises(MissingCryptographyError):
327+
PyJWKSet(keys=[{"kty": "RSA"}])

0 commit comments

Comments
 (0)