summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adams <mark@markadams.me>2016-11-30 19:46:48 -0600
committerGitHub <noreply@github.com>2016-11-30 19:46:48 -0600
commit7dd3d4a16ca270d6de8db077b7c61abc0f4d2f0d (patch)
tree9a363228874fbbf8faa4e72aece5c0bc8e277f7d
parent5caa1af9d57c3621596a12aeaa4693bda5f15596 (diff)
parent439f9a33389193ceacfe188127cae6f0b61d7f73 (diff)
downloadpyjwt-7dd3d4a16ca270d6de8db077b7c61abc0f4d2f0d.tar.gz
Merge pull request #231 from vimalloc/master
Better error messages when missing cryptography package
-rw-r--r--CHANGELOG.md1
-rw-r--r--jwt/__main__.py1
-rw-r--r--jwt/algorithms.py4
-rw-r--r--jwt/api_jws.py13
-rw-r--r--tests/keys/__init__.py1
-rw-r--r--tests/test_api_jws.py6
-rw-r--r--tests/utils.py1
7 files changed, 25 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b5c398e..37b6ffd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
-------------------------------------------------------------------------
### Changed
- Renamed commandline script `jwt` to `jwt-cli` to avoid issues with the script clobbering the `jwt` module in some circumstances.
+- Better error messages when using an algorithm that requires the cryptography package, but it isn't available [#230][230]
### Fixed
diff --git a/jwt/__main__.py b/jwt/__main__.py
index 94abf2a..6a36953 100644
--- a/jwt/__main__.py
+++ b/jwt/__main__.py
@@ -131,5 +131,6 @@ The exp key is special and can take an offset to current Unix time.\
else:
p.print_help()
+
if __name__ == '__main__':
main()
diff --git a/jwt/algorithms.py b/jwt/algorithms.py
index 893833b..2fe1883 100644
--- a/jwt/algorithms.py
+++ b/jwt/algorithms.py
@@ -31,6 +31,9 @@ try:
except ImportError:
has_crypto = False
+requires_cryptography = set(['RS256', 'RS384', 'RS512', 'ES256', 'ES384',
+ 'ES521', 'ES512', 'PS256', 'PS384', 'PS512'])
+
def get_default_algorithms():
"""
@@ -171,6 +174,7 @@ class HMACAlgorithm(Algorithm):
def verify(self, msg, key, sig):
return constant_time_compare(sig, self.sign(msg, key))
+
if has_crypto:
class RSAAlgorithm(Algorithm):
diff --git a/jwt/api_jws.py b/jwt/api_jws.py
index f4e58b7..66b6a67 100644
--- a/jwt/api_jws.py
+++ b/jwt/api_jws.py
@@ -4,7 +4,9 @@ import warnings
from collections import Mapping
-from .algorithms import Algorithm, get_default_algorithms # NOQA
+from .algorithms import (
+ Algorithm, get_default_algorithms, has_crypto, requires_cryptography # NOQA
+)
from .compat import binary_type, string_types, text_type
from .exceptions import DecodeError, InvalidAlgorithmError, InvalidTokenError
from .utils import base64url_decode, base64url_encode, force_bytes, merge_dict
@@ -101,7 +103,13 @@ class PyJWS(object):
signature = alg_obj.sign(signing_input, key)
except KeyError:
- raise NotImplementedError('Algorithm not supported')
+ if not has_crypto and algorithm in requires_cryptography:
+ raise NotImplementedError(
+ "Algorithm '%s' could not be found. Do you have cryptography "
+ "installed?" % algorithm
+ )
+ else:
+ raise NotImplementedError('Algorithm not supported')
segments.append(base64url_encode(signature))
@@ -198,6 +206,7 @@ class PyJWS(object):
if not isinstance(kid, string_types):
raise InvalidTokenError('Key ID header parameter must be a string')
+
_jws_global_obj = PyJWS()
encode = _jws_global_obj.encode
decode = _jws_global_obj.decode
diff --git a/tests/keys/__init__.py b/tests/keys/__init__.py
index 4fae687..3727378 100644
--- a/tests/keys/__init__.py
+++ b/tests/keys/__init__.py
@@ -19,6 +19,7 @@ def load_hmac_key():
return base64url_decode(force_bytes(keyobj['k']))
+
try:
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py
index 403735d..053dd11 100644
--- a/tests/test_api_jws.py
+++ b/tests/test_api_jws.py
@@ -303,6 +303,12 @@ class TestJWS:
with pytest.raises(NotImplementedError):
jws.encode(payload, 'secret', algorithm='HS1024')
+ @pytest.mark.skipif(has_crypto, reason='Scenario requires cryptography to not be installed')
+ def test_missing_crypto_library_better_error_messages(self, jws, payload):
+ with pytest.raises(NotImplementedError) as excinfo:
+ jws.encode(payload, 'secret', algorithm='RS256')
+ assert 'cryptography' in str(excinfo.value)
+
def test_unicode_secret(self, jws, payload):
secret = '\xc2'
jws_message = jws.encode(payload, secret)
diff --git a/tests/utils.py b/tests/utils.py
index 2e3f043..79c77b0 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -13,6 +13,7 @@ def key_path(key_name):
return os.path.join(os.path.dirname(os.path.realpath(__file__)),
'keys', key_name)
+
# Borrowed from `cryptography`
if hasattr(int, "from_bytes"):
int_from_bytes = int.from_bytes