o
    bL6                     @   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 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G dd deZG dd deZG dd dZ dS )    N)datetime	timedelta)settings)SuspiciousSession)signing)SuspiciousOperation)timezone)constant_time_compareget_random_stringsalted_hmac)RemovedInDjango40Warning)import_string)LANGUAGE_SESSION_KEYc                   @      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   d/var/www/secure340b-portal/env/lib/python3.10/site-packages/django/contrib/sessions/backends/base.pyr      s    r   c                   @   r   )UpdateErrorzF
    Occurs if Django tries to update a session that was deleted.
    Nr   r   r   r   r   r       s    r   c                   @   s  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edd Zd\d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/d0 Zd1d2 Zd3d4 Z d5d6 Z!d7d8 Z"d9d: Z#d;d< Z$d=d> Z%ee$Z&ee$e%Z'd]d@dAZ(ee(Z)dBdC Z*dDdE Z+dFdG Z,dHdI Z-dJdK Z.dLdM Z/dNdO Z0dPdQ Z1dRdS Z2d]dTdUZ3d\dVdWZ4dXdY Z5e6dZd[ Z7dS )^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__0   s   zSessionBase.__init__c                 C   
   || j v S N_sessionr   keyr   r   r   __contains__6      
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   __getitem__9   s   
zSessionBase.__getitem__c                 C   s   || j |< d| _d S NTr%   r   r   r'   valuer   r   r   __setitem__C   s   

zSessionBase.__setitem__c                 C   s   | j |= d| _d S r/   r0   r&   r   r   r   __delitem__G   s   
zSessionBase.__delitem__c                 C   s   d| j j S )Nzdjango.contrib.sessions.)	__class__r   r   r   r   r   key_saltK   s   zSessionBase.key_saltc                 C   s   | j ||S r#   )r%   get)r   r'   defaultr   r   r   r8   O   s   zSessionBase.getc                 C   s:   | j p|| jv | _ || ju rdn|f}| jj|g|R  S )Nr   )r   r%   _SessionBase__not_givenpop)r   r'   r9   argsr   r   r   r;   R   s   zSessionBase.popc                 C   s(   || j v r
| j | S d| _|| j |< |S r/   r0   r1   r   r   r   
setdefaultW   s
   


zSessionBase.setdefaultc                 C   s   | j | | j< d S r#   )TEST_COOKIE_VALUETEST_COOKIE_NAMEr6   r   r   r   set_test_cookie_   s   zSessionBase.set_test_cookiec                 C   s   |  | j| jkS r#   )r8   r?   r>   r6   r   r   r   test_cookie_workedb   s   zSessionBase.test_cookie_workedc                 C   s   | | j = d S r#   )r?   r6   r   r   r   delete_test_cookiee   s   zSessionBase.delete_test_cookiec                 C   s   d| j j }t|| S )Nzdjango.contrib.sessions)r5   r   r   	hexdigest)r   r2   r7   r   r   r   _hashh   s   zSessionBase._hashc                 C   s*   t jdkr
| |S tj|| j| jddS )zGReturn the given session dictionary serialized and encoded as a string.sha1T)saltr   compress)r   ZDEFAULT_HASHING_ALGORITHM_legacy_encoder   dumpsr7   r   )r   session_dictr   r   r   encodem   s   


zSessionBase.encodec                 C   s   zt j|| j| jdW S  t jy3   z| |W  Y S  ty2   td}|	d i  Y  Y S w  ty@   | | Y S w )N)rF   r   z!django.security.SuspiciousSessionSession data corrupted)
r   loadsr7   r   ZBadSignature_legacy_decode	Exceptionlogging	getLoggerwarning)r   session_dataloggerr   r   r   decodew   s   

zSessionBase.decodec                 C   s4   |   |}| |}t| d | dS )N   :ascii)r   rI   rD   base64	b64encoderK   rU   )r   rJ   
serializedhashr   r   r   rH      s   
zSessionBase._legacy_encodec              
   C   s   t |d}z |dd\}}| |}t| |s!td|  	|W S  t
yQ } zt|trEtd|jj }|t| i W  Y d }~S d }~ww )NrW   rV      rL   zdjango.security.%s)rX   	b64decoderK   splitrD   r	   rU   r   r   rM   rO   
isinstancer   rP   rQ   r5   r   rR   str)r   rS   Zencoded_datar[   rZ   Zexpected_hasherT   r   r   r   rN      s   

zSessionBase._legacy_decodec                 C   s   | j | d| _d S r/   )r%   updater   )r   Zdict_r   r   r   rb      s   
zSessionBase.updatec                 C   r"   r#   r$   r&   r   r   r   has_key   r)   zSessionBase.has_keyc                 C   
   | j  S r#   )r%   keysr6   r   r   r   re      r)   zSessionBase.keysc                 C   rd   r#   )r%   valuesr6   r   r   r   rf      r)   zSessionBase.valuesc                 C   rd   r#   )r%   itemsr6   r   r   r   rg      r)   zSessionBase.itemsc                 C   s   i | _ d| _d| _d S r/   )_session_cacher   r   r6   r   r   r   clear   s   
zSessionBase.clearc                 C   s(   z	| j  o| j W S  ty   Y dS w )zBReturn True when there is no session_key and the session is empty.T)r   rh   AttributeErrorr6   r   r   r   is_empty   s
   zSessionBase.is_emptyc                 C   s   	 t dt}| |s|S q)z)Return session key that isn't being used.T    )r
   VALID_KEY_CHARSexistsr   r   r   r   _get_new_session_key   s
   

z SessionBase._get_new_session_keyc                 C   s   | j d u r
|  | _ | j S r#   )r   ro   r6   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.
           )lenr&   r   r   r   _validate_session_key   s   z!SessionBase._validate_session_keyc                 C   s   | j S r#   )_SessionBase__session_keyr6   r   r   r   _get_session_key      zSessionBase._get_session_keyc                 C   s   |  |r
|| _dS d| _dS )zV
        Validate session key on assignment. Invalid values will set to None.
        N)rs   rt   r   r2   r   r   r   _set_session_key   s   


zSessionBase._set_session_keyFc                 C   sL   d| _ z| jW S  ty%   | jdu s|ri | _Y | jS |  | _Y | jS w )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   rh   rj   r    load)r   Zno_loadr   r   r   _get_session   s   zSessionBase._get_sessionc                 C   s   t jS r#   )r   ZSESSION_COOKIE_AGEr6   r   r   r   get_session_cookie_age   rv   z"SessionBase.get_session_cookie_agec                 K   s   z|d }W n t y   t }Y nw z|d }W n t y(   | d}Y nw |s/|  S t|ts6|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   nowr8   r{   r_   r   daysseconds)r   kwargsr|   r}   deltar   r   r   get_expiry_age   s    
zSessionBase.get_expiry_agec                 K   sz   z|d }W n t y   t }Y nw z|d }W n t y(   | d}Y nw t|tr0|S |p5|  }|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~   )r   )r   r   r   r8   r_   r   r{   r   )r   r   r|   r}   r   r   r   get_expiry_date  s   
zSessionBase.get_expiry_datec                 C   sL   |du rz| d= W dS  t y   Y dS w t|tr t | }|| 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   rw   r   r   r   
set_expiry$  s   
zSessionBase.set_expiryc                 C   s"   |  ddu r
tjS |  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   )r8   r   ZSESSION_EXPIRE_AT_BROWSER_CLOSEr6   r   r   r   get_expire_at_browser_close>  s   z'SessionBase.get_expire_at_browser_closec                 C   s   |    |   d| _dS )zc
        Remove the current session data from the database and regenerate the
        key.
        N)ri   deleter   r6   r   r   r   flushI  s   
zSessionBase.flushc                 C   s0   | j }| j}|   || _|r| | dS dS )zU
        Create a new session key, while retaining the current session data.
        N)r%   r    createrh   r   )r   datar'   r   r   r   	cycle_keyR  s   zSessionBase.cycle_keyc                 C      t d)zF
        Return True if the given session_key already exists.
        z9subclasses of SessionBase must provide an exists() methodNotImplementedErrorr   r   r   r   rn   _     zSessionBase.existsc                 C   r   )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() methodr   r6   r   r   r   r   e     zSessionBase.createc                 C   r   )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() methodr   )r   Zmust_creater   r   r   savem  r   zSessionBase.savec                 C   r   )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() methodr   r   r   r   r   r   u  s   zSessionBase.deletec                 C   r   )z@
        Load the session data and return a dictionary.
        z6subclasses of SessionBase must provide a load() methodr   r6   r   r   r   ry   |  r   zSessionBase.loadc                 C   r   )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().r   )clsr   r   r   clear_expired  s   	zSessionBase.clear_expiredr#   )F)8r   r   r   r   r?   r>   objectr:   r!   r(   r.   r3   r4   propertyr7   r8   r;   r=   r@   rA   rB   rD   rK   rU   rH   rN   rb   rc   re   rf   rg   ri   rk   ro   rp   rs   ru   rx   r    r   rz   r%   r{   r   r   r   r   r   r   rn   r   r   r   ry   classmethodr   r   r   r   r   r   '   sj    




	

	

r   )!rX   rP   stringr,   r   r   Zdjango.confr   Z"django.contrib.sessions.exceptionsr   Zdjango.corer   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digitsrm   rO   r   r   r   r   r   r   r   <module>   s$    