o
    uvXj  ã                   @   s  d Z ddlZddlZddlZ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mZ ddlmZ ddlmZ e d¡ZG d	d
„ d
eƒZG dd„ deƒZdd„ Zdd„ Zdd„ Zd"dd„ZG dd„ dƒZddedfdd„Zddedfdd„ZG dd„ dƒZG d d!„ d!eƒZdS )#ae  
Functions for creating and restoring url-safe signed JSON objects.

The format used looks like this:

>>> signing.dumps("hello")
'ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk'

There are two components here, separated by a ':'. The first component is a
URLsafe base64 encoded JSON of the object passed to dumps(). The second
component is a base64 encoded hmac/SHA1 hash of "$first_component:$secret"

signing.loads(s) checks the signature and returns the deserialized object.
If the signature fails, a BadSignature exception is raised.

>>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk")
'hello'
>>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified")
...
BadSignature: Signature failed: ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified

You can optionally compress the JSON prior to base64 encoding it to save
space, using the compress=True argument. This checks if compression actually
helps and only applies compression if the result is a shorter string:

>>> signing.dumps(list(range(1, 20)), compress=True)
'.eJwFwcERACAIwLCF-rCiILN47r-GyZVJsNgkxaFxoDgxcOHGxMKD_T7vhAml:1QaUaL:BA0thEZrp4FQVXIXuOvYJtLJSrQ'

The fact that the string is compressed is signalled by the prefixed '.' at the
start of the base64 JSON.

There are 65 url-safe characters: the 64 used by url-safe base64 and the ':'.
These functions make use of all of them.
é    N)Úsettings)Úbaseconv)Úconstant_time_compareÚsalted_hmac)Úforce_bytes)Úimport_stringz^[A-z0-9-_=]*$c                   @   ó   e Zd ZdZdS )ÚBadSignaturezSignature does not match.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úP/var/www/html/myproject/venv/lib/python3.10/site-packages/django/core/signing.pyr	   4   ó    r	   c                   @   r   )ÚSignatureExpiredz3Signature timestamp is older than required max_age.Nr
   r   r   r   r   r   9   r   r   c                 C   s   t  | ¡ d¡S )Nó   =)Úbase64Úurlsafe_b64encodeÚstrip)Úsr   r   r   Ú
b64_encode>   ó   r   c                 C   s    dt | ƒ d  }t | | ¡S )Nr   é   )Úlenr   Úurlsafe_b64decode)r   Úpadr   r   r   Ú
b64_decodeB   s   r   c                 C   s   t t| ||ƒ ¡ ƒ ¡ S ©N)r   r   ÚdigestÚdecode)ÚsaltÚvalueÚkeyr   r   r   Úbase64_hmacG   s   r%   ú%django.core.signing.get_cookie_signerc                 C   s$   t tjƒ}ttjƒ}|d| | d�S )Ns   django.http.cookies©r"   )r   r   ÚSIGNING_BACKENDr   Ú
SECRET_KEY)r"   ÚSignerr$   r   r   r   Úget_cookie_signerK   s   

r+   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚJSONSerializerzW
    Simple wrapper around json to be used in signing.dumps and
    signing.loads.
    c                 C   s   t j|dd� d¡S )N)ú,ú:)Ú
separatorsúlatin-1)ÚjsonÚdumpsÚencode)ÚselfÚobjr   r   r   r2   V   ó   zJSONSerializer.dumpsc                 C   s   t  | d¡¡S )Nr0   )r1   Úloadsr!   )r4   Údatar   r   r   r7   Y   r   zJSONSerializer.loadsN)r   r   r   r   r2   r7   r   r   r   r   r,   Q   s    r,   zdjango.core.signingFc           	      C   sd   |ƒ   | ¡}d}|rt |¡}t|ƒt|ƒd k r|}d}t|ƒ ¡ }|r)d| }t||d� |¡S )aŠ  
    Return URL-safe, hmac/SHA1 signed base64 compressed JSON string. If key is
    None, use settings.SECRET_KEY instead.

    If compress is True (not the default), check if compressing using zlib can
    save some space. Prepend a '.' to signify compression. This is included
    in the signature, to protect against zip bombs.

    Salt can be used to namespace the hash, so that a signed string is
    only valid for a given namespace. Leaving this at the default
    value or re-using a salt value across different parts of your
    application without good cause is a security risk.

    The serializer is expected to return a bytestring.
    Fé   TÚ.r'   )r2   ÚzlibÚcompressr   r   r!   ÚTimestampSignerÚsign)	r5   r$   r"   Ú
serializerr<   r8   Úis_compressedÚ
compressedÚbase64dr   r   r   r2   ]   s   
r2   c                 C   s\   t ||d�j| |d� ¡ }|dd… dk}|r|dd… }t|ƒ}|r(t |¡}|ƒ  |¡S )z|
    Reverse of dumps(), raise BadSignature if signature fails.

    The serializer is expected to accept a bytestring.
    r'   )Úmax_ageNr9   ó   .)r=   Úunsignr3   r   r;   Ú
decompressr7   )r   r$   r"   r?   rC   rB   rF   r8   r   r   r   r7   ~   s   
r7   c                   @   s.   e Zd Zddd„Zdd„ Zdd„ Zd	d
„ ZdS )r*   Nr.   c                 C   sH   |pt j| _|| _t | j¡rtd| ƒ‚|p d| jj| jj	f | _
d S )NzJUnsafe Signer separator: %r (cannot be empty or consist of only A-z0-9-_=)z%s.%s)r   r)   r$   ÚsepÚ_SEP_UNSAFEÚmatchÚ
ValueErrorÚ	__class__r   r   r"   )r4   r$   rG   r"   r   r   r   Ú__init__“   s   ÿÿzSigner.__init__c                 C   s   t | jd || jƒS )NÚsigner)r%   r"   r$   ©r4   r#   r   r   r   Ú	signaturež   r6   zSigner.signaturec                 C   s   d|| j |  |¡f S ©Nz%s%s%s)rG   rO   rN   r   r   r   r>   ¡   s   zSigner.signc                 C   sJ   | j |vrtd| j  ƒ‚| | j d¡\}}t||  |¡ƒr|S td| ƒ‚)NzNo "%s" found in valuer9   zSignature "%s" does not match)rG   r	   Úrsplitr   rO   )r4   Úsigned_valuer#   Úsigr   r   r   rE   ¤   s   
zSigner.unsign)Nr.   N)r   r   r   rL   rO   r>   rE   r   r   r   r   r*   ‘   s
    
r*   c                       s2   e Zd Zdd„ Z‡ fdd„Zd‡ fdd„	Z‡  ZS )	r=   c                 C   s   t j tt ¡ ƒ¡S r   )r   Úbase62r3   ÚintÚtime)r4   r   r   r   Ú	timestamp¯   r6   zTimestampSigner.timestampc                    s    d|| j |  ¡ f }tƒ  |¡S rP   )rG   rW   Úsuperr>   rN   ©rK   r   r   r>   ²   s   zTimestampSigner.signNc                    sn   t ƒ  |¡}| | jd¡\}}tj |¡}|dur5t|tj	ƒr#| 
¡ }t ¡ | }||kr5td||f ƒ‚|S )zk
        Retrieve original value and check it wasn't signed more
        than max_age seconds ago.
        r9   NzSignature age %s > %s seconds)rX   rE   rQ   rG   r   rT   r!   Ú
isinstanceÚdatetimeÚ	timedeltaÚtotal_secondsrV   r   )r4   r#   rC   ÚresultrW   ÚagerY   r   r   rE   ¶   s   
ÿzTimestampSigner.unsignr   )r   r   r   rW   r>   rE   Ú__classcell__r   r   rY   r   r=   ­   s    r=   )r&   ) r   r   r[   r1   ÚrerV   r;   Údjango.confr   Údjango.utilsr   Údjango.utils.cryptor   r   Údjango.utils.encodingr   Údjango.utils.module_loadingr   ÚcompilerH   Ú	Exceptionr	   r   r   r   r%   r+   r,   r2   r7   r*   r=   r   r   r   r   Ú<module>   s0    #

!