diff options
author | Markus Holtermann <info@markusholtermann.eu> | 2017-12-01 20:11:09 +0100 |
---|---|---|
committer | José Padilla <jpadilla@webapplicate.com> | 2017-12-01 14:11:09 -0500 |
commit | 0c80a7119a1a82e7023ab3b0c766311de5821707 (patch) | |
tree | 374f535413b80de40fd6d3711de6d0dd98ef724f | |
parent | e0aa10ee586bf010ce9a99c5582ee8dc9293ba1e (diff) | |
download | pyjwt-0c80a7119a1a82e7023ab3b0c766311de5821707.tar.gz |
Fix #315: Raise InvalidSignatureError over generic DecodeError (#316)
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | docs/api.rst | 5 | ||||
-rw-r--r-- | jwt/api_jws.py | 7 | ||||
-rw-r--r-- | jwt/exceptions.py | 4 | ||||
-rw-r--r-- | tests/test_api_jws.py | 11 |
5 files changed, 26 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5793d70..68eb2ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Audience parameter now supports iterables [#205][205] +- An invalid signature now raises an `InvalidSignatureError` instead of `DecodeError` [#315][315] + ### Fixed ### Added @@ -204,4 +206,5 @@ rarely used. Users affected by this should upgrade to 3.3+. [271]: https://github.com/jpadilla/pyjwt/pull/271 [277]: https://github.com/jpadilla/pyjwt/pull/277 [281]: https://github.com/jpadilla/pyjwt/pull/281 +[315]: https://github.com/jpadilla/pyjwt/pull/315 [7c1e61d]: https://github.com/jpadilla/pyjwt/commit/7c1e61dde27bafe16e7d1bb6e35199e778962742 diff --git a/docs/api.rst b/docs/api.rst index 4bb4d3b..08b6991 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -19,6 +19,11 @@ Exceptions Raised when a token cannot be decoded because it failed validation +.. class:: InvalidSignatureError + + Raised when a token's signature doesn't match the one provided as part of + the token. + .. class:: ExpiredSignatureError Raised when a token's ``exp`` claim indicates that it has expired diff --git a/jwt/api_jws.py b/jwt/api_jws.py index ad3ff6a..b796fa7 100644 --- a/jwt/api_jws.py +++ b/jwt/api_jws.py @@ -7,7 +7,10 @@ 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 .exceptions import ( + DecodeError, InvalidAlgorithmError, InvalidSignatureError, + InvalidTokenError +) from .utils import base64url_decode, base64url_encode, force_bytes, merge_dict @@ -203,7 +206,7 @@ class PyJWS(object): key = alg_obj.prepare_key(key) if not alg_obj.verify(signing_input, key, signature): - raise DecodeError('Signature verification failed') + raise InvalidSignatureError('Signature verification failed') except KeyError: raise InvalidAlgorithmError('Algorithm not supported') diff --git a/jwt/exceptions.py b/jwt/exceptions.py index 31177a0..b396bf1 100644 --- a/jwt/exceptions.py +++ b/jwt/exceptions.py @@ -6,6 +6,10 @@ class DecodeError(InvalidTokenError): pass +class InvalidSignatureError(DecodeError): + pass + + class ExpiredSignatureError(InvalidTokenError): pass diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py index 60671a2..4bf8d39 100644 --- a/tests/test_api_jws.py +++ b/tests/test_api_jws.py @@ -5,7 +5,8 @@ from decimal import Decimal from jwt.algorithms import Algorithm from jwt.api_jws import PyJWS from jwt.exceptions import ( - DecodeError, InvalidAlgorithmError, InvalidTokenError + DecodeError, InvalidAlgorithmError, InvalidSignatureError, + InvalidTokenError ) from jwt.utils import base64url_decode, force_bytes, force_unicode @@ -178,8 +179,14 @@ class TestJWS: bad_secret = 'bar' jws_message = jws.encode(payload, right_secret) - with pytest.raises(DecodeError): + with pytest.raises(DecodeError) as excinfo: + # Backward compat for ticket #315 + jws.decode(jws_message, bad_secret) + assert 'Signature verification failed' == str(excinfo.value) + + with pytest.raises(InvalidSignatureError) as excinfo: jws.decode(jws_message, bad_secret) + assert 'Signature verification failed' == str(excinfo.value) def test_decodes_valid_jws(self, jws, payload): example_secret = 'secret' |