
    ՟f8                     H   d dl Z d dlZd dlmZmZ d dlmZ 	 d dlZd dl
Z
d dlmZ d dlmZmZmZ d dl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mZmZ d d
lm Z  ddl!m"Z" ddl#m$Z$  G d de e      Z% G d de      Z& G d de&      Z' G d dee      Z(y# e	$ r d dlZY w xY w)    N)ABCabstractmethod)suppress)	timedelta)AnyDictOptional)FlaskRequestResponse)SessionInterface)SessionMixin)BadSignatureSigner
want_bytes)CallbackDict   )retry_query)Defaultsc                        e Zd ZdZdefdZ	 	 	 ddeeee	f      dee   dee   fdZ
dede	f fd	Zdded
e	de	f fdZdded
e	de	f fdZd fdZ xZS )ServerSideSessiona  Baseclass for server-side based sessions. This can be accessed through ``flask.session``.

    .. attribute:: sid

    Session id, internally we use :func:`secrets.token_urlsafe` to generate one
    session id.

    .. attribute:: modified

    When data is changed, this is set to ``True``. Only the session dictionary
    itself is tracked; if the session contains mutable data (for example a nested
    dict) then this must be set to ``True`` manually when modifying that data. The
    session cookie will only be written to the response if this is ``True``.

    .. attribute:: accessed

    When data is read (or attempted read) or written, this is set to ``True``. Used by
    :class:`.ServerSideSessionInterface` to add a ``Vary: Cookie``
    header, which allows caching proxies to cache different pages for
    different users.

    Default is ``False``.

    .. attribute:: permanent

    This sets and reflects the ``'_permanent'`` key in the dict.

    Default is ``False``.

    returnc                 V    t        t        |             xr | j                         dhk7  S )N
_permanent)booldictkeysselfs    M/var/www/cvtools/html/venv/lib/python3.12/site-packages/flask_session/base.py__bool__zServerSideSession.__bool__:   s#    DJADIIKL>$AA    initialsid	permanentc                 v    dd}t        j                  | ||       || _        |r|| _        d| _        d| _        y )Nc                      d| _         d| _        y NT)modifiedaccessedr   s    r    	on_updatez-ServerSideSession.__init__.<locals>.on_updateC   s     DM DMr"   Fr   N)r   __init__r$   r%   r)   r*   )r   r#   r$   r%   r+   s        r    r-   zServerSideSession.__init__=   s:    	! 	dGY7&DNr"   keyc                 0    d| _         t        | 	  |      S r(   )r*   super__getitem__)r   r.   	__class__s     r    r1   zServerSideSession.__getitem__N   s    w"3''r"   defaultc                 2    d| _         t        | 	  ||      S r(   )r*   r0   getr   r.   r3   r2   s      r    r5   zServerSideSession.getR   s    w{3((r"   c                 2    d| _         t        | 	  ||      S r(   )r*   r0   
setdefaultr6   s      r    r8   zServerSideSession.setdefaultV   s    w!#w//r"   c                 P    | j                  dd      }t        | 	          || d<   y)z2Clear the session except for the '_permanent' key.r   FN)r5   r0   clear)r   r%   r2   s     r    r:   zServerSideSession.clearZ   s&    HH\51	&\r"   )NNNNr,   )__name__
__module____qualname____doc__r   r!   r	   r   strr   r-   r1   r5   r8   r:   __classcell__)r2   s   @r    r   r      s    >B$ B
 -1!$(	$sCx.) c] D>	"(s (s ()s )S )C )0c 0C 03 0' 'r"   r   c                   D    e Zd ZdZededefd       Zededefd       Z	y)
Serializerz$Baseclass for session serialization.serialized_datar   c                     t               )Deserialize the session data.NotImplementedErrorr   rD   s     r    decodezSerializer.decoded        "##r"   sessionc                     t               )Serialize the session data.rG   )r   rL   s     r    encodezSerializer.encodei   rK   r"   N)
r<   r=   r>   r?   r   bytesr   rJ   r   rO    r"   r    rC   rC   a   sH    .$e $ $ $ $/ $E $ $r"   rC   c                   <    e Zd ZdedefdZdedefdZdede	fdZ
y	)
MsgSpecSerializerappformatc                    || _         |  |  |  |dk(  rjt        j                  j                         | _        t        j                  j                         | _        t        j                  j                         | _        y |dk(  rjt        j                  j                         | _        t        j                  j                         | _        t        j                  j                         | _        y t        d|       )Nmsgpackjsonz"Unsupported serialization format: )
rT   msgspecrW   EncoderencoderDecoderdecoderrX   alternate_decoder
ValueError)r   rT   rU   s      r    r-   zMsgSpecSerializer.__init__p   s    Y"??224DL"??224DL%,\\%9%9%;D"v"<<//1DL"<<//1DL%,__%<%<%>D"A&JKKr"   rL   r   c                     	 | j                   j                  t        |            S # t        $ r.}| j                  j
                  j                  d|         d}~ww xY w)rN   z"Failed to serialize session data: N)r[   rO   r   	ExceptionrT   loggererror)r   rL   es      r    rO   zMsgSpecSerializer.encode   sQ    	<<&&tG}55 	HHOO!!$Fqc"JK	s   #& 	A)AArD   c                 *   t        t        j                        5  | j                  j	                  |      cddd       S # 1 sw Y   nxY wt        t        j                        5  | j
                  j	                  |      cddd       S # 1 sw Y   nxY wt        t        j                        5  t        j                  |      cddd       S # 1 sw Y   nxY w| j                  j                  j                  dd       t        j                  d      )rF   Nz"Failed to deserialize session dataT)exc_info)r   rY   DecodeErrorr]   rJ   r^   pickleUnpicklingErrorloadsrT   rb   rc   rI   s     r    rJ   zMsgSpecSerializer.decode   s     g))* 	8<<&&7	8 	8 	8g))* 	B))00A	B 	B 	Bf,,- 	1<<0	1 	1 	1 	BTR$$%IJJs!   ?A$B		B.CCN)r<   r=   r>   r
   r@   r-   r   rP   rO   r   rJ   rQ   r"   r    rS   rS   o   sB    LE L3 L"/ E Ke K Kr"   rS   c                   .   e Zd ZdZeZdZdZej                  ej                  ej                  ej                  ej                  ej                  fdededededed	ed
ee   fdZdedefdZdedefdZdedefdZdedefdZdedefdZdededefdZd Zd#dZdeddfdZdedededdfdZ dede!defdZ"e# e$       dedee%   fd              Z&e# e$       deddfd              Z'e# e$       d e(dededdfd!              Z) e$       d#d"       Z*y)$ServerSideSessionInterfacezKUsed to open a :class:`flask.sessions.ServerSideSessionInterface` instance.NTrT   
key_prefix
use_signerr%   
sid_lengthserialization_formatcleanup_n_requestsc                 |   || _         || _        || _        |rt        j                  dt
        d       || _        || _        t        | d      | _	        || _
        t        | dd       du rB| j                  r&| j                   j                  | j                         n| j                          t        ||      | _        y )NzThe 'use_signer' option is deprecated and will be removed in the next minor release. Please update your configuration accordingly or open an issue.r   )
stacklevelget_cookie_samesitettlF)rU   rT   )rT   rm   rn   warningswarnDeprecationWarningr%   ro   hasattrhas_same_site_capabilityrq   getattrbefore_request_cleanup_n_requests_register_cleanup_app_commandrS   
serializer)r   rT   rm   rn   r%   ro   rp   rq   s           r    r-   z#ServerSideSessionInterface.__init__   s     $$MMQ"	 #$(/6K(L%"4 4%.&&''(@(@A224 ,3GSQr"   session_id_lengthr   c                 ,    t        j                  |      S )zGenerate a random session id.)secretstoken_urlsafe)r   r   s     r    _generate_sidz(ServerSideSessionInterface._generate_sid   s    $$%677r"   c                 x    t        |d      r|j                  st        d      t        |j                  dd      S )N
secret_keyz3SECRET_KEY must be set when SESSION_USE_SIGNER=Truezflask-sessionhmac)saltkey_derivation)ry   r   KeyErrorr   )r   rT   s     r    _get_signerz&ServerSideSessionInterface._get_signer   s1    sL)PQQcnn?6RRr"   r$   c                 j    | j                  |      }|j                  |      }|j                         }|S r;   )r   unsignrJ   r   rT   r$   signersid_as_bytess        r    _unsignz"ServerSideSessionInterface._unsign   s3    !!#&}}S)!!#
r"   c                 z    | j                  |      }t        |      }|j                  |      j                  d      S )Nzutf-8)r   r   signrJ   r   s        r    _signz ServerSideSessionInterface._sign   s5    !!#&!#{{<(//88r"   c                      | j                   |z   S r;   )rm   )r   r$   s     r    _get_store_idz(ServerSideSessionInterface._get_store_id   s    $$r"   rL   c                 <    |j                   xs |j                  d   S )a  Used by session backends to determine if session in storage
        should be set for this session cookie for this response. If the session
        has been modified, the session is set to storage. If
        the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the session is
        always set to storage. In the second case, this means refreshing the
        storage expiry even if the session has not been modified.

        .. versionadded:: 0.7.0
        SESSION_REFRESH_EACH_REQUEST)r)   config)r   rT   rL   s      r    should_set_storagez-ServerSideSessionInterface.should_set_storage   s     M3::.L#MMr"   c                 `      j                   j                  j                  d       fd       }y)z
        Register a custom Flask CLI command for cleaning up expired sessions.

        Run the command with `flask session_cleanup`. Run with a cron job
        or scheduler such as Heroku Scheduler to automatically clean up expired sessions.
        session_cleanupc                       j                   j                         5   j                          d d d        y # 1 sw Y   y xY wr;   )rT   app_context_delete_expired_sessionsr   s   r    r   zQServerSideSessionInterface._register_cleanup_app_command.<locals>.session_cleanup   s4    %%' 0--/0 0 0s   6?N)rT   clicommand)r   r   s   ` r    r~   z8ServerSideSessionInterface._register_cleanup_app_command   s+     
		/	0	0 
1	0r"   c                     | j                   r5t        j                  d| j                         dk(  r| j                          yyy)z
        Delete expired sessions on average every N requests.

        This is less desirable than using the scheduled app command cleanup as it may
        slow down some requests but may be useful for rapid development.
        r   N)rq   randomrandintr   r   s    r    r}   z.ServerSideSessionInterface._cleanup_n_requests   s;     ""v~~a9P9P'QUV'V))+ (W"r"   c                     |rT| j                  | j                  |j                               | j                  | j                        }||_        d|_        yy)zqRegenerate the session id for the given session. Can be used by calling ``flask.session_interface.regenerate()``.TN)_delete_sessionr   r$   r   ro   r)   )r   rL   new_sids      r    
regeneratez%ServerSideSessionInterface.regenerate  sJ      !3!3GKK!@A((9G!GK#G r"   responsec           
         | j                  |      }| j                  |      }| j                  |      }| j                  |j                        }|j
                  r|j                  j                  d       |sM|j                  r@| j                  |       |j                  |||       |j                  j                  d       y | j                  ||      sy | j                  |j                  ||       | j                  ||      sy | j                  r| j!                  ||j                        n|j                  }| j#                  ||      }	| j%                  |      }
| j'                  |      }| j(                  r| j+                  |      nd }|j-                  |||	|
||||       |j                  j                  d       y )NCookie)r.   domainpath)r.   valueexpireshttponlyr   r   securesamesite)get_cookie_domainget_cookie_pathget_cookie_namer   r$   r*   varyaddr)   r   delete_cookier   _upsert_sessionpermanent_session_lifetimeshould_set_cookiern   r   get_expiration_timeget_cookie_httponlyget_cookie_securerz   rt   
set_cookie)r   rT   rL   r   r   r   namestore_idr   r   r   r   r   s                r    save_sessionz'ServerSideSessionInterface.save_session  s   
 '',##C(##C( %%gkk2
 MMh' $$X.&&4T&J!!(+&&sG4 	S;;WhO%%c73 15

3,W[[**38++C0'',-1-J-JD$$S)PT 	
 	 	 		
 	(#r"   requestc                 p   |j                   j                  |j                  d         }|s8| j                  | j                        }| j                  || j                        S | j                  r	 | j                  ||      }| j                  |      }| j                  |      }|| j                  ||      S | j                  | j                        }| j                  || j                        S # t        $ r; | j                  | j                        }| j                  || j                        cY S w xY w)NSESSION_COOKIE_NAME)r$   r%   )r$   )cookiesr5   r   r   ro   session_classr%   rn   r   r   r   _retrieve_session_data)r   rT   r   r$   r   saved_session_datas         r    open_sessionz'ServerSideSessionInterface.open_sessionL  s#   oo!!#**-B"CD $$T__5C%%#%HH??Mll3, %%c*!88B )%%&8c%BB   1!!cT^^!DD   M((9))cT^^)LLMs   0C1 1AD54D5r   c                     t               )z/Get the saved session from the session storage.rG   r   r   s     r    r   z1ServerSideSessionInterface._retrieve_session_dataj       "##r"   c                     t               )z(Delete session from the session storage.rG   r   s     r    r   z*ServerSideSessionInterface._delete_sessionp  r   r"   session_lifetimec                     t               )z=Update existing or create new session in the session storage.rG   )r   r   rL   r   s       r    r   z*ServerSideSessionInterface._upsert_sessionv  s     "##r"   c                      y)zVDelete expired sessions from the session storage. Only required for non-TTL databases.NrQ   r   s    r    r   z3ServerSideSessionInterface._delete_expired_sessions~  s     	r"   r,   )+r<   r=   r>   r?   r   r   r   ru   r   SESSION_KEY_PREFIXSESSION_USE_SIGNERSESSION_PERMANENTSESSION_ID_LENGTHSESSION_SERIALIZATION_FORMATSESSION_CLEANUP_N_REQUESTSr
   r@   r   intr	   r-   r   r   r   r   r   r   r   r~   r}   r   r   r   r   r   r   r   r   r   r   	TimeDeltar   r   rQ   r"   r    rl   rl      s6   U%MJ
C
 #55#66"44"44$,$I$I,4,O,O!R!R !R 	!R
 !R !R "!R %SM!RJ8s 8s 8
Su S S  9c 9c 9
% % %Ne N6G ND N0,	$"3 	$ 	$8$8$#48$@H8$	8$tE E E<M E< ]$s $x~ $  $ ]$ $ $  $ ]$ )$4E$QT$	$  $ ] r"   rl   ))r   rv   abcr   r   
contextlibr   cPicklerh   ImportErrorr   datetimer   r   typingr   r   r	   rY   flaskr
   r   r   flask.sessionsr   FlaskSessionInterfacer   itsdangerousr   r   r   werkzeug.datastructuresr   _utilsr   defaultsr   r   rC   rS   rl   rQ   r"   r    <module>r      s      #   + & &  * * D ' 9 9 0  D'l D'N$ $%K
 %KPj!6 j_  s   B 	B! B!