
¿«‘_  ã               @   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	 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 Gd d „  d e ƒ Z Gd d „  d e ƒ Z d S)é    N)Údatetimeé   )Ú	text_type)Úbase64_decode)Úbase64_encode)Úbytes_to_int)Úint_to_bytes)Ú
want_bytes)ÚBadSignature)ÚBadTimeSignature)ÚSignatureExpired)Ú
Serializer)ÚSignerc               @   s[   e  Z d  Z d Z d d „  Z d d „  Z d d „  Z d d	 d
 d „ Z d d d „ Z d S)ÚTimestampSignerzþ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.
    c             C   s   t  t j ƒ  ƒ S)zTReturns the current timestamp. The function must return an
        integer.
        )ÚintÚtime)Úself© r   ú:/tmp/pip-build-5gj8f0j9/itsdangerous/itsdangerous/timed.pyÚget_timestamp   s    zTimestampSigner.get_timestampc             C   s   t  j | ƒ S)zaUsed to convert the timestamp from :meth:`get_timestamp` into
        a datetime object.
        )r   Úutcfromtimestamp)r   Útsr   r   r   Útimestamp_to_datetime   s    z%TimestampSigner.timestamp_to_datetimec             C   sV   t  | ƒ } t t |  j ƒ  ƒ ƒ } t  |  j ƒ } | | | } | | |  j | ƒ S)z:Signs the given string and also attaches time information.)r	   r   r   r   ÚsepZget_signature)r   ÚvalueÚ	timestampr   r   r   r   Úsign$   s
    zTimestampSigner.signNFc       
      C   s“  y t  j |  | ƒ } d } Wn: t k
 rX } z | } | j pC d } WYd d } ~ Xn Xt |  j ƒ } | | k r’ | r€ | ‚ t d d | ƒ‚ | j | d ƒ \ } } y t t	 | ƒ ƒ } Wn t
 k
 rÚ d } Yn X| d k	 rt t | ƒ d | d | ƒ‚ | d k r#t d d | ƒ‚ | d k	 rv|  j ƒ  | }	 |	 | k rvt d |	 | f d | d |  j | ƒ ƒ‚ | r�| |  j | ƒ f S| S)	a=  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.
        Nó    ztimestamp missingÚpayloadr   Zdate_signedzMalformed timestampzSignature age %s > %s seconds)r   Úunsignr
   r   r	   r   r   Úrsplitr   r   Ú	Exceptionr   r   r   r   )
r   r   Úmax_ageÚreturn_timestampÚresultZ	sig_errorÚer   r   Zager   r   r   r   ,   s>    
"zTimestampSigner.unsignc             C   s8   y |  j  | d | ƒd SWn t k
 r3 d SYn Xd S)zeOnly validates the given signed value. Returns ``True`` if
        the signature exists and is valid.r"   TFN)r   r
   )r   Zsigned_valuer"   r   r   r   Úvalidatee   s
    zTimestampSigner.validate)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r&   r   r   r   r   r      s   9r   c               @   sC   e  Z d  Z d Z e Z d d d d d „ Z d d d d „ Z d S)ÚTimedSerializerzOUses :class:`TimestampSigner` instead of the default
    :class:`.Signer`.
    NFc             C   s½   t  | ƒ } d } xž |  j | ƒ D]� } yE | j | | d d ƒ\ } } |  j | ƒ }	 | rh |	 | f S|	 SWq" t k
 r„ ‚  Yq" t k
 r® }
 z |
 } WYd d }
 ~
 Xq" Xq" W| ‚ d S)a†  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.
        Nr#   T)r	   Ziter_unsignersr   Zload_payloadr   r
   )r   Úsr"   r#   ÚsaltZlast_exceptionÚsignerZbase64dr   r   Úerrr   r   r   Úloadsv   s    
zTimedSerializer.loadsc             C   s(   d | i } i  } |  j  | | | | ƒ S)Nr"   )Z_loads_unsafe_impl)r   r,   r"   r-   Zload_kwargsZload_payload_kwargsr   r   r   Úloads_unsafe�   s    zTimedSerializer.loads_unsafe)r'   r(   r)   r*   r   Zdefault_signerr0   r1   r   r   r   r   r+   o   s   r+   )r   r   Ú_compatr   Úencodingr   r   r   r   r	   Úexcr
   r   r   Ú
serializerr   r.   r   r   r+   r   r   r   r   Ú<module>   s   ^