3
7^o.                 @   s   d dl Z d dlZd dlZd dlmZ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mZmZ d dlmZ ejej ZG d	d
 d
eZG dd deZG dd dZdS )    N)datetime	timedelta)settings)SuspiciousSession)SuspiciousOperation)timezone)constant_time_compareget_random_stringsalted_hmac)import_stringc               @   s   e Zd ZdZdS )CreateErrorz
    Used internally as a consistent exception type to catch from save (see the
    docstring for SessionBase.save() for details).
    N)__name__
__module____qualname____doc__ r   r   G/tmp/pip-build-8app2_gc/Django/django/contrib/sessions/backends/base.pyr      s   r   c               @   s   e Zd ZdZdS )UpdateErrorzF
    Occurs if Django tries to update a session that was deleted.
    N)r   r   r   r   r   r   r   r   r      s   r   c               @   s  e Zd ZdZdZdZe ZdTddZdd Z	d	d
 Z
dd Zdd ZdUddZefddZdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Z d7d8 Z!e"e Z#e"e e!Z$dVd:d;Z%e"e%Z&d<d= Z'd>d? Z(d@dA Z)dBdC Z*dDdE Z+dFdG Z,dHdI Z-dJdK Z.dWdLdMZ/dXdNdOZ0dPdQ Z1e2dRdS Z3dS )YSessionBasez-
    Base class for all Session classes.
    Z
testcookieZworkedNc             C   s"   || _ d| _d| _ttj| _d S )NF)_session_keyaccessedmodifiedr   r   ZSESSION_SERIALIZER
serializer)selfsession_keyr   r   r   __init__,   s    zSessionBase.__init__c             C   s
   || j kS )N)_session)r   keyr   r   r   __contains__2   s    zSessionBase.__contains__c             C   s
   | j | S )N)r   )r   r   r   r   r   __getitem__5   s    zSessionBase.__getitem__c             C   s   || j |< d| _d S )NT)r   r   )r   r   valuer   r   r   __setitem__8   s    
zSessionBase.__setitem__c             C   s   | j |= d| _d S )NT)r   r   )r   r   r   r   r   __delitem__<   s    zSessionBase.__delitem__c             C   s   | j j||S )N)r   get)r   r   defaultr   r   r   r#   @   s    zSessionBase.getc             C   s8   | j p|| jk| _ || jkr f n|f}| jj|f| S )N)r   r   _SessionBase__not_givenpop)r   r   r$   argsr   r   r   r&   C   s    zSessionBase.popc             C   s,   || j kr| j | S d| _|| j |< |S d S )NT)r   r   )r   r   r    r   r   r   
setdefaultH   s
    


zSessionBase.setdefaultc             C   s   | j | | j< d S )N)TEST_COOKIE_VALUETEST_COOKIE_NAME)r   r   r   r   set_test_cookieP   s    zSessionBase.set_test_cookiec             C   s   | j | j| jkS )N)r#   r*   r)   )r   r   r   r   test_cookie_workedS   s    zSessionBase.test_cookie_workedc             C   s   | | j = d S )N)r*   )r   r   r   r   delete_test_cookieV   s    zSessionBase.delete_test_cookiec             C   s   d| j j }t||j S )Nzdjango.contrib.sessions)	__class__r   r
   	hexdigest)r   r    Zkey_saltr   r   r   _hashY   s    zSessionBase._hashc             C   s4   | j  j|}| j|}tj|j d | jdS )zGReturn the given session dictionary serialized and encoded as a string.   :ascii)r   dumpsr0   base64	b64encodeencodedecode)r   Zsession_dict
serializedhashr   r   r   r6   ]   s    
zSessionBase.encodec             C   s   t j|jd}yD|jdd\}}| j|}t|j |sDtdn| j j	|S W nJ t
k
r } z.t|trtjd|jj }|jt| i S d }~X nX d S )Nr2   r1      zSession data corruptedzdjango.security.%s)r4   	b64decoder6   splitr0   r   r7   r   r   loads	Exception
isinstancer   logging	getLoggerr.   r   warningstr)r   Zsession_dataZencoded_datar9   r8   Zexpected_hasheloggerr   r   r   r7   c   s    


zSessionBase.decodec             C   s   | j j| d| _d S )NT)r   updater   )r   Zdict_r   r   r   rF   u   s    zSessionBase.updatec             C   s
   || j kS )N)r   )r   r   r   r   r   has_keyy   s    zSessionBase.has_keyc             C   s
   | j j S )N)r   keys)r   r   r   r   rH   |   s    zSessionBase.keysc             C   s
   | j j S )N)r   values)r   r   r   r   rI      s    zSessionBase.valuesc             C   s
   | j j S )N)r   items)r   r   r   r   rJ      s    zSessionBase.itemsc             C   s   i | _ d| _d| _d S )NT)_session_cacher   r   )r   r   r   r   clear   s    zSessionBase.clearc             C   s*   y| j  o| j S  tk
r$   dS X dS )zBReturn True when there is no session_key and the session is empty.TN)r   rK   AttributeError)r   r   r   r   is_empty   s    zSessionBase.is_emptyc             C   s"   xt dt}| j|s|S qW dS )z)Return session key that isn't being used.    N)r	   VALID_KEY_CHARSexists)r   r   r   r   r   _get_new_session_key   s    

z SessionBase._get_new_session_keyc             C   s   | j d kr| j | _ | j S )N)r   rR   )r   r   r   r   _get_or_create_session_key   s    

z&SessionBase._get_or_create_session_keyc             C   s   |ot |dkS )z
        Key must be truthy and at least 8 characters long. 8 characters is an
        arbitrary lower bound for some minimal key security.
           )len)r   r   r   r   r   _validate_session_key   s    z!SessionBase._validate_session_keyc             C   s   | j S )N)_SessionBase__session_key)r   r   r   r   _get_session_key   s    zSessionBase._get_session_keyc             C   s   | j |r|| _nd| _dS )zV
        Validate session key on assignment. Invalid values will set to None.
        N)rV   rW   )r   r    r   r   r   _set_session_key   s    
zSessionBase._set_session_keyFc             C   sH   d| _ y| jS  tk
r@   | jdks*|r2i | _n
| j | _Y nX | jS )z
        Lazily load session from storage (unless "no_load" is True, when only
        an empty dict is stored) and store it in the current instance.
        TN)r   rK   rM   r   load)r   Zno_loadr   r   r   _get_session   s    zSessionBase._get_sessionc             K   s   y|d }W n t k
r(   tj }Y nX y|d }W n t k
rT   | jd}Y nX |s`tjS t|tsn|S || }|jd |j	 S )zGet the number of seconds until the session expires.

        Optionally, this function accepts `modification` and `expiry` keyword
        arguments specifying the modification and expiry of the session.
        modificationexpiry_session_expiryiQ )
KeyErrorr   nowr#   r   SESSION_COOKIE_AGEr?   r   daysseconds)r   kwargsr\   r]   deltar   r   r   get_expiry_age   s    
zSessionBase.get_expiry_agec             K   s|   y|d }W n t k
r(   tj }Y nX y|d }W n t k
rT   | jd}Y nX t|trd|S |pltj}|t|d S )zGet session the expiry date (as a datetime object).

        Optionally, this function accepts `modification` and `expiry` keyword
        arguments specifying the modification and expiry of the session.
        r\   r]   r^   )rc   )	r_   r   r`   r#   r?   r   r   ra   r   )r   rd   r\   r]   r   r   r   get_expiry_date   s    

zSessionBase.get_expiry_datec             C   sN   |dkr,y
| d= W n t k
r&   Y nX dS t|trBtj | }|| d< dS )a*  
        Set a custom expiration for the session. ``value`` can be an integer,
        a Python ``datetime`` or ``timedelta`` object or ``None``.

        If ``value`` is an integer, the session will expire after that many
        seconds of inactivity. If set to ``0`` then the session will expire on
        browser close.

        If ``value`` is a ``datetime`` or ``timedelta`` object, the session
        will expire at that specific future time.

        If ``value`` is ``None``, the session uses the global session expiry
        policy.
        Nr^   )r_   r?   r   r   r`   )r   r    r   r   r   
set_expiry   s    

zSessionBase.set_expiryc             C   s"   | j ddkrtjS | j ddkS )a  
        Return ``True`` if the session is set to expire when the browser
        closes, and ``False`` if there's an expiry date. Use
        ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry
        date/age, if there is one.
        r^   Nr   )r#   r   ZSESSION_EXPIRE_AT_BROWSER_CLOSE)r   r   r   r   get_expire_at_browser_close  s    z'SessionBase.get_expire_at_browser_closec             C   s   | j   | j  d| _dS )zc
        Remove the current session data from the database and regenerate the
        key.
        N)rL   deleter   )r   r   r   r   flush  s    zSessionBase.flushc             C   s,   | j }| j}| j  || _|r(| j| dS )zU
        Create a new session key, while retaining the current session data.
        N)r   r   createrK   rj   )r   datar   r   r   r   	cycle_key#  s    zSessionBase.cycle_keyc             C   s   t ddS )zF
        Return True if the given session_key already exists.
        z9subclasses of SessionBase must provide an exists() methodN)NotImplementedError)r   r   r   r   r   rQ   0  s    zSessionBase.existsc             C   s   t ddS )z
        Create a new session instance. Guaranteed to create a new object with
        a unique key and will have saved the result once (with empty data)
        before the method returns.
        z8subclasses of SessionBase must provide a create() methodN)ro   )r   r   r   r   rl   6  s    zSessionBase.createc             C   s   t ddS )z
        Save the session data. If 'must_create' is True, create a new session
        object (or raise CreateError). Otherwise, only update an existing
        object and don't create one (raise UpdateError if needed).
        z6subclasses of SessionBase must provide a save() methodN)ro   )r   Zmust_creater   r   r   save>  s    zSessionBase.savec             C   s   t ddS )zx
        Delete the session data under this key. If the key is None, use the
        current session key value.
        z8subclasses of SessionBase must provide a delete() methodN)ro   )r   r   r   r   r   rj   F  s    zSessionBase.deletec             C   s   t ddS )z@
        Load the session data and return a dictionary.
        z6subclasses of SessionBase must provide a load() methodN)ro   )r   r   r   r   rZ   M  s    zSessionBase.loadc             C   s   t ddS )a  
        Remove expired sessions from the session store.

        If this operation isn't possible on a given backend, it should raise
        NotImplementedError. If it isn't necessary, because the backend has
        a built-in expiration mechanism, it should be a no-op.
        z.This backend does not support clear_expired().N)ro   )clsr   r   r   clear_expiredS  s    	zSessionBase.clear_expired)N)N)F)F)N)4r   r   r   r   r*   r)   objectr%   r   r   r   r!   r"   r#   r&   r(   r+   r,   r-   r0   r6   r7   rF   rG   rH   rI   rJ   rL   rN   rR   rS   rV   rX   rY   propertyr   r   r[   r   rf   rg   rh   ri   rk   rn   rQ   rl   rp   rj   rZ   classmethodrr   r   r   r   r   r   #   s\   

	

	

r   )r4   r@   stringr   r   Zdjango.confr   Z"django.contrib.sessions.exceptionsr   Zdjango.core.exceptionsr   Zdjango.utilsr   Zdjango.utils.cryptor   r	   r
   Zdjango.utils.module_loadingr   ascii_lowercasedigitsrP   r>   r   r   r   r   r   r   r   <module>   s   