
_!                 @   s   d  d l  Z  d d l m Z d d l m Z d d l m Z d d l m Z d d l m	 Z	 d d l
 m Z d	 d
   Z Gd d   d e  Z d S)    N   )	text_type)json)
want_bytes)
BadPayload)BadSignature)Signerc             C   s   t  |  j i   t  S)z5Checks whether a serializer generates text or binary.)
isinstancedumpsr   )
serializer r   ?/tmp/pip-build-5gj8f0j9/itsdangerous/itsdangerous/serializer.pyis_text_serializer   s    r   c               @   s   e  Z d  Z d Z e Z e Z d e j	 i g Z
 d d d d d d d d  Z d d d  Z d	 d
   Z d d d  Z d d d  Z d d d  Z d d d  Z d d d  Z d d d  Z d d d  Z d d d d  Z d d   Z d S)
Serializera  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.
    Zdigest_methods   itsdangerousNc             C   s   t  |  |  _ t  |  |  _ | d  k r3 |  j } | |  _ t |  |  _ | d  k r` |  j } | |  _ | pr i  |  _ | d  k r t	 |  j
 p f   } | |  _ | p i  |  _ d  S)N)r   
secret_keysaltdefault_serializerr   r   default_signersignersigner_kwargslistdefault_fallback_signersfallback_signersserializer_kwargs)selfr   r   r   r   r   r   r   r   r   r   __init__P   s    
					zSerializer.__init__c             C   s   | d k r! |  j  } |  j } n t |  } y& | rE | j d  } | j |  SWn7 t k
 r } z t d d |  WYd d } ~ Xn Xd S)a  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.
        Nzutf-8zSCould not load the payload because an exception occurred on unserializing the data.original_error)r   r   decodeloads	Exceptionr   )r   payloadr   Zis_texter   r   r   load_payloadi   s    	zSerializer.load_payloadc             C   s   t  |  j j | |  j   S)zDumps the encoded object. The return value is always bytes.
        If the internal serializer returns text, the value will be
        encoded as UTF-8.
        )r   r   r
   r   )r   objr   r   r   dump_payload   s    zSerializer.dump_payloadc             C   s1   | d k r |  j  } |  j |  j d | |  j S)zCreates a new instance of the signer to be used. The default
        implementation uses the :class:`.Signer` base class.
        Nr   )r   r   r   r   )r   r   r   r   r   make_signer   s    	zSerializer.make_signerc             c   s   | d k r |  j  } |  j |  Vxv |  j D]k } t |  t k rW | } |  j } n* t |  t k rx | \ } } n	 |  j } | |  j d | | Vq- Wd S)zIterates over all signers to be tried for unsigning. Starts
        with the configured signer, then constructs each signer
        specified in ``fallback_signers``.
        Nr   )	r   r%   r   typedictr   tupler   r   )r   r   fallbackkwargsr   r   r   iter_unsigners   s    		zSerializer.iter_unsignersc             C   sI   t  |  j |   } |  j |  j |  } |  j rE | j d  } | S)zReturns 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.
        zutf-8)r   r$   r%   signr   r   )r   r#   r   r    rvr   r   r   r
      s
    	zSerializer.dumpsc             C   s   | j  |  j | |   d S)zLike :meth:`dumps` but dumps into a file. The file handle has
        to be compatible with what the internal serializer expects.
        N)writer
   )r   r#   fr   r   r   r   dump   s    zSerializer.dumpc             C   s~   t  |  } d } x_ |  j |  D]N } y |  j | j |   SWq" t k
 ro } z | } WYd d } ~ Xq" Xq" W|  d S)ziReverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the
        signature validation fails.
        N)r   r+   r"   Zunsignr   )r   sr   Zlast_exceptionr   errr   r   r   r      s    zSerializer.loadsc             C   s   |  j  | j   |  S)z)Like :meth:`loads` but loads from a file.)r   read)r   r/   r   r   r   r   load   s    zSerializer.loadc             C   s   |  j  | |  S)a9  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
        )_loads_unsafe_impl)r   r1   r   r   r   r   loads_unsafe   s    zSerializer.loads_unsafec             C   s   y& d |  j  | d | | p i  f SWnt t k
 r } zT | j d k rN d Sy# d |  j | j | pi i   f SWn t k
 r d SYn XWYd d } ~ Xn Xd S)zfLow level helper function to implement :meth:`loads_unsafe`
        in serializer subclasses.
        Tr   NF)FN)FN)r   r   r    r"   r   )r   r1   r   Zload_kwargsZload_payload_kwargsr!   r   r   r   r5      s    & zSerializer._loads_unsafe_implc             O   s   |  j  | j   | |  S)zYLike :meth:`loads_unsafe` but loads from a file.

        .. versionadded:: 0.15
        )r6   r3   )r   r/   argsr*   r   r   r   load_unsafe   s    zSerializer.load_unsafe)__name__
__module____qualname____doc__r   r   r   r   hashlibsha512r   r   r"   r$   r%   r+   r
   r0   r   r4   r6   r5   r8   r   r   r   r   r      s*   1r   )r=   _compatr   _jsonr   encodingr   excr   r   r   r   r   objectr   r   r   r   r   <module>   s   