
v^0                 @   s%  d  d l  Z  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 d  d	 l m Z d  d
 l m Z e j e j Z Gd d   d e  Z Gd d   d e  Z Gd d   d  Z d S)    N)datetime	timedelta)settings)SuspiciousSession)SuspiciousOperation)timezone)constant_time_compareget_random_stringsalted_hmac)RemovedInDjango40Warning)import_string)LANGUAGE_SESSION_KEYc               @   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-8lau8j11/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               @   sJ  e  Z d  Z d Z d Z d Z e   Z d d d  Z d d   Z	 d	 d
   Z
 d d   Z d d   Z d d d  Z e 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 d1 d2   Z d3 d4   Z d5 d6   Z  d7 d8   Z! e" e   Z# e" e  e!  Z$ d9 d: d;  Z% e" e%  Z& d< d=   Z' d> d?   Z( d@ dA   Z) dB dC   Z* dD dE   Z+ dF dG   Z, dH dI   Z- dJ dK   Z. dL dM   Z/ d9 dN dO  Z0 d dP dQ  Z1 dR dS   Z2 e3 dT dU    Z4 d S)VSessionBasez-
    Base class for all Session classes.
    Z
testcookieZworkedNc             C   s1   | |  _  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__5   s    zSessionBase.__contains__c             C   s-   | t  k r" t j d t d d |  j | S)NzThe user language will no longer be stored in request.session in Django 4.0. Read it from request.COOKIES[settings.LANGUAGE_COOKIE_NAME] instead.
stacklevel   )r   warningswarnr   r   )r   r   r   r   r   __getitem__8   s
    zSessionBase.__getitem__c             C   s   | |  j  | <d |  _ d  S)NT)r   r   )r   r   valuer   r   r   __setitem__B   s    zSessionBase.__setitem__c             C   s   |  j  | =d |  _ d  S)NT)r   r   )r   r   r   r   r   __delitem__F   s    
zSessionBase.__delitem__c             C   s   |  j  j | |  S)N)r   get)r   r   defaultr   r   r   r)   J   s    zSessionBase.getc             C   sL   |  j  p | |  j k |  _  | |  j k r0 f  n | f } |  j j | |  S)N)r   r   _SessionBase__not_givenpop)r   r   r*   argsr   r   r   r,   M   s    zSessionBase.popc             C   s8   | |  j  k r |  j  | Sd |  _ | |  j  | <| Sd  S)NT)r   r   )r   r   r&   r   r   r   
setdefaultR   s
    	zSessionBase.setdefaultc             C   s   |  j  |  |  j <d  S)N)TEST_COOKIE_VALUETEST_COOKIE_NAME)r   r   r   r   set_test_cookieZ   s    zSessionBase.set_test_cookiec             C   s   |  j  |  j  |  j k S)N)r)   r0   r/   )r   r   r   r   test_cookie_worked]   s    zSessionBase.test_cookie_workedc             C   s   |  |  j  =d  S)N)r0   )r   r   r   r   delete_test_cookie`   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   _hashc   s    zSessionBase._hashc             C   sH   |  j    j |  } |  j |  } t j | j   d |  j d  S)zGReturn the given session dictionary serialized and encoded as a string.   :ascii)r   dumpsr6   base64	b64encodeencodedecode)r   Zsession_dict
serializedhashr   r   r   r<   g   s    zSessionBase.encodec             C   s   t  j | j d   } yb | j d d  \ } } |  j |  } t | j   |  sf t d   n |  j   j	 |  SWnd t
 k
 r } zD t | t  r t j d | j j  } | j t |   i  SWYd  d  } ~ Xn Xd  S)Nr8   r7      zSession data corruptedzdjango.security.%s)r:   	b64decoder<   splitr6   r   r=   r   r   loads	Exception
isinstancer   logging	getLoggerr4   r   warningstr)r   Zsession_dataZencoded_datar?   r>   Zexpected_hasheloggerr   r   r   r=   m   s    zSessionBase.decodec             C   s   |  j  j |  d |  _ d  S)NT)r   updater   )r   Zdict_r   r   r   rL      s    zSessionBase.updatec             C   s   | |  j  k S)N)r   )r   r   r   r   r   has_key   s    zSessionBase.has_keyc             C   s   |  j  j   S)N)r   keys)r   r   r   r   rN      s    zSessionBase.keysc             C   s   |  j  j   S)N)r   values)r   r   r   r   rO      s    zSessionBase.valuesc             C   s   |  j  j   S)N)r   items)r   r   r   r   rP      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   s3   y |  j  o |  j SWn t k
 r. d SYn Xd S)zBReturn True when there is no session_key and the session is empty.TN)r   rQ   AttributeError)r   r   r   r   is_empty   s    zSessionBase.is_emptyc             C   s-   x& t  d t  } |  j |  s | Sq Wd 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   rX   )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)r\   r]   )r   r&   r   r   r   _set_session_key   s    zSessionBase._set_session_keyFc             C   s`   d |  _  y |  j SWnB t k
 rX |  j d k s9 | rE i  |  _ n |  j   |  _ Yn 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   rQ   rS   r   load)r   Zno_loadr   r   r   _get_session   s    	zSessionBase._get_sessionc             C   s   t  j S)N)r   ZSESSION_COOKIE_AGE)r   r   r   r   get_session_cookie_age   s    z"SessionBase.get_session_cookie_agec             K   s   y | d } Wn t  k
 r. t j   } Yn Xy | d } Wn! t  k
 r` |  j d  } Yn X| sq |  j   St | t  s | 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)   rb   rE   r   daysseconds)r   kwargsrc   rd   deltar   r   r   get_expiry_age   s    

zSessionBase.get_expiry_agec             K   s   y | d } Wn t  k
 r. t j   } Yn Xy | d } Wn! t  k
 r` |  j d  } Yn Xt | t  rt | S| p |  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.
        rc   rd   re   ri   )rf   r   rg   r)   rE   r   rb   r   )r   rj   rc   rd   r   r   r   get_expiry_date   s    zSessionBase.get_expiry_datec             C   s]   | d k r0 y |  d =Wn t  k
 r+ Yn Xd St | t  rO t 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.
        Nre   )rf   rE   r   r   rg   )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.
        re   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)rR   deleter   )r   r   r   r   flush'  s    

zSessionBase.flushc             C   s<   |  j  } |  j } |  j   | |  _ | r8 |  j |  d S)zU
        Create a new session key, while retaining the current session data.
        N)r   r   createrQ   rp   )r   datar   r   r   r   	cycle_key0  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   rW   =  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)ru   )r   r   r   r   rr   C  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)ru   )r   Zmust_creater   r   r   saveK  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)ru   )r   r   r   r   r   rp   S  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)ru   )r   r   r   r   r`   Z  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)ru   )clsr   r   r   clear_expired`  s    	zSessionBase.clear_expired)5r   r   r   r   r0   r/   objectr+   r   r    r%   r'   r(   r)   r,   r.   r1   r2   r3   r6   r<   r=   rL   rM   rN   rO   rP   rR   rT   rX   rY   r\   r^   r_   propertyr   r   ra   r   rb   rl   rm   rn   ro   rq   rt   rW   rr   rv   rp   r`   classmethodrx   r   r   r   r   r   &   s^   	
		r   )r:   rF   stringr#   r   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.deprecationr   Zdjango.utils.module_loadingr   Zdjango.utils.translationr   ascii_lowercasedigitsrV   rD   r   r   r   r   r   r   r   <module>   s    