|
4 | 4 | import warnings |
5 | 5 |
|
6 | 6 | from flask import Flask |
7 | | -from jwt import ExpiredSignatureError, InvalidSignatureError, InvalidAudienceError |
| 7 | + |
| 8 | +from jwt import ( |
| 9 | + ExpiredSignatureError, InvalidSignatureError, InvalidAudienceError, |
| 10 | + ImmatureSignatureError |
| 11 | +) |
8 | 12 |
|
9 | 13 | from flask_jwt_extended import ( |
10 | 14 | JWTManager, create_access_token, decode_token, create_refresh_token, |
@@ -37,6 +41,20 @@ def default_access_token(app): |
37 | 41 | } |
38 | 42 |
|
39 | 43 |
|
| 44 | +@pytest.fixture(scope='function') |
| 45 | +def patch_datetime_now(monkeypatch): |
| 46 | + |
| 47 | + DATE_IN_FUTURE = datetime.utcnow() + timedelta(seconds=30) |
| 48 | + |
| 49 | + class mydatetime(datetime): |
| 50 | + @classmethod |
| 51 | + def utcnow(cls): |
| 52 | + return DATE_IN_FUTURE |
| 53 | + |
| 54 | + monkeypatch.setattr(__name__ + ".datetime", mydatetime) |
| 55 | + monkeypatch.setattr("datetime.datetime", mydatetime) |
| 56 | + |
| 57 | + |
40 | 58 | @pytest.mark.parametrize("user_loader_return", [{}, None]) |
41 | 59 | def test_no_user_claims(app, user_loader_return): |
42 | 60 | jwtM = get_jwt_manager(app) |
@@ -107,6 +125,18 @@ def test_never_expire_token(app): |
107 | 125 | assert 'exp' not in decoded |
108 | 126 |
|
109 | 127 |
|
| 128 | +def test_nbf_token_in_future(app, patch_datetime_now): |
| 129 | + with pytest.raises(ImmatureSignatureError): |
| 130 | + with app.test_request_context(): |
| 131 | + access_token = create_access_token('username') |
| 132 | + decode_token(access_token) |
| 133 | + |
| 134 | + with app.test_request_context(): |
| 135 | + app.config['JWT_DECODE_LEEWAY'] = 30 |
| 136 | + access_token = create_access_token('username') |
| 137 | + decode_token(access_token) |
| 138 | + |
| 139 | + |
110 | 140 | def test_alternate_identity_claim(app, default_access_token): |
111 | 141 | app.config['JWT_IDENTITY_CLAIM'] = 'sub' |
112 | 142 |
|
|
0 commit comments