From 258d7bab0ecb86be91738ac1e23744429280acd1 Mon Sep 17 00:00:00 2001 From: Kevin Kirsche Date: Tue, 5 Oct 2021 22:13:28 -0400 Subject: [PATCH] Use timezone package as Python 3.5+ is required (#694) * Use timezone package as Python 3.5+ is required This method is deprecated: https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow Replaced with: https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow using: https://docs.python.org/3/library/datetime.html#datetime.timezone.utc which seems to indicate this was added in Python 3.2 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/usage.rst | 11 ++++++----- jwt/api_jwt.py | 4 ++-- tests/test_api_jwt.py | 10 +++++----- tests/utils.py | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 2eacb969..0c6794bc 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -119,7 +119,7 @@ datetime, which will be converted into an int. For example: .. code-block:: python jwt.encode({"exp": 1371720939}, "secret") - jwt.encode({"exp": datetime.utcnow()}, "secret") + jwt.encode({"exp": datetime.now(tz=timezone.utc)}, "secret") Expiration time is automatically verified in `jwt.decode()` and raises `jwt.ExpiredSignatureError` if the expiration time is in the past: @@ -133,7 +133,7 @@ Expiration time is automatically verified in `jwt.decode()` and raises ... Expiration time will be compared to the current UTC time (as given by -`timegm(datetime.utcnow().utctimetuple())`), so be sure to use a UTC timestamp +`timegm(datetime.now(tz=timezone.utc).utctimetuple())`), so be sure to use a UTC timestamp or datetime in encoding. You can turn off expiration time verification with the `verify_exp` parameter in the options argument. @@ -147,7 +147,8 @@ you can set a leeway of 10 seconds in order to have some margin: .. code-block:: python jwt_payload = jwt.encode( - {"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30)}, "secret" + {"exp": datetime.datetime.now(tz=timezone.utc) + datetime.timedelta(seconds=30)}, + "secret", ) time.sleep(32) @@ -181,7 +182,7 @@ The `nbf` claim works similarly to the `exp` claim above. .. code-block:: python jwt.encode({"nbf": 1371720939}, "secret") - jwt.encode({"nbf": datetime.utcnow()}, "secret") + jwt.encode({"nbf": datetime.now(tz=timezone.utc)}, "secret") Issuer Claim (iss) ~~~~~~~~~~~~~~~~~~ @@ -259,7 +260,7 @@ Issued At Claim (iat) .. code-block:: python jwt.encode({"iat": 1371720939}, "secret") - jwt.encode({"iat": datetime.utcnow()}, "secret") + jwt.encode({"iat": datetime.now(tz=timezone.utc)}, "secret") Requiring Presence of Claims ---------------------------- diff --git a/jwt/api_jwt.py b/jwt/api_jwt.py index 2e9760fe..7e21b754 100644 --- a/jwt/api_jwt.py +++ b/jwt/api_jwt.py @@ -1,7 +1,7 @@ import json from calendar import timegm from collections.abc import Iterable, Mapping -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from typing import Any, Dict, List, Optional, Type, Union from . import api_jws @@ -133,7 +133,7 @@ def _validate_claims(self, payload, options, audience, issuer, leeway): self._validate_required_claims(payload, options) - now = timegm(datetime.utcnow().utctimetuple()) + now = timegm(datetime.now(tz=timezone.utc).utctimetuple()) if "iat" in payload and options["verify_iat"]: self._validate_iat(payload, now, leeway) diff --git a/tests/test_api_jwt.py b/tests/test_api_jwt.py index 3f274a37..53fd150e 100644 --- a/tests/test_api_jwt.py +++ b/tests/test_api_jwt.py @@ -1,7 +1,7 @@ import json import time from calendar import timegm -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from decimal import Decimal import pytest @@ -252,7 +252,7 @@ def test_decode_raises_exception_if_aud_is_none(self, jwt): def test_encode_datetime(self, jwt): secret = "secret" - current_datetime = datetime.utcnow() + current_datetime = datetime.now(tz=timezone.utc) payload = { "exp": current_datetime, "iat": current_datetime, @@ -499,7 +499,7 @@ def test_skip_check_audience(self, jwt): def test_skip_check_exp(self, jwt): payload = { "some": "payload", - "exp": datetime.utcnow() - timedelta(days=1), + "exp": datetime.now(tz=timezone.utc) - timedelta(days=1), } token = jwt.encode(payload, "secret") jwt.decode( @@ -576,7 +576,7 @@ def test_skip_check_signature(self, jwt): def test_skip_check_iat(self, jwt): payload = { "some": "payload", - "iat": datetime.utcnow() + timedelta(days=1), + "iat": datetime.now(tz=timezone.utc) + timedelta(days=1), } token = jwt.encode(payload, "secret") jwt.decode( @@ -589,7 +589,7 @@ def test_skip_check_iat(self, jwt): def test_skip_check_nbf(self, jwt): payload = { "some": "payload", - "nbf": datetime.utcnow() + timedelta(days=1), + "nbf": datetime.now(tz=timezone.utc) + timedelta(days=1), } token = jwt.encode(payload, "secret") jwt.decode( diff --git a/tests/utils.py b/tests/utils.py index faa3d5a6..34091b5e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,6 +1,6 @@ import os from calendar import timegm -from datetime import datetime +from datetime import datetime, timezone import pytest @@ -8,7 +8,7 @@ def utc_timestamp(): - return timegm(datetime.utcnow().utctimetuple()) + return timegm(datetime.now(tz=timezone.utc).utctimetuple()) def key_path(key_name):