diff options
Diffstat (limited to 'python/itsdangerous/timed.py')
-rw-r--r-- | python/itsdangerous/timed.py | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/python/itsdangerous/timed.py b/python/itsdangerous/timed.py deleted file mode 100644 index 4c117e4..0000000 --- a/python/itsdangerous/timed.py +++ /dev/null @@ -1,147 +0,0 @@ -import time -from datetime import datetime - -from ._compat import text_type -from .encoding import base64_decode -from .encoding import base64_encode -from .encoding import bytes_to_int -from .encoding import int_to_bytes -from .encoding import want_bytes -from .exc import BadSignature -from .exc import BadTimeSignature -from .exc import SignatureExpired -from .serializer import Serializer -from .signer import Signer - - -class TimestampSigner(Signer): - """Works like the regular :class:`.Signer` but also records the time - of the signing and can be used to expire signatures. The - :meth:`unsign` method can raise :exc:`.SignatureExpired` if the - unsigning failed because the signature is expired. - """ - - def get_timestamp(self): - """Returns the current timestamp. The function must return an - integer. - """ - return int(time.time()) - - def timestamp_to_datetime(self, ts): - """Used to convert the timestamp from :meth:`get_timestamp` into - a datetime object. - """ - return datetime.utcfromtimestamp(ts) - - def sign(self, value): - """Signs the given string and also attaches time information.""" - value = want_bytes(value) - timestamp = base64_encode(int_to_bytes(self.get_timestamp())) - sep = want_bytes(self.sep) - value = value + sep + timestamp - return value + sep + self.get_signature(value) - - def unsign(self, value, max_age=None, return_timestamp=False): - """Works like the regular :meth:`.Signer.unsign` but can also - validate the time. See the base docstring of the class for - the general behavior. If ``return_timestamp`` is ``True`` the - timestamp of the signature will be returned as a naive - :class:`datetime.datetime` object in UTC. - """ - try: - result = Signer.unsign(self, value) - sig_error = None - except BadSignature as e: - sig_error = e - result = e.payload or b"" - sep = want_bytes(self.sep) - - # If there is no timestamp in the result there is something - # seriously wrong. In case there was a signature error, we raise - # that one directly, otherwise we have a weird situation in - # which we shouldn't have come except someone uses a time-based - # serializer on non-timestamp data, so catch that. - if sep not in result: - if sig_error: - raise sig_error - raise BadTimeSignature("timestamp missing", payload=result) - - value, timestamp = result.rsplit(sep, 1) - try: - timestamp = bytes_to_int(base64_decode(timestamp)) - except Exception: - timestamp = None - - # Signature is *not* okay. Raise a proper error now that we have - # split the value and the timestamp. - if sig_error is not None: - raise BadTimeSignature( - text_type(sig_error), payload=value, date_signed=timestamp - ) - - # Signature was okay but the timestamp is actually not there or - # malformed. Should not happen, but we handle it anyway. - if timestamp is None: - raise BadTimeSignature("Malformed timestamp", payload=value) - - # Check timestamp is not older than max_age - if max_age is not None: - age = self.get_timestamp() - timestamp - if age > max_age: - raise SignatureExpired( - "Signature age %s > %s seconds" % (age, max_age), - payload=value, - date_signed=self.timestamp_to_datetime(timestamp), - ) - - if return_timestamp: - return value, self.timestamp_to_datetime(timestamp) - return value - - def validate(self, signed_value, max_age=None): - """Only validates the given signed value. Returns ``True`` if - the signature exists and is valid.""" - try: - self.unsign(signed_value, max_age=max_age) - return True - except BadSignature: - return False - - -class TimedSerializer(Serializer): - """Uses :class:`TimestampSigner` instead of the default - :class:`.Signer`. - """ - - default_signer = TimestampSigner - - def loads(self, s, max_age=None, return_timestamp=False, salt=None): - """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the - signature validation fails. If a ``max_age`` is provided it will - ensure the signature is not older than that time in seconds. In - case the signature is outdated, :exc:`.SignatureExpired` is - raised. All arguments are forwarded to the signer's - :meth:`~TimestampSigner.unsign` method. - """ - s = want_bytes(s) - last_exception = None - for signer in self.iter_unsigners(salt): - try: - base64d, timestamp = signer.unsign(s, max_age, return_timestamp=True) - payload = self.load_payload(base64d) - if return_timestamp: - return payload, timestamp - return payload - # If we get a signature expired it means we could read the - # signature but it's invalid. In that case we do not want to - # try the next signer. - except SignatureExpired: - raise - except BadSignature as err: - last_exception = err - raise last_exception - - def loads_unsafe(self, s, max_age=None, salt=None): - load_kwargs = {"max_age": max_age} - load_payload_kwargs = {} - return self._loads_unsafe_impl(s, salt, load_kwargs, load_payload_kwargs) |