3
(h                 @   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)SimpleCookie)six)constant_time_comparesalted_hmac)SafeData	mark_safec                   s$   e Zd ZdZdZ fddZ  ZS )MessageEncoderzJ
    Compactly serializes instances of the ``Message`` class as JSON.
    Z__json_messagec                sV   t |trFt |jtrdnd}| j||j|jg}|jrB|j|j |S tt	| j
|S )N   r   )
isinstancer   messager	   message_keylevelZ
extra_tagsappendsuperr   default)selfobjZis_safedatar   )	__class__ J/tmp/pip-install-q3hcpn_q/Django/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 )MessageDecoderzF
    Decodes JSON that includes serialized ``Message`` instances.
    c                s   t |trr|rr|d tjkr`t|dkr8t|dd   S |d rPt|d |d< t|dd   S  fdd|D S t |tr fddtj	|D S |S )	Nr      r      c                s   g | ]} j |qS r   )process_messages).0item)r   r   r   
<listcomp>*   s    z3MessageDecoder.process_messages.<locals>.<listcomp>c                s   i | ]\}} j ||qS r   )r!   )r"   keyvalue)r   r   r   
<dictcomp>,   s   z3MessageDecoder.process_messages.<locals>.<dictcomp>)
r   listr   r   lenr   r
   dictr   	iteritems)r   r   r   )r   r   r!   !   s    

zMessageDecoder.process_messagesc                s   t t| j|f|}| j|S )N)r   r   decoder!   )r   skwargsdecoded)r   r   r   r,   0   s    zMessageDecoder.decode)r   r   r   r   r!   r,   r   r   r   )r   r   r      s   r   c               @   sP   e Zd ZdZdZdZdZdd Zdd Zdd
dZ	dd Z
dddZdd ZdS )CookieStoragez&
    Stores messages in a cookie.
    messagesi   Z__messagesnotfinished__c             O   sH   | j jj| j}| j|}|o*|d | jk }|r@| r@|j  ||fS )a  
        Retrieves 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.
        r   )requestZCOOKIESgetcookie_name_decodenot_finishedpop)r   argsr.   datar1   Zall_retrievedr   r   r   _get@   s    

zCookieStorage._getc             C   s@   |r*|j | j|tjtjpdtjp"dd n|j| jtjd dS )z|
        Either sets the cookie with the encoded data if there is any data to
        store, or deletes the cookie.
        N)domainsecurehttponly)r<   )
set_cookier5   r   ZSESSION_COOKIE_DOMAINZSESSION_COOKIE_SECUREZSESSION_COOKIE_HTTPONLYZdelete_cookie)r   encoded_dataresponser   r   r   _update_cookieO   s    zCookieStorage._update_cookieTc       	         s   g }| j |}| jrzt   fdd}xR|rx||| jkrx|rP|j|jd n|jd|j  | j || jg |d}q(W | j|| |S )aV  
        Stores the messages to a cookie, returning a list of any messages which
        could not be stored.

        If the encoded data is larger than ``max_cookie_size``, removes
        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  j| d S )Nr   )r)   value_encode)val)cookier   r   stored_lengthn   s    z+CookieStorage._store.<locals>.stored_lengthr   )encode_empty)_encodemax_cookie_sizer   r   r8   insertr7   rB   )	r   r1   rA   Zremove_oldestr9   r.   Zunstored_messagesr@   rF   r   )rE   r   _store^   s    	
zCookieStorage._storec             C   s   d}t ||j S )z
        Creates an HMAC/SHA1 hash based on the value and the project setting's
        SECRET_KEY, modified to make it unique for the present purpose.
        zdjango.contrib.messages)r   	hexdigest)r   r&   Zkey_saltr   r   r   _hash{   s    zCookieStorage._hashFc             C   s2   |s|r.t dd}|j|}d| j||f S dS )a	  
        Returns 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.
        ,:)
separatorsz%s$%sN)rN   rO   )r   encoderM   )r   r1   rG   encoderr&   r   r   r   rH      s    

zCookieStorage._encodec             C   sf   |sdS |j dd}t|dkr\|\}}t|| j|r\ytj|tdS  tk
rZ   Y nX d| _dS )z
        Safely decodes 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, ``None`` is returned.
        N$r   r    )clsT)	splitr)   r   rM   jsonloadsr   
ValueErrorused)r   r:   bitshashr&   r   r   r   r6      s    zCookieStorage._decodeN)T)F)r   r   r   r   r5   rI   r7   r;   rB   rK   rM   rH   r6   r   r   r   r   r0   5   s   

r0   )rV   Zdjango.confr   Z$django.contrib.messages.storage.baser   r   Zdjango.httpr   Zdjango.utilsr   Zdjango.utils.cryptor   r   Zdjango.utils.safestringr	   r
   JSONEncoderr   JSONDecoderr   r0   r   r   r   r   <module>   s   