3
¥Yðiª  ã               @   sü   d dl Z d dlZ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 ejeef Zeje Zeje ZejrØd dlZG dd„ deƒZG dd„ deƒZdS )é    N)Údatetime)Útimezoneé   )Úbase64_decode)Úbase64_encode)Úbytes_to_int)Úint_to_bytes)Ú
want_bytes)ÚBadSignature)ÚBadTimeSignature)ÚSignatureExpired)Ú
Serializer)ÚSignerc                   sÆ   e Zd ZdZedœdd„Zeedœdd„Zee	dœd	d
„Z
ejdeede	dœdd„ƒZejdeedeje	ef dœdd„ƒZdeeeejeje	ef e	f dœ‡ fdd„Zdeeedœdd„Z‡  Z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.
    )Úreturnc             C   s   t tjƒ ƒS )zTReturns the current timestamp. The function must return an
        integer.
        )ÚintÚtime)Úself© r   ú:/tmp/pip-build-8om4l6ph/itsdangerous/itsdangerous/timed.pyÚget_timestamp!   s    zTimestampSigner.get_timestamp)Útsr   c             C   s   t j|tjd�S )a   Convert the timestamp from :meth:`get_timestamp` into an
        aware :class`datetime.datetime` in UTC.

        .. versionchanged:: 2.0
            The timestamp is returned as a timezone-aware ``datetime``
            in UTC rather than a naive ``datetime`` assumed to be UTC.
        )Útz)r   Úfromtimestampr   Úutc)r   r   r   r   r   Útimestamp_to_datetime'   s    z%TimestampSigner.timestamp_to_datetime)Úvaluer   c             C   s@   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   r   Ú	timestampr   r   r   r   Úsign1   s
    
zTimestampSigner.signNFz_te.Literal[False])Úsigned_valueÚmax_ageÚreturn_timestampr   c             C   s   d S )Nr   )r   r    r!   r"   r   r   r   Úunsign<   s    zTimestampSigner.unsignTz_te.Literal[True]c             C   s   d S )Nr   )r   r    r!   r"   r   r   r   r#   E   s    c                sj  yt ƒ j|ƒ}d}W n0 tk
rD } z|}|jp2d}W Y dd}~X nX t| jƒ}||krl|r`|‚td|d�‚|j|dƒ\}}	d}
d}ytt	|	ƒƒ}
W n t
k
r¨   Y nX |dk	rÖ|
dk	rÄ| j|
ƒ}tt|ƒ||d�‚|
dkrêtd|d�‚|dk	�rR| jƒ |
 }||k�r,td|› d	|› d
�|| j|
ƒd�‚|dk �rRtd|› d�|| j|
ƒd�‚|�rf|| 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 an aware
        :class:`datetime.datetime` object in UTC.

        .. versionchanged:: 2.0
            The timestamp is returned as a timezone-aware ``datetime``
            in UTC rather than a naive ``datetime`` assumed to be UTC.
        Nó    ztimestamp missing)Úpayloadr   )r%   Zdate_signedzMalformed timestampzSignature age z > z secondsr   z < 0 seconds)Úsuperr#   r
   r%   r	   r   r   Úrsplitr   r   Ú	Exceptionr   Ústrr   r   )r   r    r!   r"   ÚresultZ	sig_errorÚer   r   Zts_bytesZts_intZts_dtZage)Ú	__class__r   r   r#   N   sN    





)r    r!   r   c             C   s,   y| j ||d� dS  tk
r&   dS X dS )zeOnly validates the given signed value. Returns ``True`` if
        the signature exists and is valid.)r!   TFN)r#   r
   )r   r    r!   r   r   r   ÚvalidateŸ   s
    zTimestampSigner.validate)NF)NT)NF)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   Ú_t_str_bytesÚbytesr   ÚtypingZoverloadÚ
_t_opt_intr#   Ú_tÚTupleÚboolÚUnionr-   Ú__classcell__r   r   )r,   r   r      s    
   &Lr   c                   s|   e Zd ZU dZeZeje deej	e dœ‡ fdd„Z
deeeeejdœdd	„Zdeeeejeejf d
œdd„Z‡  ZS )ÚTimedSerializerzOUses :class:`TimestampSigner` instead of the default
    :class:`.Signer`.
    N)Úsaltr   c                s   t jdtƒ j|ƒƒS )Nz_t.Iterator[TimestampSigner])r6   Úcastr&   Úiter_unsigners)r   r<   )r,   r   r   r>   °   s    zTimedSerializer.iter_unsignersF)Úsr!   r"   r<   r   c             C   sš   t |ƒ}d}x|| j|ƒD ]n}y.|j||dd�\}}| j|ƒ}	|rH|	|fS |	S  tk
r`   ‚ Y q tk
r„ }
 z
|
}W Y dd}
~
X qX qW tjt|ƒ‚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.
        NT)r!   r"   )r	   r>   r#   Zload_payloadr   r
   r6   r=   )r   r?   r!   r"   r<   Zlast_exceptionÚsignerZbase64dr   r%   Úerrr   r   r   Úloads¸   s    
zTimedSerializer.loads)r?   r!   r<   r   c             C   s   | j ||d|id�S )Nr!   )Zload_kwargs)Z_loads_unsafe_impl)r   r?   r!   r<   r   r   r   Úloads_unsafeÝ   s    zTimedSerializer.loads_unsafe)N)NFN)NN)r.   r/   r0   r1   r   Zdefault_signerr6   ÚTypeÚ_t_opt_str_bytesÚIteratorr>   r2   r5   r8   ZAnyrB   r7   rC   r:   r   r   )r,   r   r;   ©   s   
	  
" r;   ) r   r4   r6   r   r   Úencodingr   r   r   r   r	   Úexcr
   r   r   Ú
serializerr   r@   r   r9   r)   r3   r2   ÚOptionalrE   r   r5   ZTYPE_CHECKINGZtyping_extensionsZ_ter   r;   r   r   r   r   Ú<module>   s,   

 