mirror of
https://github.com/bvanroll/cicdTest.git
synced 2025-08-29 20:12:43 +00:00
build test
This commit is contained in:
233
venv/lib/python3.7/site-packages/itsdangerous/serializer.py
Normal file
233
venv/lib/python3.7/site-packages/itsdangerous/serializer.py
Normal file
@@ -0,0 +1,233 @@
|
||||
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)
|
Reference in New Issue
Block a user