diff options
Diffstat (limited to 'python/itsdangerous/serializer.py')
-rw-r--r-- | python/itsdangerous/serializer.py | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/python/itsdangerous/serializer.py b/python/itsdangerous/serializer.py deleted file mode 100644 index 12c20f4..0000000 --- a/python/itsdangerous/serializer.py +++ /dev/null @@ -1,233 +0,0 @@ -import hashlib - -from ._compat import text_type -from ._json import json -from .encoding import want_bytes -from .exc import BadPayload -from .exc import BadSignature -from .signer import Signer - - -def is_text_serializer(serializer): - """Checks whether a serializer generates text or binary.""" - return isinstance(serializer.dumps({}), text_type) - - -class Serializer(object): - """This class provides a serialization interface on top of the - signer. It provides a similar API to json/pickle and other modules - but is structured differently internally. If you want to change the - underlying implementation for parsing and loading you have to - override the :meth:`load_payload` and :meth:`dump_payload` - functions. - - This implementation uses simplejson if available for dumping and - loading and will fall back to the standard library's json module if - it's not available. - - You do not need to subclass this class in order to switch out or - customize the :class:`.Signer`. You can instead pass a different - class to the constructor as well as keyword arguments as a dict that - should be forwarded. - - .. code-block:: python - - s = Serializer(signer_kwargs={'key_derivation': 'hmac'}) - - You may want to upgrade the signing parameters without invalidating - existing signatures that are in use. Fallback signatures can be - given that will be tried if unsigning with the current signer fails. - - Fallback signers can be defined by providing a list of - ``fallback_signers``. Each item can be one of the following: a - signer class (which is instantiated with ``signer_kwargs``, - ``salt``, and ``secret_key``), a tuple - ``(signer_class, signer_kwargs)``, or a dict of ``signer_kwargs``. - - For example, this is a serializer that signs using SHA-512, but will - unsign using either SHA-512 or SHA1: - - .. code-block:: python - - s = Serializer( - signer_kwargs={"digest_method": hashlib.sha512}, - fallback_signers=[{"digest_method": hashlib.sha1}] - ) - - .. versionchanged:: 0.14: - The ``signer`` and ``signer_kwargs`` parameters were added to - the constructor. - - .. versionchanged:: 1.1.0: - Added support for ``fallback_signers`` and configured a default - SHA-512 fallback. This fallback is for users who used the yanked - 1.0.0 release which defaulted to SHA-512. - """ - - #: If a serializer module or class is not passed to the constructor - #: this one is picked up. This currently defaults to :mod:`json`. - default_serializer = json - - #: The default :class:`Signer` class that is being used by this - #: serializer. - #: - #: .. versionadded:: 0.14 - default_signer = Signer - - #: The default fallback signers. - default_fallback_signers = [{"digest_method": hashlib.sha512}] - - def __init__( - self, - secret_key, - salt=b"itsdangerous", - serializer=None, - serializer_kwargs=None, - signer=None, - signer_kwargs=None, - fallback_signers=None, - ): - self.secret_key = want_bytes(secret_key) - self.salt = want_bytes(salt) - if serializer is None: - serializer = self.default_serializer - self.serializer = serializer - self.is_text_serializer = is_text_serializer(serializer) - if signer is None: - signer = self.default_signer - self.signer = signer - self.signer_kwargs = signer_kwargs or {} - if fallback_signers is None: - fallback_signers = list(self.default_fallback_signers or ()) - self.fallback_signers = fallback_signers - self.serializer_kwargs = serializer_kwargs or {} - - def load_payload(self, payload, serializer=None): - """Loads the encoded object. This function raises - :class:`.BadPayload` if the payload is not valid. The - ``serializer`` parameter can be used to override the serializer - stored on the class. The encoded ``payload`` should always be - bytes. - """ - if serializer is None: - serializer = self.serializer - is_text = self.is_text_serializer - else: - is_text = is_text_serializer(serializer) - try: - if is_text: - payload = payload.decode("utf-8") - return serializer.loads(payload) - except Exception as e: - raise BadPayload( - "Could not load the payload because an exception" - " occurred on unserializing the data.", - original_error=e, - ) - - def dump_payload(self, obj): - """Dumps the encoded object. The return value is always bytes. - If the internal serializer returns text, the value will be - encoded as UTF-8. - """ - return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) - - def make_signer(self, salt=None): - """Creates a new instance of the signer to be used. The default - implementation uses the :class:`.Signer` base class. - """ - if salt is None: - salt = self.salt - return self.signer(self.secret_key, salt=salt, **self.signer_kwargs) - - def iter_unsigners(self, salt=None): - """Iterates over all signers to be tried for unsigning. Starts - with the configured signer, then constructs each signer - specified in ``fallback_signers``. - """ - if salt is None: - salt = self.salt - yield self.make_signer(salt) - for fallback in self.fallback_signers: - if type(fallback) is dict: - kwargs = fallback - fallback = self.signer - elif type(fallback) is tuple: - fallback, kwargs = fallback - else: - kwargs = self.signer_kwargs - yield fallback(self.secret_key, salt=salt, **kwargs) - - def dumps(self, obj, salt=None): - """Returns a signed string serialized with the internal - serializer. The return value can be either a byte or unicode - string depending on the format of the internal serializer. - """ - payload = want_bytes(self.dump_payload(obj)) - rv = self.make_signer(salt).sign(payload) - if self.is_text_serializer: - rv = rv.decode("utf-8") - return rv - - def dump(self, obj, f, salt=None): - """Like :meth:`dumps` but dumps into a file. The file handle has - to be compatible with what the internal serializer expects. - """ - f.write(self.dumps(obj, salt)) - - def loads(self, s, salt=None): - """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the - signature validation fails. - """ - s = want_bytes(s) - last_exception = None - for signer in self.iter_unsigners(salt): - try: - return self.load_payload(signer.unsign(s)) - except BadSignature as err: - last_exception = err - raise last_exception - - def load(self, f, salt=None): - """Like :meth:`loads` but loads from a file.""" - return self.loads(f.read(), salt) - - def loads_unsafe(self, s, salt=None): - """Like :meth:`loads` but without verifying the signature. This - is potentially very dangerous to use depending on how your - serializer works. The return value is ``(signature_valid, - payload)`` instead of just the payload. The first item will be a - boolean that indicates if the signature is valid. This function - never fails. - - Use it for debugging only and if you know that your serializer - module is not exploitable (for example, do not use it with a - pickle serializer). - - .. versionadded:: 0.15 - """ - return self._loads_unsafe_impl(s, salt) - - def _loads_unsafe_impl(self, s, salt, load_kwargs=None, load_payload_kwargs=None): - """Low level helper function to implement :meth:`loads_unsafe` - in serializer subclasses. - """ - try: - return True, self.loads(s, salt=salt, **(load_kwargs or {})) - except BadSignature as e: - if e.payload is None: - return False, None - try: - return ( - False, - self.load_payload(e.payload, **(load_payload_kwargs or {})), - ) - except BadPayload: - return False, None - - def load_unsafe(self, f, *args, **kwargs): - """Like :meth:`loads_unsafe` but loads from a file. - - .. versionadded:: 0.15 - """ - return self.loads_unsafe(f.read(), *args, **kwargs) |