§
    ùÛgý7  ã                   óR  — d 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m	Z	 ddl
mZ ddlmZmZ dd	lmZmZ dd
lmZ ddlmZmZ  G d„ de¦  «        Zd„ Z G d„ de¦  «        Z e¦   «         Z G d„ dee¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        ZdS )zÂ
    flask.sessions
    ~~~~~~~~~~~~~~

    Implements cookie based sessions based on itsdangerous.

    :copyright: (c) 2015 by Armin Ronacher.
    :license: BSD, see LICENSE for more details.
é    N)Ú	b64encodeÚ	b64decode)Údatetime)Ú	http_dateÚ
parse_date)ÚCallbackDicté   )ÚMarkupÚjson)Ú	iteritemsÚ	text_type)Útotal_seconds)ÚURLSafeTimedSerializerÚBadSignaturec                   óB   — e Zd ZdZd„ Zd„ Z eee¦  «        Z[[dZdZ	dS )ÚSessionMixinzvExpands a basic dictionary with an accessors that are expected
    by Flask extensions and users for the session.
    c                 ó.   — |                       dd¦  «        S )NÚ
_permanentF)Úget©Úselfs    úD/granary/edev/quantum/lib/python3.11/site-packages/flask/sessions.pyÚ_get_permanentzSessionMixin._get_permanent   s   € Ø�xŠx˜ eÑ,Ô,Ð,ó    c                 ó*   — t          |¦  «        | d<   d S )Nr   )Úbool©r   Úvalues     r   Ú_set_permanentzSessionMixin._set_permanent!   s   € Ý! %™[œ[ˆˆ\ÑÐÐr   FTN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   ÚpropertyÚ	permanentÚnewÚmodified© r   r   r   r      s\   € € € € € ðð ð-ð -ð -ð)ð )ð )ð �˜¨Ñ8Ô8€IØ˜ð
 €Cð €H€H€Hr   r   c                 ó  — t          | t          ¦  «        rdd„ | D ¦   «         iS t          | t          j        ¦  «        r	d| j        iS t          | t
          ¦  «        r$dt          | ¦  «                             d¦  «        iS t          t          | dd ¦  «        ¦  «        r#dt          |                      ¦   «         ¦  «        iS t          | t          ¦  «        rd„ | D ¦   «         S t          | t          ¦  «        rd	t          | ¦  «        iS t          | t          ¦  «        r&t          d
„ t!          | ¦  «        D ¦   «         ¦  «        S t          | t"          ¦  «        r2	 t          | ¦  «        S # t$          $ r ddlm}  |d| z  ¦  «        ‚w xY w| S )Nú tc                 ó,   — g | ]}t          |¦  «        ‘ŒS r(   ©Ú_tag©Ú.0Úxs     r   ú
<listcomp>z_tag.<locals>.<listcomp>6   s   € Ð.Ð.Ð. 1•t˜A‘w”wÐ.Ð.Ð.r   ú uú bÚasciiÚ__html__ú mc                 ó,   — g | ]}t          |¦  «        ‘ŒS r(   r,   r.   s     r   r1   z_tag.<locals>.<listcomp>>   s   € Ð'Ð'Ð'˜A•�Q‘”Ð'Ð'Ð'r   ú dc              3   ó>   K  — | ]\  }}|t          |¦  «        fV — Œd S ©Nr,   )r/   ÚkÚvs      r   ú	<genexpr>z_tag.<locals>.<genexpr>B   s0   è è € Ð>Ð>¡T Q¨�Q�˜Q™œ�LÐ>Ð>Ð>Ð>Ð>Ð>r   r   )ÚUnexpectedUnicodeErrorzžA byte string with non-ASCII data was passed to the session system which can only store unicode strings.  Consider base64 encoding your string (String was %r))Ú
isinstanceÚtupleÚuuidÚUUIDÚhexÚbytesr   ÚdecodeÚcallableÚgetattrr   r5   Úlistr   r   Údictr   ÚstrÚUnicodeErrorÚflask.debughelpersr>   )r   r>   s     r   r-   r-   4   sÍ  € Ý�%�ÑÔð HØÐ.Ð.¨Ð.Ñ.Ô.Ð/Ð/Ý	�E�4œ9Ñ	%Ô	%ð HØ�e”iÐ Ð Ý	�E�5Ñ	!Ô	!ð HØ•i Ñ&Ô&×-Ò-¨gÑ6Ô6Ð7Ð7Ý	•'˜% ¨TÑ2Ô2Ñ	3Ô	3ð HØ•i §¢Ñ 0Ô 0Ñ1Ô1Ð2Ð2Ý	�E�4Ñ	 Ô	 ð HØ'Ð' Ð'Ñ'Ô'Ð'Ý	�E�8Ñ	$Ô	$ð HØ•i Ñ&Ô&Ð'Ð'Ý	�E�4Ñ	 Ô	 ð 
HÝÐ>Ð>­Y°uÑ-=Ô-=Ð>Ñ>Ô>Ñ>Ô>Ð>Ý	�E�3Ñ	Ô	ð Hð	HÝ˜UÑ#Ô#Ð#øÝð 	Hð 	Hð 	HØAÐAÐAÐAÐAÐAØ(Ð(ð *?ð BGñ*Gñ Hô Hð Hð	Høøøð €Ls   ÅE( Å(Fc                   ó   — e Zd ZdZd„ Zd„ ZdS )ÚTaggedJSONSerializerz“A customized JSON serializer that supports a few extra types that
    we take for granted when serializing (tuples, markup objects, datetime).
    c                 óH   — t          j        t          |¦  «        d¬¦  «        S )N)ú,ú:)Ú
separators)r   Údumpsr-   r   s     r   rS   zTaggedJSONSerializer.dumpsT   s   € ÝŒz�$˜u™+œ+°*Ð=Ñ=Ô=Ð=r   c                 ó4   — d„ }t          j        ||¬¦  «        S )Nc                 óJ  — t          | ¦  «        dk    r| S t          t          | ¦  «        ¦  «        \  }}|dk    rt          |¦  «        S |dk    rt	          j        |¦  «        S |dk    rt          |¦  «        S |dk    rt          |¦  «        S |dk    rt          |¦  «        S | S )Nr	   r*   r2   r3   r6   r8   )	ÚlenÚnextr   r@   rA   rB   r   r
   r   )ÚobjÚthe_keyÚ	the_values      r   Úobject_hookz/TaggedJSONSerializer.loads.<locals>.object_hookX   s¨   € Ý�3‰xŒx˜1Š}ˆ}Ø�
Ý!%¥i°¡n¤nÑ!5Ô!5ÑˆG�YØ˜$ŠˆÝ˜YÑ'Ô'Ð'Ø˜D’�Ý”y Ñ+Ô+Ð+Ø˜D’�Ý  Ñ+Ô+Ð+Ø˜D’�Ý˜iÑ(Ô(Ð(Ø˜D’�Ý! )Ñ,Ô,Ð,ØˆJr   )r[   )r   Úloads)r   r   r[   s      r   r\   zTaggedJSONSerializer.loadsW   s(   € ð	ð 	ð 	õ Œz˜%¨[Ð9Ñ9Ô9Ð9r   N)r    r!   r"   r#   rS   r\   r(   r   r   rN   rN   O   s<   € € € € € ðð ð>ð >ð >ð:ð :ð :ð :ð :r   rN   c                   ó   — e Zd ZdZdd„ZdS )ÚSecureCookieSessionz0Base class for sessions based on signed cookies.Nc                 óF   — d„ }t          j        | ||¦  «         d| _        d S )Nc                 ó   — d| _         d S )NT)r'   r   s    r   Ú	on_updatez/SecureCookieSession.__init__.<locals>.on_updateq   s   € Ø ˆDŒMˆMˆMr   F)r   Ú__init__r'   )r   Úinitialra   s      r   rb   zSecureCookieSession.__init__p   s1   € ð	!ð 	!ð 	!åÔ˜d G¨YÑ7Ô7Ð7ØˆŒˆˆr   r:   )r    r!   r"   r#   rb   r(   r   r   r^   r^   m   s.   € € € € € Ø:Ð:ðð ð ð ð ð r   r^   c                   ó6   — e Zd ZdZd„ ZexZxZxZxZxZ	xZ
Z[dS )ÚNullSessionz¤Class used to generate nicer error messages if sessions are not
    available.  Will still allow read-only access to the empty session
    but fail on setting.
    c                 ó    — t          d¦  «        ‚)Nz€The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.)ÚRuntimeError)r   ÚargsÚkwargss      r   Ú_failzNullSession._fail}   s   € Ýð Iñ Jô Jð 	Jr   N)r    r!   r"   r#   rj   Ú__setitem__Ú__delitem__ÚclearÚpopÚpopitemÚupdateÚ
setdefaultr(   r   r   re   re   w   s_   € € € € € ðð ð
Jð Jð Jð
 $ð$€Kð $�+ð $ ð $¨ð $¨gð $Ø�Øˆˆr   re   c                   óV   — e Zd ZdZeZdZd„ Zd„ Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zd
„ Zd„ Zd„ ZdS )ÚSessionInterfacea¶  The basic interface you have to implement in order to replace the
    default session interface which uses werkzeug's securecookie
    implementation.  The only methods you have to implement are
    :meth:`open_session` and :meth:`save_session`, the others have
    useful defaults which you don't need to change.

    The session object returned by the :meth:`open_session` method has to
    provide a dictionary like interface plus the properties and methods
    from the :class:`SessionMixin`.  We recommend just subclassing a dict
    and adding that mixin::

        class Session(dict, SessionMixin):
            pass

    If :meth:`open_session` returns ``None`` Flask will call into
    :meth:`make_null_session` to create a session that acts as replacement
    if the session support cannot work because some requirement is not
    fulfilled.  The default :class:`NullSession` class that is created
    will complain that the secret key was not set.

    To replace the session interface on an application all you have to do
    is to assign :attr:`flask.Flask.session_interface`::

        app = Flask(__name__)
        app.session_interface = MySessionInterface()

    .. versionadded:: 0.8
    Fc                 ó*   — |                       ¦   «         S )aÉ  Creates a null session which acts as a replacement object if the
        real session support could not be loaded due to a configuration
        error.  This mainly aids the user experience because the job of the
        null session is to still support lookup without complaining but
        modifications are answered with a helpful error message of what
        failed.

        This creates an instance of :attr:`null_session_class` by default.
        )Únull_session_class©r   Úapps     r   Úmake_null_sessionz"SessionInterface.make_null_session±   s   € ð ×&Ò&Ñ(Ô(Ð(r   c                 ó,   — t          || j        ¦  «        S )zÊChecks if a given object is a null session.  Null sessions are
        not asked to be saved.

        This checks if the object is an instance of :attr:`null_session_class`
        by default.
        )r?   ru   )r   rX   s     r   Úis_null_sessionz SessionInterface.is_null_session½   s   € õ ˜#˜tÔ6Ñ7Ô7Ð7r   c                 ó   — |j         d         �|j         d         S |j         d         �fd|j         d                              dd¦  «        d         z   }|dk    rd}|�0|                      |¦  «        }|d	k    r|                     d¦  «        }|S dS )
z�Helpful helper method that returns the cookie domain that should
        be used for the session cookie if session cookies are used.
        ÚSESSION_COOKIE_DOMAINNÚSERVER_NAMEú.rQ   r	   r   z
.localhostú/)ÚconfigÚrsplitÚget_cookie_pathÚlstrip)r   rw   ÚrvÚpaths       r   Úget_cookie_domainz"SessionInterface.get_cookie_domainÆ   s¤   € ð Œ:Ð-Ô.Ð:Ø”:Ð5Ô6Ð6ØŒ:�mÔ$Ð0à�s”z -Ô0×7Ò7¸¸QÑ?Ô?ÀÔBÑBˆBð
 �\Ò!Ð!Ø�ð
 ˆ~Ø×+Ò+¨CÑ0Ô0�Ø˜3’;�;ØŸš 3™œ�BàˆIð% 1Ð0r   c                 ó:   — |j         d         p|j         d         pdS )a  Returns the path for which the cookie should be valid.  The
        default implementation uses the value from the ``SESSION_COOKIE_PATH``
        config var if it's set, and falls back to ``APPLICATION_ROOT`` or
        uses ``/`` if it's ``None``.
        ÚSESSION_COOKIE_PATHÚAPPLICATION_ROOTr   ©r€   rv   s     r   r‚   z SessionInterface.get_cookie_pathà   s,   € ð ŒzÐ/Ô0ð 5ØŒzÐ,Ô-ð5Ø14ð	5r   c                 ó   — |j         d         S )z¥Returns True if the session cookie should be httponly.  This
        currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
        config var.
        ÚSESSION_COOKIE_HTTPONLYrŠ   rv   s     r   Úget_cookie_httponlyz$SessionInterface.get_cookie_httponlyé   s   € ð
 ŒzÐ3Ô4Ð4r   c                 ó   — |j         d         S )zŽReturns True if the cookie should be secure.  This currently
        just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
        ÚSESSION_COOKIE_SECURErŠ   rv   s     r   Úget_cookie_securez"SessionInterface.get_cookie_secureð   s   € ð ŒzÐ1Ô2Ð2r   c                 óJ   — |j         rt          j        ¦   «         |j        z   S dS )a  A helper method that returns an expiration date for the session
        or ``None`` if the session is linked to the browser session.  The
        default implementation returns now + the permanent session
        lifetime configured on the application.
        N)r%   r   ÚutcnowÚpermanent_session_lifetime)r   rw   Úsessions      r   Úget_expiration_timez$SessionInterface.get_expiration_timeö   s2   € ð Ôð 	FÝ”?Ñ$Ô$ sÔ'EÑEÐEð	Fð 	Fr   c                 ó@   — |j         rdS |j        d         }|o|j        S )a  Indicates whether a cookie should be set now or not.  This is
        used by session backends to figure out if they should emit a
        set-cookie header or not.  The default behavior is controlled by
        the ``SESSION_REFRESH_EACH_REQUEST`` config variable.  If
        it's set to ``False`` then a cookie is only set if the session is
        modified, if set to ``True`` it's always set if the session is
        permanent.

        This check is usually skipped if sessions get deleted.

        .. versionadded:: 0.11
        TÚSESSION_REFRESH_EACH_REQUEST)r'   r€   r%   )r   rw   r”   Ú	save_eachs       r   Úshould_set_cookiez"SessionInterface.should_set_cookieÿ   s/   € ð Ôð 	Ø�4Ø”JÐ=Ô>ˆ	ØÐ.˜WÔ.Ð.r   c                 ó   — t          ¦   «         ‚)a%  This method has to be implemented and must either return ``None``
        in case the loading failed because of a configuration error or an
        instance of a session object which implements a dictionary like
        interface + the methods and attributes on :class:`SessionMixin`.
        ©ÚNotImplementedError)r   rw   Úrequests      r   Úopen_sessionzSessionInterface.open_session  ó   € õ "Ñ#Ô#Ð#r   c                 ó   — t          ¦   «         ‚)zïThis is called for actual sessions returned by :meth:`open_session`
        at the end of the request.  This is still called during a request
        context so if you absolutely need access to the request you can do
        that.
        r›   )r   rw   r”   Úresponses       r   Úsave_sessionzSessionInterface.save_session  rŸ   r   N)r    r!   r"   r#   re   ru   Úpickle_basedrx   rz   r†   r‚   r�   r�   r•   r™   rž   r¢   r(   r   r   rs   rs   †   sÇ   € € € € € ðð ðB %Ðð €Lð
)ð 
)ð 
)ð8ð 8ð 8ðð ð ð45ð 5ð 5ð5ð 5ð 5ð3ð 3ð 3ðFð Fð Fð/ð /ð /ð$$ð $ð $ð$ð $ð $ð $ð $r   rs   c                   óT   — e Zd ZdZdZ eej        ¦  «        ZdZ	e
ZeZd„ Zd„ Zd„ ZdS )ÚSecureCookieSessionInterfacezuThe default session interface that stores sessions in signed cookies
    through the :mod:`itsdangerous` module.
    zcookie-sessionÚhmacc                 óŽ   — |j         sd S t          | j        | j        ¬¦  «        }t	          |j         | j        | j        |¬¦  «        S )N)Úkey_derivationÚdigest_method)ÚsaltÚ
serializerÚsigner_kwargs)Ú
secret_keyrI   r¨   r©   r   rª   r«   )r   rw   r¬   s      r   Úget_signing_serializerz3SecureCookieSessionInterface.get_signing_serializer4  s^   € ØŒ~ð 	Ø�4ÝØÔ.ØÔ,ð
ñ 
ô 
ˆõ & c¤n¸4¼9Ø15´Ø4AðCñ Cô Cð 	Cr   c                 óh  — |                       |¦  «        }|€d S |j                             |j        ¦  «        }|s|                      ¦   «         S t          |j        ¦  «        }	 |                     ||¬¦  «        }|                      |¦  «        S # t          $ r |                      ¦   «         cY S w xY w)N)Úmax_age)	r®   Úcookiesr   Úsession_cookie_nameÚsession_classr   r“   r\   r   )r   rw   r�   ÚsÚvalr°   Údatas          r   rž   z)SecureCookieSessionInterface.open_session?  sÂ   € Ø×'Ò'¨Ñ,Ô,ˆØˆ9Ø�4ØŒo×!Ò! #Ô"9Ñ:Ô:ˆØð 	(Ø×%Ò%Ñ'Ô'Ð'Ý Ô >Ñ?Ô?ˆð	(Ø—7’7˜3¨�7Ñ0Ô0ˆDØ×%Ò% dÑ+Ô+Ð+øÝð 	(ð 	(ð 	(Ø×%Ò%Ñ'Ô'Ð'Ð'Ð'ð	(øøøs   Á$+B ÂB1Â0B1c           	      ó  — |                       |¦  «        }|                      |¦  «        }|s&|j        r|                     |j        ||¬¦  «         d S |                      ||¦  «        sd S |                      |¦  «        }|                      |¦  «        }|                      ||¦  «        }|  	                    |¦  «         
                    t          |¦  «        ¦  «        }	|                     |j        |	|||||¬¦  «         d S )N)Údomainr…   )ÚexpiresÚhttponlyr¸   r…   Úsecure)r†   r‚   r'   Údelete_cookier²   r™   r�   r�   r•   r®   rS   rI   Ú
set_cookie)
r   rw   r”   r¡   r¸   r…   rº   r»   r¹   rµ   s
             r   r¢   z)SecureCookieSessionInterface.save_sessionM  s-  € Ø×'Ò'¨Ñ,Ô,ˆØ×#Ò# CÑ(Ô(ˆð
 ð 	ØÔð AØ×&Ò& sÔ'>Ø.4¸4ð 'ñ Aô Að AàˆFð ×%Ò% c¨7Ñ3Ô3ð 	ØˆFà×+Ò+¨CÑ0Ô0ˆØ×'Ò'¨Ñ,Ô,ˆØ×*Ò*¨3°Ñ8Ô8ˆØ×)Ò)¨#Ñ.Ô.×4Ò4µT¸'±]´]ÑCÔCˆØ×Ò˜CÔ3°SØ$+°hØ#)°¸Vð 	ñ 	Eô 	Eð 	Eð 	Eð 	Er   N)r    r!   r"   r#   rª   ÚstaticmethodÚhashlibÚsha1r©   r¨   Úsession_json_serializerr«   r^   r³   r®   rž   r¢   r(   r   r   r¥   r¥   "  s~   € € € € € ðð ð
 €Dà �L ¤Ñ.Ô.€Mð €Nð )€JØ'€Mð	Cð 	Cð 	Cð(ð (ð (ðEð Eð Eð Eð Er   r¥   ) r#   rA   r¿   Úbase64r   r   r   Úwerkzeug.httpr   r   Úwerkzeug.datastructuresr   Ú r
   r   Ú_compatr   r   Úhelpersr   Úitsdangerousr   r   Úobjectr   r-   rN   rÁ   r^   re   rs   r¥   r(   r   r   ú<module>rÊ      s  ððð ð €€€Ø €€€Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø Ð Ð Ð Ð Ð Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø Ð Ð Ð Ð Ð Ð Ð Ø )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ø "Ð "Ð "Ð "Ð "Ð "à =Ð =Ð =Ð =Ð =Ð =Ð =Ð =ðð ð ð ð �6ñ ô ð ð6ð ð ð6:ð :ð :ð :ð :˜6ñ :ô :ð :ð6 /Ð.Ñ0Ô0Ð ðð ð ð ð ˜,¨ñ ô ð ðð ð ð ð Ð%ñ ô ð ðY$ð Y$ð Y$ð Y$ð Y$�vñ Y$ô Y$ð Y$ðxHEð HEð HEð HEð HEÐ#3ñ HEô HEð HEð HEð HEr   