From b407c63b17f16e78c13c36d784d6e1822fee1147 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Thu, 26 Jan 2023 15:28:51 +0100 Subject: Improve error messages when cryptography isn't installed (#846) * Improve error messages when cryptography isn't installed * Add test * [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> --- jwt/api_jwk.py | 15 ++++++++++----- tests/test_api_jwk.py | 8 +++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/jwt/api_jwk.py b/jwt/api_jwk.py index ef8cce8..fdcde21 100644 --- a/jwt/api_jwk.py +++ b/jwt/api_jwk.py @@ -4,7 +4,7 @@ import json import time from typing import Any, Optional -from .algorithms import get_default_algorithms +from .algorithms import get_default_algorithms, has_crypto, requires_cryptography from .exceptions import InvalidKeyError, PyJWKError, PyJWKSetError from .types import JWKDict @@ -49,10 +49,13 @@ class PyJWK: else: raise InvalidKeyError(f"Unsupported kty: {kty}") + if not has_crypto and algorithm in requires_cryptography: + raise PyJWKError(f"{algorithm} requires 'cryptography' to be installed.") + self.Algorithm = self._algorithms.get(algorithm) if not self.Algorithm: - raise PyJWKError(f"Unable to find a algorithm for key: {self._jwk_data}") + raise PyJWKError(f"Unable to find an algorithm for key: {self._jwk_data}") self.key = self.Algorithm.from_jwk(self._jwk_data) @@ -66,11 +69,11 @@ class PyJWK: return PyJWK.from_dict(obj, algorithm) @property - def key_type(self) -> str: + def key_type(self) -> Optional[str]: return self._jwk_data.get("kty", None) @property - def key_id(self) -> str: + def key_id(self) -> Optional[str]: return self._jwk_data.get("kid", None) @property @@ -96,7 +99,9 @@ class PyJWKSet: continue if len(self.keys) == 0: - raise PyJWKSetError("The JWK Set did not contain any usable keys") + raise PyJWKSetError( + "The JWK Set did not contain any usable keys. Perhaps 'cryptography' is not installed?" + ) @staticmethod def from_dict(obj: dict[str, Any]) -> "PyJWKSet": diff --git a/tests/test_api_jwk.py b/tests/test_api_jwk.py index 3f40fc5..f04f575 100644 --- a/tests/test_api_jwk.py +++ b/tests/test_api_jwk.py @@ -6,7 +6,7 @@ from jwt.algorithms import has_crypto from jwt.api_jwk import PyJWK, PyJWKSet from jwt.exceptions import InvalidKeyError, PyJWKError, PyJWKSetError -from .utils import crypto_required, key_path +from .utils import crypto_required, key_path, no_crypto_required if has_crypto: from jwt.algorithms import ECAlgorithm, HMACAlgorithm, OKPAlgorithm, RSAAlgorithm @@ -207,6 +207,12 @@ class TestPyJWK: with pytest.raises(InvalidKeyError): PyJWK.from_dict(v) + @no_crypto_required + def test_missing_crypto_library_good_error_message(self): + with pytest.raises(PyJWKError) as exc: + PyJWK({"kty": "dummy"}, algorithm="RS256") + assert "cryptography" in str(exc.value) + @crypto_required class TestPyJWKSet: -- cgit v1.2.1