U
    8ÄT_b  ã                   @   s”   d dl Z d dlmZ d dlmZmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZmZ G dd	„ d	e jƒZG d
d„ de jƒZG dd„ deƒZdS )é    N)Úsettings)ÚBaseStorageÚMessage)Úsigning)ÚSimpleCookie)Úconstant_time_compareÚsalted_hmac)ÚSafeDataÚ	mark_safec                       s$   e Zd ZdZdZ‡ fdd„Z‡  ZS )ÚMessageEncoderzI
    Compactly serialize instances of the ``Message`` class as JSON.
    Z__json_messagec                    sR   t |tƒrFt |jtƒrdnd}| j||j|jg}|jrB| |j¡ |S tƒ  	|¡S )Né   r   )
Ú
isinstancer   Úmessager	   Úmessage_keyÚlevelZ
extra_tagsÚappendÚsuperÚdefault)ÚselfÚobjZis_safedatar   ©Ú	__class__© úJ/tmp/pip-unpacked-wheel-dv63caxw/django/contrib/messages/storage/cookie.pyr      s    
zMessageEncoder.default)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__classcell__r   r   r   r   r      s   r   c                       s(   e Zd ZdZdd„ Z‡ fdd„Z‡  ZS )ÚMessageDecoderzE
    Decode JSON that includes serialized ``Message`` instances.
    c                    sz   t |tƒrV|rV|d tjkrD|d r4t|d ƒ|d< t|dd … Ž S ‡ fdd„|D ƒS t |tƒrv‡ fdd„| ¡ D ƒS |S )	Nr   r   é   é   c                    s   g | ]}ˆ   |¡‘qS r   ©Úprocess_messages)Ú.0Úitem©r   r   r   Ú
<listcomp>'   s     z3MessageDecoder.process_messages.<locals>.<listcomp>c                    s   i | ]\}}|ˆ   |¡“qS r   r"   )r$   ÚkeyÚvaluer&   r   r   Ú
<dictcomp>)   s   ÿ z3MessageDecoder.process_messages.<locals>.<dictcomp>)r   Úlistr   r   r
   r   ÚdictÚitems)r   r   r   r&   r   r#   !   s    

ÿzMessageDecoder.process_messagesc                    s   t ƒ j|f|Ž}|  |¡S )N)r   Údecoder#   )r   ÚsÚkwargsÚdecodedr   r   r   r.   -   s    zMessageDecoder.decode)r   r   r   r   r#   r.   r   r   r   r   r   r      s   r   c                       sl   e Zd ZdZdZdZdZdZ‡ fdd„Zdd	„ Z	d
d„ Z
ddd„Zdd„ Zddd„Zdd„ Zdd„ Z‡  ZS )ÚCookieStoragez%
    Store messages in a cookie.
    Úmessagesi   Z__messagesnotfinished__údjango.contrib.messagesc                    s"   t ƒ j||Ž tj| jd�| _d S )N)Zsalt)r   Ú__init__r   Zget_cookie_signerÚkey_saltÚsigner)r   Úargsr0   r   r   r   r5   >   s    zCookieStorage.__init__c                 O   sF   | j j | j¡}|  |¡}|o*|d | jk }|r>|s>| ¡  ||fS )a
  
        Retrieve a list of messages from the messages cookie. If the
        not_finished sentinel value is found at the end of the message list,
        remove it and return a result indicating that not all messages were
        retrieved by this storage.
        éÿÿÿÿ)ÚrequestZCOOKIESÚgetÚcookie_nameÚ_decodeÚnot_finishedÚpop)r   r8   r0   Údatar3   Zall_retrievedr   r   r   Ú_getB   s    
zCookieStorage._getc                 C   sH   |r.|j | j|tjtjpdtjp"dtjd� n|j| jtjtjd� dS )zz
        Either set the cookie with the encoded data if there is any data to
        store, or delete the cookie.
        N)ÚdomainÚsecureÚhttponlyÚsamesite)rB   rE   )Ú
set_cookier<   r   ZSESSION_COOKIE_DOMAINZSESSION_COOKIE_SECUREZSESSION_COOKIE_HTTPONLYZSESSION_COOKIE_SAMESITEZdelete_cookie)r   Úencoded_dataÚresponser   r   r   Ú_update_cookieQ   s     ûýzCookieStorage._update_cookieTc           	         s†   g }|   |¡}| jrvtƒ ‰ ‡ fdd„}|rv||ƒ| jkrv|rN| | d¡¡ n| d| ¡ ¡ | j || jg |d�}q&|  ||¡ |S )aT  
        Store the messages to a cookie and return a list of any messages which
        could not be stored.

        If the encoded data is larger than ``max_cookie_size``, remove
        messages until the data fits (these are the messages which are
        returned), and add the not_finished sentinel value to indicate as much.
        c                    s   t ˆ  | ¡d ƒS )Nr   )ÚlenÚvalue_encode)Úval©Úcookier   r   Ústored_lengthu   s    z+CookieStorage._store.<locals>.stored_lengthr   )Úencode_empty)Ú_encodeÚmax_cookie_sizer   r   r?   Úinsertr>   rI   )	r   r3   rH   Zremove_oldestr8   r0   Zunstored_messagesrG   rO   r   rM   r   Ú_storee   s    	
ÿzCookieStorage._storec                 C   s   d}t ||ƒ ¡ S )zê
        # RemovedInDjango40Warning: pre-Django 3.1 hashes will be invalid.
        Create an HMAC/SHA1 hash based on the value and the project setting's
        SECRET_KEY, modified to make it unique for the present purpose.
        r4   )r   Ú	hexdigest)r   r)   r6   r   r   r   Ú_legacy_hash‚   s    	zCookieStorage._legacy_hashFc                 C   s,   |s|r(t dd�}| |¡}| j |¡S dS )a  
        Return an encoded version of the messages list which can be stored as
        plain text.

        Since the data will be retrieved from the client-side, the encoded data
        also contains a hash to ensure that the data was not tampered with.
        )ú,ú:)Ú
separatorsN)r   Úencoder7   Úsign)r   r3   rP   Úencoderr)   r   r   r   rQ   Ž   s    

zCookieStorage._encodec                 C   sp   |sdS z| j  |¡}W n  tjk
r8   |  |¡}Y nX |rfztj|td�W S  tjk
rd   Y nX d| _	dS )zÄ
        Safely decode an encoded text stream back into a list of messages.

        If the encoded text stream contained an invalid hash or was in an
        invalid format, return None.
        N)ÚclsT)
r7   Zunsignr   ZBadSignatureÚ_legacy_decodeÚjsonÚloadsr   ÚJSONDecodeErrorÚused)r   r@   r1   r   r   r   r=   ›   s    zCookieStorage._decodec                 C   s8   |  dd¡}t|ƒdkr4|\}}t||  |¡ƒr4|S d S )Nú$r   r!   )ÚsplitrJ   r   rV   )r   r@   ÚbitsZhash_r)   r   r   r   r^   µ   s    zCookieStorage._legacy_decode)T)F)r   r   r   r   r<   rR   r>   r6   r5   rA   rI   rT   rV   rQ   r=   r^   r   r   r   r   r   r2   2   s   

r2   )r_   Zdjango.confr   Z$django.contrib.messages.storage.baser   r   Zdjango.corer   Zdjango.httpr   Zdjango.utils.cryptor   r   Zdjango.utils.safestringr	   r
   ÚJSONEncoderr   ÚJSONDecoderr   r2   r   r   r   r   Ú<module>   s   