Hello community,
here is the log from the commit of package python-flask-jwt-extended for
openSUSE:Factory checked in at 2019-08-13 13:27:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-flask-jwt-extended (Old)
and /work/SRC/openSUSE:Factory/.python-flask-jwt-extended.new.9556 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-flask-jwt-extended"
Tue Aug 13 13:27:12 2019 rev:3 rq:722843 version:3.21.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-flask-jwt-extended/python-flask-jwt-extended.changes
2019-07-24 20:34:55.342578120 +0200
+++
/work/SRC/openSUSE:Factory/.python-flask-jwt-extended.new.9556/python-flask-jwt-extended.changes
2019-08-13 13:27:15.217323820 +0200
@@ -1,0 +2,9 @@
+Mon Aug 12 15:45:57 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 3.21.0:
+ * Require flask 1.0 or greater (#263)
+ * Move docs to pallets-sphinx-themes (#261)
+ * Add a new JWT_DECODE_ISSUER option for use with other JWT providers (#259)
+ * Gracefully handle errors for malformed tokens (#246)
+
+-------------------------------------------------------------------
Old:
----
Flask-JWT-Extended-3.20.0.tar.gz
New:
----
Flask-JWT-Extended-3.21.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-flask-jwt-extended.spec ++++++
--- /var/tmp/diff_new_pack.ng7oMd/_old 2019-08-13 13:27:15.873323647 +0200
+++ /var/tmp/diff_new_pack.ng7oMd/_new 2019-08-13 13:27:15.873323647 +0200
@@ -17,13 +17,13 @@
Name: python-flask-jwt-extended
-Version: 3.20.0
+Version: 3.21.0
Release: 0
Summary: An open source Flask extension that provides JWT support
License: MIT
Group: Development/Languages/Python
URL: https://github.com/vimalloc/flask-jwt-extended
-Source:
https://files.pythonhosted.org/packages/source/f/flask-jwt-extended/Flask-JWT-Extended-%{version}.tar.gz
+Source:
https://files.pythonhosted.org/packages/source/F/Flask-JWT-Extended/Flask-JWT-Extended-%{version}.tar.gz
BuildRequires: %{python_module Flask >= 1.0}
BuildRequires: %{python_module PyJWT >= 1.6.4}
BuildRequires: %{python_module Werkzeug >= 0.14}
++++++ Flask-JWT-Extended-3.20.0.tar.gz -> Flask-JWT-Extended-3.21.0.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/Flask_JWT_Extended.egg-info/PKG-INFO
new/Flask-JWT-Extended-3.21.0/Flask_JWT_Extended.egg-info/PKG-INFO
--- old/Flask-JWT-Extended-3.20.0/Flask_JWT_Extended.egg-info/PKG-INFO
2019-07-03 17:26:49.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/Flask_JWT_Extended.egg-info/PKG-INFO
2019-08-03 17:50:24.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: Flask-JWT-Extended
-Version: 3.20.0
+Version: 3.21.0
Summary: Extended JWT integration with Flask
Home-page: https://github.com/vimalloc/flask-jwt-extended
Author: Landon Gilbert-Bland
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/Flask_JWT_Extended.egg-info/requires.txt
new/Flask-JWT-Extended-3.21.0/Flask_JWT_Extended.egg-info/requires.txt
--- old/Flask-JWT-Extended-3.20.0/Flask_JWT_Extended.egg-info/requires.txt
2019-07-03 17:26:49.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/Flask_JWT_Extended.egg-info/requires.txt
2019-08-03 17:50:24.000000000 +0200
@@ -1,5 +1,5 @@
Werkzeug>=0.14
-Flask
+Flask>=1.0
PyJWT>=1.6.4
six
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-JWT-Extended-3.20.0/PKG-INFO
new/Flask-JWT-Extended-3.21.0/PKG-INFO
--- old/Flask-JWT-Extended-3.20.0/PKG-INFO 2019-07-03 17:26:53.000000000
+0200
+++ new/Flask-JWT-Extended-3.21.0/PKG-INFO 2019-08-03 17:50:24.000000000
+0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: Flask-JWT-Extended
-Version: 3.20.0
+Version: 3.21.0
Summary: Extended JWT integration with Flask
Home-page: https://github.com/vimalloc/flask-jwt-extended
Author: Landon Gilbert-Bland
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/__init__.py
new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/__init__.py
--- old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/__init__.py
2019-07-03 17:21:11.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/__init__.py
2019-08-03 17:42:04.000000000 +0200
@@ -11,4 +11,4 @@
unset_jwt_cookies, unset_refresh_cookies
)
-__version__ = '3.20.0'
+__version__ = '3.21.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/config.py
new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/config.py
--- old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/config.py 2019-07-03
17:20:36.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/config.py 2019-08-03
17:16:25.000000000 +0200
@@ -317,6 +317,10 @@
return current_app.config['JWT_DECODE_AUDIENCE']
@property
+ def issuer(self):
+ return current_app.config['JWT_DECODE_ISSUER']
+
+ @property
def leeway(self):
return current_app.config['JWT_DECODE_LEEWAY']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/jwt_manager.py
new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/jwt_manager.py
--- old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/jwt_manager.py
2019-07-03 17:20:36.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/jwt_manager.py
2019-08-03 17:34:19.000000000 +0200
@@ -1,7 +1,10 @@
import datetime
from warnings import warn
-from jwt import ExpiredSignatureError, InvalidTokenError, InvalidAudienceError
+from jwt import (
+ ExpiredSignatureError, InvalidTokenError, InvalidAudienceError,
+ InvalidIssuerError, DecodeError
+)
try:
from flask import _app_ctx_stack as ctx_stack
except ImportError: # pragma: no cover
@@ -110,6 +113,10 @@
def handle_invalid_header_error(e):
return self._invalid_token_callback(str(e))
+ @app.errorhandler(DecodeError)
+ def handle_invalid_header_error(e):
+ return self._invalid_token_callback(str(e))
+
@app.errorhandler(InvalidTokenError)
def handle_invalid_token_error(e):
return self._invalid_token_callback(str(e))
@@ -126,6 +133,10 @@
def handle_invalid_audience_error(e):
return self._invalid_token_callback(str(e))
+ @app.errorhandler(InvalidIssuerError)
+ def handle_invalid_issuer_error(e):
+ return self._invalid_token_callback(str(e))
+
@app.errorhandler(RevokedTokenError)
def handle_revoked_token_error(e):
return self._revoked_token_callback()
@@ -214,6 +225,7 @@
app.config.setdefault('JWT_IDENTITY_CLAIM', 'identity')
app.config.setdefault('JWT_USER_CLAIMS', 'user_claims')
app.config.setdefault('JWT_DECODE_AUDIENCE', None)
+ app.config.setdefault('JWT_DECODE_ISSUER', None)
app.config.setdefault('JWT_DECODE_LEEWAY', 0)
app.config.setdefault('JWT_CLAIMS_IN_REFRESH_TOKEN', False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/tokens.py
new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/tokens.py
--- old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/tokens.py 2019-07-03
17:20:36.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/tokens.py 2019-08-03
17:34:38.000000000 +0200
@@ -114,7 +114,7 @@
def decode_jwt(encoded_token, secret, algorithms, identity_claim_key,
user_claims_key, csrf_value=None, audience=None,
- leeway=0, allow_expired=False):
+ leeway=0, allow_expired=False, issuer=None):
"""
Decodes an encoded JWT
@@ -125,6 +125,7 @@
:param user_claims_key: expected key that contains the user claims
:param csrf_value: Expected double submit csrf value
:param audience: expected audience in the JWT
+ :param issuer: expected issuer in the JWT
:param leeway: optional leeway to add some margin around expiration times
:param allow_expired: Options to ignore exp claim validation in token
:return: Dictionary containing contents of the JWT
@@ -135,7 +136,7 @@
# This call verifies the ext, iat, nbf, and aud claims
data = jwt.decode(encoded_token, secret, algorithms=algorithms,
audience=audience,
- leeway=leeway, options=options)
+ leeway=leeway, options=options, issuer=issuer)
# Make sure that any custom claims we expect in the token are present
if 'jti' not in data:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/utils.py
new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/utils.py
--- old/Flask-JWT-Extended-3.20.0/flask_jwt_extended/utils.py 2019-07-03
17:20:36.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/flask_jwt_extended/utils.py 2019-08-03
17:15:19.000000000 +0200
@@ -103,6 +103,7 @@
user_claims_key=config.user_claims_key,
csrf_value=csrf_value,
audience=config.audience,
+ issuer=config.issuer,
leeway=config.leeway,
allow_expired=allow_expired
)
@@ -115,6 +116,7 @@
user_claims_key=config.user_claims_key,
csrf_value=csrf_value,
audience=config.audience,
+ issuer=config.issuer,
leeway=config.leeway,
allow_expired=True
)
@@ -150,7 +152,7 @@
expiration. If this is None, it will use the
'JWT_ACCESS_TOKEN_EXPIRES` config value
(see :ref:`Configuration Options`)
- :param user_claims: Optionnal JSON serializable to override user claims.
+ :param user_claims: Optional JSON serializable to override user claims.
:return: An encoded access token
"""
jwt_manager = _get_jwt_manager()
@@ -172,7 +174,7 @@
expiration. If this is None, it will use the
'JWT_REFRESH_TOKEN_EXPIRES` config value
(see :ref:`Configuration Options`)
- :param user_claims: Optionnal JSON serializable to override user claims.
+ :param user_claims: Optional JSON serializable to override user claims.
:return: An encoded refresh token
"""
jwt_manager = _get_jwt_manager()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-JWT-Extended-3.20.0/requirements.txt
new/Flask-JWT-Extended-3.21.0/requirements.txt
--- old/Flask-JWT-Extended-3.20.0/requirements.txt 2019-01-03
18:24:37.000000000 +0100
+++ new/Flask-JWT-Extended-3.21.0/requirements.txt 2019-08-03
16:59:26.000000000 +0200
@@ -1,35 +1,43 @@
alabaster==0.7.12
asn1crypto==0.24.0
-Babel==2.6.0
-certifi==2018.11.29
-cffi==1.11.5
+attrs==19.1.0
+Babel==2.7.0
+certifi==2019.6.16
+cffi==1.12.3
chardet==3.0.4
Click==7.0
-cryptography==2.4.2
-docutils==0.14
-filelock==3.0.10
-Flask==1.0.2
-Flask-Sphinx-Themes==1.0.2
+cryptography==2.7
+docutils==0.15.2
+filelock==3.0.12
+Flask==1.1.1
idna==2.8
imagesize==1.1.0
+importlib-metadata==0.19
itsdangerous==1.1.0
-Jinja2==2.10
-MarkupSafe==1.1.0
-packaging==18.0
-pluggy==0.8.0
-py==1.7.0
+Jinja2==2.10.1
+MarkupSafe==1.1.1
+packaging==19.1
+Pallets-Sphinx-Themes==1.2.1
+pluggy==0.12.0
+py==1.8.0
pycparser==2.19
-Pygments==2.3.1
+Pygments==2.4.2
PyJWT==1.7.1
-pyparsing==2.3.0
-pytz==2018.7
-requests==2.21.0
+pyparsing==2.4.2
+pytz==2019.2
+requests==2.22.0
six==1.12.0
-snowballstemmer==1.2.1
-Sphinx==1.8.3
-sphinxcontrib-websupport==1.1.0
+snowballstemmer==1.9.0
+Sphinx==2.1.2
+sphinxcontrib-applehelp==1.0.1
+sphinxcontrib-devhelp==1.0.1
+sphinxcontrib-htmlhelp==1.0.2
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.2
+sphinxcontrib-serializinghtml==1.1.3
toml==0.10.0
-tox==3.6.1
-urllib3==1.24.1
-virtualenv==16.2.0
-Werkzeug==0.14.1
+tox==3.13.2
+urllib3==1.25.3
+virtualenv==16.7.2
+Werkzeug==0.15.5
+zipp==0.5.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-JWT-Extended-3.20.0/setup.py
new/Flask-JWT-Extended-3.21.0/setup.py
--- old/Flask-JWT-Extended-3.20.0/setup.py 2019-05-10 23:50:27.000000000
+0200
+++ new/Flask-JWT-Extended-3.21.0/setup.py 2019-08-03 16:52:54.000000000
+0200
@@ -30,7 +30,7 @@
platforms='any',
install_requires=[
'Werkzeug>=0.14', # Needed for SameSite cookie functionality
- 'Flask',
+ 'Flask>=1.0',
'PyJWT>=1.6.4',
'six',
],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/tests/test_decode_tokens.py
new/Flask-JWT-Extended-3.21.0/tests/test_decode_tokens.py
--- old/Flask-JWT-Extended-3.20.0/tests/test_decode_tokens.py 2019-03-02
05:58:44.000000000 +0100
+++ new/Flask-JWT-Extended-3.21.0/tests/test_decode_tokens.py 2019-08-03
17:35:12.000000000 +0200
@@ -8,7 +8,7 @@
from jwt import (
ExpiredSignatureError, InvalidSignatureError, InvalidAudienceError,
- ImmatureSignatureError
+ ImmatureSignatureError, InvalidIssuerError, DecodeError
)
from flask_jwt_extended import (
@@ -246,9 +246,9 @@
app.config['JWT_DECODE_AUDIENCE'] = ['foo', 'bar']
default_access_token['aud'] = token_aud
- invalid_token = encode_token(app, default_access_token)
+ valid_token = encode_token(app, default_access_token)
with app.test_request_context():
- decoded = decode_token(invalid_token)
+ decoded = decode_token(valid_token)
assert decoded['aud'] == token_aud
@@ -261,3 +261,28 @@
with pytest.raises(InvalidAudienceError):
with app.test_request_context():
decode_token(invalid_token)
+
+def test_valid_iss(app, default_access_token):
+ app.config['JWT_DECODE_ISSUER'] = 'foobar'
+
+ default_access_token['iss'] = 'foobar'
+ valid_token = encode_token(app, default_access_token)
+ with app.test_request_context():
+ decoded = decode_token(valid_token)
+ assert decoded['iss'] == 'foobar'
+
+def test_invalid_iss(app, default_access_token):
+ app.config['JWT_DECODE_ISSUER'] = 'baz'
+
+ default_access_token['iss'] = 'foobar'
+ invalid_token = encode_token(app, default_access_token)
+ with pytest.raises(InvalidIssuerError):
+ with app.test_request_context():
+ decode_token(invalid_token)
+
+
+def test_malformed_token(app):
+ invalid_token = 'foobarbaz'
+ with pytest.raises(DecodeError):
+ with app.test_request_context():
+ decode_token(invalid_token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-JWT-Extended-3.20.0/tests/test_view_decorators.py
new/Flask-JWT-Extended-3.21.0/tests/test_view_decorators.py
--- old/Flask-JWT-Extended-3.20.0/tests/test_view_decorators.py 2019-05-10
23:50:27.000000000 +0200
+++ new/Flask-JWT-Extended-3.21.0/tests/test_view_decorators.py 2019-08-03
17:37:29.000000000 +0200
@@ -216,7 +216,6 @@
def test_jwt_invalid_audience(app):
url = '/protected'
- jwtM = get_jwt_manager(app)
test_client = app.test_client()
# No audience claim expected or provided - OK
@@ -238,6 +237,39 @@
assert response.get_json() == {'msg': 'Invalid audience'}
+def test_jwt_invalid_issuer(app):
+ url = '/protected'
+ test_client = app.test_client()
+
+ # No issuer claim expected or provided - OK
+ access_token = encode_token(app, {'identity': 'me'})
+ response = test_client.get(url, headers=make_headers(access_token))
+ assert response.status_code == 200
+
+ # Issuer claim expected and not provided - not OK
+ app.config['JWT_DECODE_ISSUER'] = 'my_issuer'
+ access_token = encode_token(app, {'identity': 'me'})
+ response = test_client.get(url, headers=make_headers(access_token))
+ assert response.status_code == 422
+ assert response.get_json() == {'msg': 'Token is missing the "iss" claim'}
+
+ # Issuer claim still expected and wrong one provided - not OK
+ access_token = encode_token(app, {'iss': 'different_issuer', 'identity':
'me'})
+ response = test_client.get(url, headers=make_headers(access_token))
+ assert response.status_code == 422
+ assert response.get_json() == {'msg': 'Invalid issuer'}
+
+
+def test_malformed_token(app):
+ url = '/protected'
+ test_client = app.test_client()
+
+ access_token = 'foobarbaz'
+ response = test_client.get(url, headers=make_headers(access_token))
+ assert response.status_code == 422
+ assert response.get_json() == {'msg': 'Not enough segments'}
+
+
@pytest.mark.parametrize("delta_func", [timedelta, relativedelta])
def test_expired_token(app, delta_func):
url = '/protected'