diff options
author | Pau Ruiz Safont <psafont@users.noreply.github.com> | 2020-05-14 15:50:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-14 20:50:39 +0600 |
commit | 008490a85932415ec14ab7d61c64216ddaef75fc (patch) | |
tree | 85e3da382b296678460c6e7bfdd871f43e677abc | |
parent | c2c91a7bb504f9ff10387972b8ce9353493ed773 (diff) | |
download | pyjwt-008490a85932415ec14ab7d61c64216ddaef75fc.tar.gz |
Require tweak (#280)
* Use require options as a list, instead of booleans
Deprecate the use of the boolean options
* Add test for the new require option
* Add documentation on how to use the require option
Co-authored-by: Pau Ruiz i Safont <psafont@ebi.ac.uk>
-rw-r--r-- | docs/usage.rst | 10 | ||||
-rw-r--r-- | jwt/api_jwt.py | 34 | ||||
-rw-r--r-- | tests/test_api_jwt.py | 15 |
3 files changed, 47 insertions, 12 deletions
diff --git a/docs/usage.rst b/docs/usage.rst index d2da71a..d012a95 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -242,3 +242,13 @@ Issued At Claim (iat) jwt.encode({'iat': 1371720939}, 'secret') jwt.encode({'iat': datetime.utcnow()}, 'secret') + +Requiring Presence of Claims +---------------------------- + +If you wish to require one or more claims to be present in the claimset, you can set the ``require`` paramenter to include these claims. + +.. code-block:: python + + >>jwt.decode(encoded, options={'require': ['exp', 'iss', 'sub']}) + {u'exp': 1371720939, u'iss': u'urn:foo', u'sub': u'25c37522-f148-4cbf-8ee6-c4a9718dd0af'} diff --git a/jwt/api_jwt.py b/jwt/api_jwt.py index 22bfc6a..125b57a 100644 --- a/jwt/api_jwt.py +++ b/jwt/api_jwt.py @@ -26,10 +26,11 @@ except ImportError: class PyJWT(PyJWS): header_type = "JWT" + deprecated_requires = ["require_exp", "require_iat", "require_nbf"] @staticmethod def _get_default_options(): - # type: () -> Dict[str, bool] + # type: () -> Dict[str, Union[bool, List[str]]] return { "verify_signature": True, "verify_exp": True, @@ -37,9 +38,7 @@ class PyJWT(PyJWS): "verify_iat": True, "verify_aud": True, "verify_iss": True, - "require_exp": False, - "require_iat": False, - "require_nbf": False, + "require": [], } def encode( @@ -128,6 +127,22 @@ class PyJWT(PyJWS): DeprecationWarning, ) + verify_claims = { + required + for required in self.deprecated_requires + if required in options + } + require_options = options.setdefault("require", []) + for opt in verify_claims: + opt_claim = opt.split("require_", 1)[1] + if options[opt]: + require_options.append(opt_claim) + warnings.warn( + "The {0} parameter is deprecated. Please add {1} to" + " the require list in options instead".format(opt, opt_claim), + DeprecationWarning, + ) + if isinstance(leeway, timedelta): leeway = leeway.total_seconds() @@ -154,14 +169,9 @@ class PyJWT(PyJWS): self._validate_aud(payload, audience) def _validate_required_claims(self, payload, options): - if options.get("require_exp") and payload.get("exp") is None: - raise MissingRequiredClaimError("exp") - - if options.get("require_iat") and payload.get("iat") is None: - raise MissingRequiredClaimError("iat") - - if options.get("require_nbf") and payload.get("nbf") is None: - raise MissingRequiredClaimError("nbf") + for claim in options.get("require", []): + if payload.get(claim) is None: + raise MissingRequiredClaimError(claim) def _validate_iat(self, payload, now, leeway): try: diff --git a/tests/test_api_jwt.py b/tests/test_api_jwt.py index e4065c6..c1759e3 100644 --- a/tests/test_api_jwt.py +++ b/tests/test_api_jwt.py @@ -437,6 +437,21 @@ class TestJWT: assert exc.value.claim == "nbf" + def test_decode_should_raise_error_if_claim_required_but_not_present( + self, jwt + ): + claim = "sub" + payload = { + "some": "payload", + # claim not present + } + token = jwt.encode(payload, "secret") + + with pytest.raises(MissingRequiredClaimError) as exc: + jwt.decode(token, "secret", options={"require": [claim]}) + + assert exc.value.claim == claim + def test_skip_check_signature(self, jwt): token = ( "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" |