summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Padilla <jpadilla@webapplicate.com>2020-03-28 15:27:39 -0400
committerJosé Padilla <jpadilla@webapplicate.com>2020-04-06 09:35:51 -0400
commit24a5b2ff84dec9f109e3e32a10e5a079cb3e7ca8 (patch)
tree9f017a380a069c4006582376761a8838eeed4583
parente490f9d8b8bc927a0fb337eed446a44858886242 (diff)
downloadpyjwt-24a5b2ff84dec9f109e3e32a10e5a079cb3e7ca8.tar.gz
Handle deprecations
-rw-r--r--jwt/api_jws.py25
-rw-r--r--jwt/api_jwt.py30
-rw-r--r--tests/test_api_jws.py130
-rw-r--r--tests/test_api_jwt.py214
-rw-r--r--tests/test_jwt.py4
5 files changed, 239 insertions, 164 deletions
diff --git a/jwt/api_jws.py b/jwt/api_jws.py
index 6a1569e..7ed4467 100644
--- a/jwt/api_jws.py
+++ b/jwt/api_jws.py
@@ -1,6 +1,5 @@
import binascii
import json
-import warnings
from .algorithms import requires_cryptography # NOQA
from .algorithms import Algorithm, get_default_algorithms, has_crypto
@@ -132,7 +131,6 @@ class PyJWS(object):
self,
jwt, # type: str
key="", # type: str
- verify=True, # type: bool
algorithms=None, # type: List[str]
options=None, # type: Dict
complete=False, # type: bool
@@ -143,23 +141,14 @@ class PyJWS(object):
verify_signature = merged_options["verify_signature"]
if verify_signature and not algorithms:
- warnings.warn(
- "It is strongly recommended that you pass in a "
+ raise DecodeError(
+ "It is required that you pass in a "
+ 'value for the "algorithms" argument when calling decode(). '
- + "This argument will be mandatory in a future version.",
- DeprecationWarning,
)
payload, signing_input, header, signature = self._load(jwt)
- if not verify:
- warnings.warn(
- "The verify parameter is deprecated. "
- "Please use verify_signature in options instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- elif verify_signature:
+ if verify_signature:
self._verify_signature(
payload, signing_input, header, signature, key, algorithms
)
@@ -225,13 +214,7 @@ class PyJWS(object):
return (payload, signing_input, header, signature)
def _verify_signature(
- self,
- payload,
- signing_input,
- header,
- signature,
- key="",
- algorithms=None,
+ self, payload, signing_input, header, signature, key, algorithms
):
alg = header.get("alg")
diff --git a/jwt/api_jwt.py b/jwt/api_jwt.py
index 122204a..8749683 100644
--- a/jwt/api_jwt.py
+++ b/jwt/api_jwt.py
@@ -1,5 +1,4 @@
import json
-import warnings
from calendar import timegm
from datetime import datetime, timedelta
@@ -77,7 +76,6 @@ class PyJWT(PyJWS):
self,
jwt, # type: str
key="", # type: str
- verify=True, # type: bool
algorithms=None, # type: List[str]
options=None, # type: Dict
complete=False, # type: bool
@@ -85,20 +83,18 @@ class PyJWT(PyJWS):
):
# type: (...) -> Dict[str, Any]
- if verify and not algorithms:
- warnings.warn(
- "It is strongly recommended that you pass in a "
- + 'value for the "algorithms" argument when calling decode(). '
- + "This argument will be mandatory in a future version.",
- DeprecationWarning,
- )
-
payload, _, _, _ = self._load(jwt)
if options is None:
- options = {"verify_signature": verify}
+ options = {"verify_signature": True}
else:
- options.setdefault("verify_signature", verify)
+ options.setdefault("verify_signature", True)
+
+ if options["verify_signature"] and not algorithms:
+ raise DecodeError(
+ "It is required that you pass in a "
+ + 'value for the "algorithms" argument when calling decode(). '
+ )
decoded = super(PyJWT, self).decode(
jwt,
@@ -119,7 +115,7 @@ class PyJWT(PyJWS):
if not isinstance(payload, dict):
raise DecodeError("Invalid payload string: must be a json object")
- if verify:
+ if options["verify_signature"]:
merged_options = merge_dict(self.options, options)
self._validate_claims(payload, merged_options, **kwargs)
@@ -133,14 +129,6 @@ class PyJWT(PyJWS):
self, payload, options, audience=None, issuer=None, leeway=0, **kwargs
):
- if "verify_expiration" in kwargs:
- options["verify_exp"] = kwargs.get("verify_expiration", True)
- warnings.warn(
- "The verify_expiration parameter is deprecated. "
- "Please use verify_exp in options instead.",
- DeprecationWarning,
- )
-
if isinstance(leeway, timedelta):
leeway = leeway.total_seconds()
diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py
index 55db607..e2e51db 100644
--- a/tests/test_api_jws.py
+++ b/tests/test_api_jws.py
@@ -88,8 +88,8 @@ class TestJWS:
def test_encode_decode(self, jws, payload):
secret = "secret"
- jws_message = jws.encode(payload, secret)
- decoded_payload = jws.decode(jws_message, secret)
+ jws_message = jws.encode(payload, secret, algorithm="HS256")
+ decoded_payload = jws.decode(jws_message, secret, algorithms=["HS256"])
assert decoded_payload == payload
@@ -98,7 +98,7 @@ class TestJWS:
):
secret = "secret"
jws_token = jws.encode(payload, secret, algorithm="HS256")
- jws.decode(jws_token, secret)
+ jws.decode(jws_token, secret, algorithms=["HS256"])
with pytest.raises(InvalidAlgorithmError):
jws.decode(jws_token, secret, algorithms=["HS384"])
@@ -111,7 +111,7 @@ class TestJWS:
".tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8"
)
- jws.decode(unicode_jws, secret)
+ jws.decode(unicode_jws, secret, algorithms=["HS256"])
def test_decode_missing_segments_throws_exception(self, jws):
secret = "secret"
@@ -122,7 +122,7 @@ class TestJWS:
) # Missing segment
with pytest.raises(DecodeError) as context:
- jws.decode(example_jws, secret)
+ jws.decode(example_jws, secret, algorithms=["HS256"])
exception = context.value
assert str(exception) == "Not enough segments"
@@ -132,7 +132,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as context:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
exception = context.value
assert "Invalid token type" in str(exception)
@@ -142,7 +142,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as context:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
exception = context.value
assert "Invalid token type" in str(exception)
@@ -156,7 +156,7 @@ class TestJWS:
)
with pytest.raises(DecodeError) as context:
- jws.decode(example_jws, secret)
+ jws.decode(example_jws, secret, algorithms=["HS256"])
exception = context.value
assert str(exception) == "Invalid header string: must be a json object"
@@ -181,7 +181,7 @@ class TestJWS:
)
with pytest.raises(InvalidAlgorithmError) as context:
- jws.decode(example_jws, "secret")
+ jws.decode(example_jws, "secret", algorithms=["hs256"])
exception = context.value
assert str(exception) == "Algorithm not supported"
@@ -193,11 +193,11 @@ class TestJWS:
with pytest.raises(DecodeError) as excinfo:
# Backward compat for ticket #315
- jws.decode(jws_message, bad_secret)
+ jws.decode(jws_message, bad_secret, algorithms=["HS256"])
assert "Signature verification failed" == str(excinfo.value)
with pytest.raises(InvalidSignatureError) as excinfo:
- jws.decode(jws_message, bad_secret)
+ jws.decode(jws_message, bad_secret, algorithms=["HS256"])
assert "Signature verification failed" == str(excinfo.value)
def test_decodes_valid_jws(self, jws, payload):
@@ -208,7 +208,9 @@ class TestJWS:
b"gEW0pdU4kxPthjtehYdhxB9mMOGajt1xCKlGGXDJ8PM"
)
- decoded_payload = jws.decode(example_jws, example_secret)
+ decoded_payload = jws.decode(
+ example_jws, example_secret, algorithms=["HS256"]
+ )
assert decoded_payload == payload
@@ -228,7 +230,9 @@ class TestJWS:
b"eyJoZWxsbyI6IndvcmxkIn0.TORyNQab_MoXM7DvNKaTwbrJr4UY"
b"d2SsX8hhlnWelQFmPFSf_JzC2EbLnar92t-bXsDovzxp25ExazrVHkfPkQ"
)
- decoded_payload = jws.decode(example_jws, example_pubkey)
+ decoded_payload = jws.decode(
+ example_jws, example_pubkey, algorithms=["ES256"]
+ )
json_payload = json.loads(force_unicode(decoded_payload))
assert json_payload == example_payload
@@ -256,7 +260,9 @@ class TestJWS:
b"uwmrtSWCBUjiN8sqJ00CDgycxKqHfUndZbEAOjcCAhBr"
b"qWW3mSVivUfubsYbwUdUG3fSRPjaUPcpe8A"
)
- decoded_payload = jws.decode(example_jws, example_pubkey)
+ decoded_payload = jws.decode(
+ example_jws, example_pubkey, algorithms=["RS384"]
+ )
json_payload = json.loads(force_unicode(decoded_payload))
assert json_payload == example_payload
@@ -269,24 +275,19 @@ class TestJWS:
b"SIr03zM64awWRdPrAM_61QWsZchAtgDV3pphfHPPWkI"
)
- decoded_payload = jws.decode(example_jws, key=example_secret)
+ decoded_payload = jws.decode(
+ example_jws, key=example_secret, algorithms=["HS256"]
+ )
assert decoded_payload == payload
def test_allow_skip_verification(self, jws, payload):
right_secret = "foo"
jws_message = jws.encode(payload, right_secret)
- decoded_payload = jws.decode(jws_message, verify=False)
-
- assert decoded_payload == payload
-
- def test_verify_false_deprecated(self, jws, recwarn):
- example_jws = (
- b"eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9"
- b".eyJoZWxsbyI6ICJ3b3JsZCJ9"
- b".tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8"
+ decoded_payload = jws.decode(
+ jws_message, options={"verify_signature": False}
)
- pytest.deprecated_call(jws.decode, example_jws, verify=False)
+ assert decoded_payload == payload
def test_decode_with_optional_algorithms(self, jws):
example_secret = "secret"
@@ -296,7 +297,13 @@ class TestJWS:
b"SIr03zM64awWRdPrAM_61QWsZchAtgDV3pphfHPPWkI"
)
- pytest.deprecated_call(jws.decode, example_jws, key=example_secret)
+ with pytest.raises(DecodeError) as exc:
+ jws.decode(example_jws, key=example_secret)
+
+ assert (
+ 'It is required that you pass in a value for the "algorithms" argument when calling decode().'
+ in str(exc.value)
+ )
def test_decode_no_algorithms_verify_signature_false(self, jws):
example_secret = "secret"
@@ -306,23 +313,22 @@ class TestJWS:
b"SIr03zM64awWRdPrAM_61QWsZchAtgDV3pphfHPPWkI"
)
- try:
- pytest.deprecated_call(
- jws.decode,
- example_jws,
- key=example_secret,
- options={"verify_signature": False},
- )
- except pytest.fail.Exception:
- pass
- else:
- assert False, "Unexpected DeprecationWarning raised."
+ jws.decode(
+ example_jws,
+ key=example_secret,
+ options={"verify_signature": False},
+ )
def test_load_no_verification(self, jws, payload):
right_secret = "foo"
jws_message = jws.encode(payload, right_secret)
- decoded_payload = jws.decode(jws_message, key=None, verify=False)
+ decoded_payload = jws.decode(
+ jws_message,
+ key=None,
+ algorithms=["HS256"],
+ options={"verify_signature": False},
+ )
assert decoded_payload == payload
@@ -331,14 +337,14 @@ class TestJWS:
jws_message = jws.encode(payload, right_secret)
with pytest.raises(DecodeError):
- jws.decode(jws_message)
+ jws.decode(jws_message, algorithms=["HS256"])
def test_verify_signature_with_no_secret(self, jws, payload):
right_secret = "foo"
jws_message = jws.encode(payload, right_secret)
with pytest.raises(DecodeError) as exc:
- jws.decode(jws_message)
+ jws.decode(jws_message, algorithms=["HS256"])
assert "Signature verification" in str(exc.value)
@@ -352,7 +358,7 @@ class TestJWS:
)
with pytest.raises(InvalidAlgorithmError):
- jws.decode(example_jws, "secret")
+ jws.decode(example_jws, "secret", algorithms=["HS256"])
def test_invalid_crypto_alg(self, jws, payload):
with pytest.raises(NotImplementedError):
@@ -369,7 +375,7 @@ class TestJWS:
def test_unicode_secret(self, jws, payload):
secret = "\xc2"
jws_message = jws.encode(payload, secret)
- decoded_payload = jws.decode(jws_message, secret)
+ decoded_payload = jws.decode(jws_message, secret, algorithms=["HS256"])
assert decoded_payload == payload
@@ -377,7 +383,7 @@ class TestJWS:
secret = "\xc2" # char value that ascii codec cannot decode
jws_message = jws.encode(payload, secret)
- decoded_payload = jws.decode(jws_message, secret)
+ decoded_payload = jws.decode(jws_message, secret, algorithms=["HS256"])
assert decoded_payload == payload
@@ -385,7 +391,7 @@ class TestJWS:
secret = b"\xc2" # char value that ascii codec cannot decode
jws_message = jws.encode(payload, secret)
- decoded_payload = jws.decode(jws_message, secret)
+ decoded_payload = jws.decode(jws_message, secret, algorithms=["HS256"])
assert decoded_payload == payload
@@ -398,7 +404,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as exc:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
assert "header padding" in str(exc.value)
@@ -411,7 +417,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as exc:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
assert "Invalid header" in str(exc.value)
@@ -424,7 +430,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as exc:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
assert "Invalid payload padding" in str(exc.value)
@@ -437,7 +443,7 @@ class TestJWS:
example_secret = "secret"
with pytest.raises(DecodeError) as exc:
- jws.decode(example_jws, example_secret)
+ jws.decode(example_jws, example_secret, algorithms=["HS256"])
assert "Invalid crypto padding" in str(exc.value)
@@ -445,13 +451,13 @@ class TestJWS:
jws_message = jws.encode(payload, key=None, algorithm=None)
with pytest.raises(DecodeError):
- jws.decode(jws_message)
+ jws.decode(jws_message, algorithms=["none"])
def test_decode_with_algo_none_and_verify_false_should_pass(
self, jws, payload
):
jws_message = jws.encode(payload, key=None, algorithm=None)
- jws.decode(jws_message, verify=False)
+ jws.decode(jws_message, options={"verify_signature": False})
def test_get_unverified_header_returns_header_values(self, jws, payload):
jws_message = jws.encode(
@@ -499,7 +505,7 @@ class TestJWS:
force_bytes(rsa_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS256"])
# string-formatted key
with open("tests/keys/testkey_rsa", "r") as rsa_priv_file:
@@ -508,7 +514,7 @@ class TestJWS:
with open("tests/keys/testkey_rsa.pub", "r") as rsa_pub_file:
pub_rsakey = rsa_pub_file.read()
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS256"])
@pytest.mark.skipif(
not has_crypto, reason="Not supported without cryptography library"
@@ -527,7 +533,7 @@ class TestJWS:
pub_rsakey = load_ssh_public_key(
force_bytes(rsa_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS384"])
# string-formatted key
with open("tests/keys/testkey_rsa", "r") as rsa_priv_file:
@@ -536,7 +542,7 @@ class TestJWS:
with open("tests/keys/testkey_rsa.pub", "r") as rsa_pub_file:
pub_rsakey = rsa_pub_file.read()
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS384"])
@pytest.mark.skipif(
not has_crypto, reason="Not supported without cryptography library"
@@ -555,7 +561,7 @@ class TestJWS:
pub_rsakey = load_ssh_public_key(
force_bytes(rsa_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS512"])
# string-formatted key
with open("tests/keys/testkey_rsa", "r") as rsa_priv_file:
@@ -564,7 +570,7 @@ class TestJWS:
with open("tests/keys/testkey_rsa.pub", "r") as rsa_pub_file:
pub_rsakey = rsa_pub_file.read()
- jws.decode(jws_message, pub_rsakey)
+ jws.decode(jws_message, pub_rsakey, algorithms=["RS512"])
def test_rsa_related_algorithms(self, jws):
jws = PyJWS()
@@ -603,7 +609,7 @@ class TestJWS:
pub_eckey = load_pem_public_key(
force_bytes(ec_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES256"])
# string-formatted key
with open("tests/keys/testkey_ec", "r") as ec_priv_file:
@@ -612,7 +618,7 @@ class TestJWS:
with open("tests/keys/testkey_ec.pub", "r") as ec_pub_file:
pub_eckey = ec_pub_file.read()
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES256"])
@pytest.mark.skipif(
not has_crypto, reason="Can't run without cryptography library"
@@ -632,7 +638,7 @@ class TestJWS:
pub_eckey = load_pem_public_key(
force_bytes(ec_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES384"])
# string-formatted key
with open("tests/keys/testkey_ec", "r") as ec_priv_file:
@@ -641,7 +647,7 @@ class TestJWS:
with open("tests/keys/testkey_ec.pub", "r") as ec_pub_file:
pub_eckey = ec_pub_file.read()
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES384"])
@pytest.mark.skipif(
not has_crypto, reason="Can't run without cryptography library"
@@ -660,7 +666,7 @@ class TestJWS:
pub_eckey = load_pem_public_key(
force_bytes(ec_pub_file.read()), backend=default_backend()
)
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES512"])
# string-formatted key
with open("tests/keys/testkey_ec", "r") as ec_priv_file:
@@ -669,7 +675,7 @@ class TestJWS:
with open("tests/keys/testkey_ec.pub", "r") as ec_pub_file:
pub_eckey = ec_pub_file.read()
- jws.decode(jws_message, pub_eckey)
+ jws.decode(jws_message, pub_eckey, algorithms=["ES512"])
def test_ecdsa_related_algorithms(self, jws):
jws = PyJWS()
diff --git a/tests/test_api_jwt.py b/tests/test_api_jwt.py
index 4cc5ca7..1efc218 100644
--- a/tests/test_api_jwt.py
+++ b/tests/test_api_jwt.py
@@ -41,7 +41,9 @@ class TestJWT:
b".eyJoZWxsbyI6ICJ3b3JsZCJ9"
b".tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8"
)
- decoded_payload = jwt.decode(example_jwt, example_secret)
+ decoded_payload = jwt.decode(
+ example_jwt, example_secret, algorithms=["HS256"]
+ )
assert decoded_payload == example_payload
@@ -54,7 +56,9 @@ class TestJWT:
b".tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8"
)
- decoded_payload = jwt.decode(example_jwt, key=example_secret)
+ decoded_payload = jwt.decode(
+ example_jwt, key=example_secret, algorithms=["HS256"]
+ )
assert decoded_payload == example_payload
@@ -67,7 +71,7 @@ class TestJWT:
example_secret = "secret"
with pytest.raises(DecodeError) as exc:
- jwt.decode(example_jwt, example_secret)
+ jwt.decode(example_jwt, example_secret, algorithms=["HS256"])
assert "Invalid payload string" in str(exc.value)
@@ -80,7 +84,7 @@ class TestJWT:
)
with pytest.raises(DecodeError) as context:
- jwt.decode(example_jwt, secret)
+ jwt.decode(example_jwt, secret, algorithms=["HS256"])
exception = context.value
assert (
@@ -96,7 +100,7 @@ class TestJWT:
)
with pytest.raises(TypeError) as context:
- jwt.decode(example_jwt, secret, audience=1)
+ jwt.decode(example_jwt, secret, audience=1, algorithms=["HS256"])
exception = context.value
assert str(exception) == "audience must be a string, iterable, or None"
@@ -110,7 +114,12 @@ class TestJWT:
)
with pytest.raises(InvalidAudienceError) as context:
- jwt.decode(example_jwt, secret, audience="my_audience")
+ jwt.decode(
+ example_jwt,
+ secret,
+ audience="my_audience",
+ algorithms=["HS256"],
+ )
exception = context.value
assert str(exception) == "Invalid claim format in token"
@@ -124,7 +133,12 @@ class TestJWT:
)
with pytest.raises(InvalidAudienceError) as context:
- jwt.decode(example_jwt, secret, audience="my_audience")
+ jwt.decode(
+ example_jwt,
+ secret,
+ audience="my_audience",
+ algorithms=["HS256"],
+ )
exception = context.value
assert str(exception) == "Invalid claim format in token"
@@ -134,7 +148,10 @@ class TestJWT:
types = ["string", tuple(), list(), 42, set()]
for t in types:
- pytest.raises(TypeError, lambda: jwt.encode(t, "secret"))
+ pytest.raises(
+ TypeError,
+ lambda: jwt.encode(t, "secret", algorithms=["HS256"]),
+ )
def test_decode_raises_exception_if_exp_is_not_int(self, jwt):
# >>> jwt.encode({'exp': 'not-an-int'}, 'secret')
@@ -145,7 +162,7 @@ class TestJWT:
)
with pytest.raises(DecodeError) as exc:
- jwt.decode(example_jwt, "secret")
+ jwt.decode(example_jwt, "secret", algorithms=["HS256"])
assert "exp" in str(exc.value)
@@ -158,7 +175,7 @@ class TestJWT:
)
with pytest.raises(InvalidIssuedAtError):
- jwt.decode(example_jwt, "secret")
+ jwt.decode(example_jwt, "secret", algorithms=["HS256"])
def test_decode_raises_exception_if_nbf_is_not_int(self, jwt):
# >>> jwt.encode({'nbf': 'not-an-int'}, 'secret')
@@ -169,7 +186,7 @@ class TestJWT:
)
with pytest.raises(DecodeError):
- jwt.decode(example_jwt, "secret")
+ jwt.decode(example_jwt, "secret", algorithms=["HS256"])
def test_encode_datetime(self, jwt):
secret = "secret"
@@ -180,7 +197,9 @@ class TestJWT:
"nbf": current_datetime,
}
jwt_message = jwt.encode(payload, secret)
- decoded_payload = jwt.decode(jwt_message, secret, leeway=1)
+ decoded_payload = jwt.decode(
+ jwt_message, secret, leeway=1, algorithms=["HS256"]
+ )
assert decoded_payload["exp"] == timegm(
current_datetime.utctimetuple()
@@ -209,7 +228,9 @@ class TestJWT:
b"d2SsX8hhlnWelQFmPFSf_JzC2EbLnar92t-bXsDovzxp25ExazrVHkfPkQ"
)
- decoded_payload = jwt.decode(example_jwt, example_pubkey)
+ decoded_payload = jwt.decode(
+ example_jwt, example_pubkey, algorithms=["ES256"]
+ )
assert decoded_payload == example_payload
# 'Control' RSA JWT created by another library.
@@ -235,7 +256,9 @@ class TestJWT:
b"uwmrtSWCBUjiN8sqJ00CDgycxKqHfUndZbEAOjcCAhBr"
b"qWW3mSVivUfubsYbwUdUG3fSRPjaUPcpe8A"
)
- decoded_payload = jwt.decode(example_jwt, example_pubkey)
+ decoded_payload = jwt.decode(
+ example_jwt, example_pubkey, algorithms=["RS384"]
+ )
assert decoded_payload == example_payload
@@ -245,7 +268,7 @@ class TestJWT:
jwt_message = jwt.encode(payload, secret)
with pytest.raises(ExpiredSignatureError):
- jwt.decode(jwt_message, secret)
+ jwt.decode(jwt_message, secret, algorithms=["HS256"])
def test_decode_with_notbefore(self, jwt, payload):
payload["nbf"] = utc_timestamp() + 10
@@ -253,21 +276,31 @@ class TestJWT:
jwt_message = jwt.encode(payload, secret)
with pytest.raises(ImmatureSignatureError):
- jwt.decode(jwt_message, secret)
+ jwt.decode(jwt_message, secret, algorithms=["HS256"])
def test_decode_skip_expiration_verification(self, jwt, payload):
payload["exp"] = time.time() - 1
secret = "secret"
jwt_message = jwt.encode(payload, secret)
- jwt.decode(jwt_message, secret, options={"verify_exp": False})
+ jwt.decode(
+ jwt_message,
+ secret,
+ algorithms=["HS256"],
+ options={"verify_exp": False},
+ )
def test_decode_skip_notbefore_verification(self, jwt, payload):
payload["nbf"] = time.time() + 10
secret = "secret"
jwt_message = jwt.encode(payload, secret)
- jwt.decode(jwt_message, secret, options={"verify_nbf": False})
+ jwt.decode(
+ jwt_message,
+ secret,
+ algorithms=["HS256"],
+ options={"verify_nbf": False},
+ )
def test_decode_with_expiration_with_leeway(self, jwt, payload):
payload["exp"] = utc_timestamp() - 2
@@ -278,12 +311,16 @@ class TestJWT:
# With 3 seconds leeway, should be ok
for leeway in (3, timedelta(seconds=3)):
- jwt.decode(jwt_message, secret, leeway=leeway)
+ jwt.decode(
+ jwt_message, secret, leeway=leeway, algorithms=["HS256"]
+ )
# With 1 seconds, should fail
for leeway in (1, timedelta(seconds=1)):
with pytest.raises(ExpiredSignatureError):
- jwt.decode(jwt_message, secret, leeway=leeway)
+ jwt.decode(
+ jwt_message, secret, leeway=leeway, algorithms=["HS256"]
+ )
def test_decode_with_notbefore_with_leeway(self, jwt, payload):
payload["nbf"] = utc_timestamp() + 10
@@ -291,37 +328,47 @@ class TestJWT:
jwt_message = jwt.encode(payload, secret)
# With 13 seconds leeway, should be ok
- jwt.decode(jwt_message, secret, leeway=13)
+ jwt.decode(jwt_message, secret, leeway=13, algorithms=["HS256"])
with pytest.raises(ImmatureSignatureError):
- jwt.decode(jwt_message, secret, leeway=1)
+ jwt.decode(jwt_message, secret, leeway=1, algorithms=["HS256"])
def test_check_audience_when_valid(self, jwt):
payload = {"some": "payload", "aud": "urn:me"}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", audience="urn:me")
+ jwt.decode(token, "secret", audience="urn:me", algorithms=["HS256"])
def test_check_audience_list_when_valid(self, jwt):
payload = {"some": "payload", "aud": "urn:me"}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", audience=["urn:you", "urn:me"])
+ jwt.decode(
+ token,
+ "secret",
+ audience=["urn:you", "urn:me"],
+ algorithms=["HS256"],
+ )
def test_check_audience_none_specified(self, jwt):
payload = {"some": "payload", "aud": "urn:me"}
token = jwt.encode(payload, "secret")
with pytest.raises(InvalidAudienceError):
- jwt.decode(token, "secret")
+ jwt.decode(token, "secret", algorithms=["HS256"])
def test_raise_exception_invalid_audience_list(self, jwt):
payload = {"some": "payload", "aud": "urn:me"}
token = jwt.encode(payload, "secret")
with pytest.raises(InvalidAudienceError):
- jwt.decode(token, "secret", audience=["urn:you", "urn:him"])
+ jwt.decode(
+ token,
+ "secret",
+ audience=["urn:you", "urn:him"],
+ algorithms=["HS256"],
+ )
def test_check_audience_in_array_when_valid(self, jwt):
payload = {"some": "payload", "aud": ["urn:me", "urn:someone-else"]}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", audience="urn:me")
+ jwt.decode(token, "secret", audience="urn:me", algorithms=["HS256"])
def test_raise_exception_invalid_audience(self, jwt):
payload = {"some": "payload", "aud": "urn:someone-else"}
@@ -329,7 +376,9 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(InvalidAudienceError):
- jwt.decode(token, "secret", audience="urn-me")
+ jwt.decode(
+ token, "secret", audience="urn-me", algorithms=["HS256"]
+ )
def test_raise_exception_invalid_audience_in_array(self, jwt):
payload = {
@@ -340,7 +389,9 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(InvalidAudienceError):
- jwt.decode(token, "secret", audience="urn:me")
+ jwt.decode(
+ token, "secret", audience="urn:me", algorithms=["HS256"]
+ )
def test_raise_exception_token_without_issuer(self, jwt):
issuer = "urn:wrong"
@@ -350,7 +401,7 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(MissingRequiredClaimError) as exc:
- jwt.decode(token, "secret", issuer=issuer)
+ jwt.decode(token, "secret", issuer=issuer, algorithms=["HS256"])
assert exc.value.claim == "iss"
@@ -359,7 +410,9 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(MissingRequiredClaimError) as exc:
- jwt.decode(token, "secret", audience="urn:me")
+ jwt.decode(
+ token, "secret", audience="urn:me", algorithms=["HS256"]
+ )
assert exc.value.claim == "aud"
@@ -367,7 +420,7 @@ class TestJWT:
issuer = "urn:foo"
payload = {"some": "payload", "iss": "urn:foo"}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", issuer=issuer)
+ jwt.decode(token, "secret", issuer=issuer, algorithms=["HS256"])
def test_raise_exception_invalid_issuer(self, jwt):
issuer = "urn:wrong"
@@ -377,12 +430,17 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(InvalidIssuerError):
- jwt.decode(token, "secret", issuer=issuer)
+ jwt.decode(token, "secret", issuer=issuer, algorithms=["HS256"])
def test_skip_check_audience(self, jwt):
payload = {"some": "payload", "aud": "urn:me"}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", options={"verify_aud": False})
+ jwt.decode(
+ token,
+ "secret",
+ options={"verify_aud": False},
+ algorithms=["HS256"],
+ )
def test_skip_check_exp(self, jwt):
payload = {
@@ -390,7 +448,12 @@ class TestJWT:
"exp": datetime.utcnow() - timedelta(days=1),
}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", options={"verify_exp": False})
+ jwt.decode(
+ token,
+ "secret",
+ options={"verify_exp": False},
+ algorithms=["HS256"],
+ )
def test_decode_should_raise_error_if_exp_required_but_not_present(
self, jwt
@@ -402,7 +465,12 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(MissingRequiredClaimError) as exc:
- jwt.decode(token, "secret", options={"require_exp": True})
+ jwt.decode(
+ token,
+ "secret",
+ options={"require_exp": True},
+ algorithms=["HS256"],
+ )
assert exc.value.claim == "exp"
@@ -416,7 +484,12 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(MissingRequiredClaimError) as exc:
- jwt.decode(token, "secret", options={"require_iat": True})
+ jwt.decode(
+ token,
+ "secret",
+ options={"require_iat": True},
+ algorithms=["HS256"],
+ )
assert exc.value.claim == "iat"
@@ -430,7 +503,12 @@ class TestJWT:
token = jwt.encode(payload, "secret")
with pytest.raises(MissingRequiredClaimError) as exc:
- jwt.decode(token, "secret", options={"require_nbf": True})
+ jwt.decode(
+ token,
+ "secret",
+ options={"require_nbf": True},
+ algorithms=["HS256"],
+ )
assert exc.value.claim == "nbf"
@@ -440,7 +518,12 @@ class TestJWT:
".eyJzb21lIjoicGF5bG9hZCJ9"
".4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZA"
)
- jwt.decode(token, "secret", options={"verify_signature": False})
+ jwt.decode(
+ token,
+ "secret",
+ options={"verify_signature": False},
+ algorithms=["HS256"],
+ )
def test_skip_check_iat(self, jwt):
payload = {
@@ -448,7 +531,12 @@ class TestJWT:
"iat": datetime.utcnow() + timedelta(days=1),
}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", options={"verify_iat": False})
+ jwt.decode(
+ token,
+ "secret",
+ options={"verify_iat": False},
+ algorithms=["HS256"],
+ )
def test_skip_check_nbf(self, jwt):
payload = {
@@ -456,7 +544,12 @@ class TestJWT:
"nbf": datetime.utcnow() + timedelta(days=1),
}
token = jwt.encode(payload, "secret")
- jwt.decode(token, "secret", options={"verify_nbf": False})
+ jwt.decode(
+ token,
+ "secret",
+ options={"verify_nbf": False},
+ algorithms=["HS256"],
+ )
def test_custom_json_encoder(self, jwt):
class CustomJSONEncoder(json.JSONEncoder):
@@ -468,42 +561,47 @@ class TestJWT:
data = {"some_decimal": Decimal("2.2")}
with pytest.raises(TypeError):
- jwt.encode(data, "secret")
+ jwt.encode(data, "secret", algorithms=["HS256"])
token = jwt.encode(data, "secret", json_encoder=CustomJSONEncoder)
- payload = jwt.decode(token, "secret")
+ payload = jwt.decode(token, "secret", algorithms=["HS256"])
assert payload == {"some_decimal": "it worked"}
- def test_decode_with_verify_expiration_kwarg(self, jwt, payload):
+ def test_decode_with_verify_exp_option(self, jwt, payload):
payload["exp"] = utc_timestamp() - 1
secret = "secret"
jwt_message = jwt.encode(payload, secret)
- pytest.deprecated_call(
- jwt.decode, jwt_message, secret, verify_expiration=False
+ jwt.decode(
+ jwt_message,
+ secret,
+ algorithms=["HS256"],
+ options={"verify_exp": False},
)
with pytest.raises(ExpiredSignatureError):
- pytest.deprecated_call(
- jwt.decode, jwt_message, secret, verify_expiration=True
+ jwt.decode(
+ jwt_message,
+ secret,
+ algorithms=["HS256"],
+ options={"verify_exp": True},
)
def test_decode_with_optional_algorithms(self, jwt, payload):
secret = "secret"
jwt_message = jwt.encode(payload, secret)
- pytest.deprecated_call(jwt.decode, jwt_message, secret)
+ with pytest.raises(DecodeError) as exc:
+ jwt.decode(jwt_message, secret)
+
+ assert (
+ 'It is required that you pass in a value for the "algorithms" argument when calling decode().'
+ in str(exc.value)
+ )
- def test_decode_no_algorithms_verify_false(self, jwt, payload):
+ def test_decode_no_algorithms_verify_signature_false(self, jwt, payload):
secret = "secret"
jwt_message = jwt.encode(payload, secret)
- try:
- pytest.deprecated_call(
- jwt.decode, jwt_message, secret, verify=False
- )
- except pytest.fail.Exception:
- pass
- else:
- assert False, "Unexpected DeprecationWarning raised."
+ jwt.decode(jwt_message, secret, options={"verify_signature": False})
diff --git a/tests/test_jwt.py b/tests/test_jwt.py
index db96f46..126fc9b 100644
--- a/tests/test_jwt.py
+++ b/tests/test_jwt.py
@@ -13,7 +13,7 @@ def test_encode_decode():
payload = {"iss": "jeff", "exp": utc_timestamp() + 15, "claim": "insanity"}
secret = "secret"
- jwt_message = jwt.encode(payload, secret)
- decoded_payload = jwt.decode(jwt_message, secret)
+ jwt_message = jwt.encode(payload, secret, algorithm="HS256")
+ decoded_payload = jwt.decode(jwt_message, secret, algorithms=["HS256"])
assert decoded_payload == payload