diff --git a/CHANGELOG.md b/CHANGELOG.md index 56e4145f..04e52594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,26 @@ This project adheres to [Semantic Versioning](http://semver.org/). [Unreleased][unreleased] ------------------------------------------------------------------------- ### Changed + +### Fixed + +[v1.5.0][1.5.0] +------------------------------------------------------------------------- +### Changed - Add support for ECDSA public keys in RFC 4253 (OpenSSH) format [#244][244] -- Renamed commandline script `jwt` to `jwt-cli` to avoid issues with the script clobbering the `jwt` module in some circumstances. +- Renamed commandline script `jwt` to `jwt-cli` to avoid issues with the script clobbering the `jwt` module in some circumstances. [#187][187] - Better error messages when using an algorithm that requires the cryptography package, but it isn't available [#230][230] -------------------------------------------------------------------------- +- Tokens with future 'iat' values are no longer rejected [#190][190] +- Non-numeric 'iat' values now raise InvalidIssuedAtError instead of DecodeError +- Remove rejection of future 'iat' claims [#252][252] ### Fixed +- Add back 'ES512' for backward compatibility (for now) [#225][225] +- Fix incorrectly named ECDSA algorithm [#219][219] +- Fix rpm build [#196][196] + +### Added +- Add JWK support for HMAC and RSA keys [#202][202] [v1.4.2][1.4.2] ------------------------------------------------------------------------- @@ -110,8 +124,7 @@ rarely used. Users affected by this should upgrade to 3.3+. [1.4.0]: https://github.com/jpadilla/pyjwt/compare/1.3.0...1.4.0 [1.4.1]: https://github.com/jpadilla/pyjwt/compare/1.4.0...1.4.1 [1.4.2]: https://github.com/jpadilla/pyjwt/compare/1.4.1...1.4.2 - - +[1.5.0]: https://github.com/jpadilla/pyjwt/compare/1.4.2...1.5.0 [109]: https://github.com/jpadilla/pyjwt/pull/109 [110]: https://github.com/jpadilla/pyjwt/pull/110 @@ -130,5 +143,13 @@ rarely used. Users affected by this should upgrade to 3.3+. [174]: https://github.com/jpadilla/pyjwt/pull/174 [182]: https://github.com/jpadilla/pyjwt/pull/182 [183]: https://github.com/jpadilla/pyjwt/pull/183 +[190]: https://github.com/jpadilla/pyjwt/pull/190 [213]: https://github.com/jpadilla/pyjwt/pull/214 [244]: https://github.com/jpadilla/pyjwt/pull/244 +[202]: https://github.com/jpadilla/pyjwt/pull/202 +[252]: https://github.com/jpadilla/pyjwt/pull/252 +[225]: https://github.com/jpadilla/pyjwt/pull/225 +[219]: https://github.com/jpadilla/pyjwt/pull/219 +[196]: https://github.com/jpadilla/pyjwt/pull/196 +[187]: https://github.com/jpadilla/pyjwt/pull/187 +[230]: https://github.com/jpadilla/pyjwt/pull/230 diff --git a/docs/faq.rst b/docs/faq.rst index 59a6cb68..a5eb1396 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -9,6 +9,7 @@ extract the public or private keys from a x509 certificate in PEM format. .. code-block:: python + # Python 2 from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.backends import default_backend @@ -17,6 +18,18 @@ extract the public or private keys from a x509 certificate in PEM format. public_key = cert_obj.public_key() private_key = cert_obj.private_key() +.. code-block:: python + + # Python 3 + from cryptography.x509 import load_pem_x509_certificate + from cryptography.hazmat.backends import default_backend + + cert_str = "-----BEGIN CERTIFICATE-----MIIDETCCAfm...".encode() + cert_obj = load_pem_x509_certificate(cert_str, default_backend()) + public_key = cert_obj.public_key() + private_key = cert_obj.private_key() + + I'm using Google App Engine and can't install `cryptography`, what can I do? ---------------------------------------------------------------------------- diff --git a/docs/usage.rst b/docs/usage.rst index c2e286c6..a485a94d 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -180,8 +180,7 @@ Issued At Claim (iat) This claim can be used to determine the age of the JWT. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. -If the `iat` claim is in the future, an `jwt.InvalidIssuedAtError` exception -will be raised. + If the `iat` claim is not a number, an `jwt.InvalidIssuedAtError` exception will be raised. .. code-block:: python diff --git a/jwt/__init__.py b/jwt/__init__.py index 64b2f973..398d8540 100644 --- a/jwt/__init__.py +++ b/jwt/__init__.py @@ -10,7 +10,7 @@ __title__ = 'pyjwt' -__version__ = '1.4.2' +__version__ = '1.5.0' __author__ = 'José Padilla' __license__ = 'MIT' __copyright__ = 'Copyright 2015 José Padilla' diff --git a/jwt/api_jwt.py b/jwt/api_jwt.py index c6a6f527..ee9bf622 100644 --- a/jwt/api_jwt.py +++ b/jwt/api_jwt.py @@ -118,13 +118,9 @@ def _validate_required_claims(self, payload, options): def _validate_iat(self, payload, now, leeway): try: - iat = int(payload['iat']) + int(payload['iat']) except ValueError: - raise DecodeError('Issued At claim (iat) must be an integer.') - - if iat > (now + leeway): - raise InvalidIssuedAtError('Issued At claim (iat) cannot be in' - ' the future.') + raise InvalidIssuedAtError('Issued At claim (iat) must be an integer.') def _validate_nbf(self, payload, now, leeway): try: diff --git a/setup.cfg b/setup.cfg index 80f5ae00..e66417cf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,13 +1,13 @@ [flake8] max-line-length = 119 -exclude = +exclude = docs/, .tox/ [wheel] universal = 1 -[pytest] +[tool:pytest] addopts = --cov-report term-missing --cov-config=.coveragerc --cov . [aliases] diff --git a/setup.py b/setup.py index a2bd736b..e53eb839 100755 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ def get_version(package): sys.exit() tests_require = [ - 'pytest==2.7.3', + 'pytest >3,<4', 'pytest-cov', 'pytest-runner', ] diff --git a/tests/test_api_jwt.py b/tests/test_api_jwt.py index 0bae3f7c..f1151c91 100644 --- a/tests/test_api_jwt.py +++ b/tests/test_api_jwt.py @@ -142,7 +142,7 @@ def test_decode_raises_exception_if_iat_is_not_int(self, jwt): 'eyJpYXQiOiJub3QtYW4taW50In0.' 'H1GmcQgSySa5LOKYbzGm--b1OmRbHFkyk8pq811FzZM') - with pytest.raises(DecodeError): + with pytest.raises(InvalidIssuedAtError): jwt.decode(example_jwt, 'secret') def test_decode_raises_exception_if_nbf_is_not_int(self, jwt): @@ -154,13 +154,6 @@ def test_decode_raises_exception_if_nbf_is_not_int(self, jwt): with pytest.raises(DecodeError): jwt.decode(example_jwt, 'secret') - def test_decode_raises_exception_if_iat_in_the_future(self, jwt): - now = datetime.utcnow() - token = jwt.encode({'iat': now + timedelta(days=1)}, key='secret') - - with pytest.raises(InvalidIssuedAtError): - jwt.decode(token, 'secret') - def test_encode_datetime(self, jwt): secret = 'secret' current_datetime = datetime.utcnow()