Skip to content

Commit

Permalink
Raise exception when required cryptography dependency is missing (#963)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
tobloef and pre-commit-ci[bot] committed Jul 5, 2024
1 parent 18a50be commit 527fec2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
16 changes: 13 additions & 3 deletions jwt/api_jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
from typing import Any

from .algorithms import get_default_algorithms, has_crypto, requires_cryptography
from .exceptions import InvalidKeyError, PyJWKError, PyJWKSetError, PyJWTError
from .exceptions import (
InvalidKeyError,
MissingCryptographyError,
PyJWKError,
PyJWKSetError,
PyJWTError,
)
from .types import JWKDict


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

if not has_crypto and algorithm in requires_cryptography:
raise PyJWKError(f"{algorithm} requires 'cryptography' to be installed.")
raise MissingCryptographyError(
f"{algorithm} requires 'cryptography' to be installed."
)

self.algorithm_name = algorithm

Expand Down Expand Up @@ -96,7 +104,9 @@ def __init__(self, keys: list[JWKDict]) -> None:
for key in keys:
try:
self.keys.append(PyJWK(key))
except PyJWTError:
except PyJWTError as error:
if isinstance(error, MissingCryptographyError):
raise error
# skip unusable keys
continue

Expand Down
4 changes: 4 additions & 0 deletions jwt/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class PyJWKError(PyJWTError):
pass


class MissingCryptographyError(PyJWKError):
pass


class PyJWKSetError(PyJWTError):
pass

Expand Down
24 changes: 22 additions & 2 deletions tests/test_api_jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

from jwt.algorithms import has_crypto
from jwt.api_jwk import PyJWK, PyJWKSet
from jwt.exceptions import InvalidKeyError, PyJWKError, PyJWKSetError
from jwt.exceptions import (
InvalidKeyError,
MissingCryptographyError,
PyJWKError,
PyJWKSetError,
)

from .utils import crypto_required, key_path, no_crypto_required

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

@no_crypto_required
def test_missing_crypto_library_raises_missing_cryptography_error(self):
with pytest.raises(MissingCryptographyError):
PyJWK({"kty": "dummy"}, algorithm="RS256")


@crypto_required
class TestPyJWKSet:
@crypto_required
def test_should_load_keys_from_jwk_data_dict(self):
algo = RSAAlgorithm(RSAAlgorithm.SHA256)

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

@crypto_required
def test_should_load_keys_from_jwk_data_json_string(self):
algo = RSAAlgorithm(RSAAlgorithm.SHA256)

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

@crypto_required
def test_keyset_should_index_by_kid(self):
algo = RSAAlgorithm(RSAAlgorithm.SHA256)

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

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

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

@crypto_required
def test_empty_keys_list(self):
with pytest.raises(PyJWKSetError) as err:
PyJWKSet(keys=[])
assert str(err.value) == "The JWK Set did not contain any keys"

@no_crypto_required
def test_missing_crypto_library_raises_when_required(self):
with pytest.raises(MissingCryptographyError):
PyJWKSet(keys=[{"kty": "RSA"}])

0 comments on commit 527fec2

Please sign in to comment.