Ë
    :vžjLw  ã                  ó¶  — d Z ddlmZ ddlZddlZddlZddlZddlZ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mZmZ ddlmZmZmZmZmZmZmZmZmZ ddl m!Z! dd	l"m#Z# d
dl$m%Z%m&Z& d
dl'm(Z( ejR                  rddlZ ejT                  d«      Z+ejX                  d   Z-e G d„ d«      «       Z.dd„Z/ G d„ de!«      Z0 G d„ de0«      Z1 G d„ de1«      Z2y)z®Identity Provider interface

This defines the _authentication_ layer of Jupyter Server,
to be used in combination with Authorizer for _authorization_.

.. versionadded:: 2.0
é    )ÚannotationsN)ÚasdictÚ	dataclass)ÚMorsel)ÚescapeÚhttputilÚweb)	ÚBoolÚDictÚEnumÚListÚ
TraitErrorÚTypeÚUnicodeÚdefaultÚvalidate)ÚLoggingConfigurable)Ú_i18né   )Úpasswd_checkÚset_password)Úget_anonymous_usernamez[^A-Za-z0-9]©ÚnameÚdisplay_nameÚinitialsÚ
avatar_urlÚcolorc                  ón   — e Zd ZU dZded<   dZded<   dZded<   dZded	<   dZded
<   dZ	ded<   d„ Z
d„ Zy)ÚUserziObject representing a User

    This or a subclass should be returned from IdentityProvider.get_user
    ÚstrÚusernameÚ r   r   Nú
str | Noner   r   r   c                ó$   — | j                  «        y ©N)Úfill_defaults©Úselfs    úm/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/jupyter_server/auth/identity.pyÚ__post_init__zUser.__post_init__B   s   € Ø×ÑÕó    c                ó²   — | j                   sd| › �}t        |«      ‚| j                  s| j                   | _        | j                  s| j                  | _        yy)zÑFill out default fields in the identity model

        - Ensures all values are defined
        - Fills out derivative values for name fields fields
        - Fills out null values for optional fields
        z!user.username must not be empty: N)r"   Ú
ValueErrorr   r   )r)   Úmsgs     r*   r'   zUser.fill_defaultsE   sO   € ð �}Š}Ø5°d°VÐ<ˆCÜ˜S“/Ð!ð �yŠyØŸ™ˆDŒIØ× Ò Ø $§	¡	ˆDÕð !r,   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r   r   r   r   r   r+   r'   © r,   r*   r    r    *   sO   … ñð
 ƒMð €Dˆ#ƒNð €L�#Óð  €HˆjÓØ!€J�
Ó!Ø€Eˆ:Óò
ó*r,   r    c                ó6  — t        | t        «      rt        | ¬«      S t        | t        «      r@i }d| vrd| v r| d   |d<   t        j                  D ]  }|| v sŒ| |   ||<   Œ 	 t        di |¤ŽS d| › �}t        |«      ‚# t
        $ r d| › �}t        |«      d‚w xY w)a  Backward-compatibility for LoginHandler.get_user

    Prior to 2.0, LoginHandler.get_user could return anything truthy.

    Typically, this was either a simple string username,
    or a simple dict.

    Make some effort to allow common patterns to keep working.
    )r"   r"   r   zUnrecognized user: Nr5   )Ú
isinstancer!   r    ÚdictÚ__dataclass_fields__Ú	TypeErrorr.   )Úgot_userÚkwargsÚfieldr/   s       r*   Ú_backward_compat_userr>   Y   s½   € ô �(œCÔ Ü˜XÔ&Ð&Ü	�HœdÔ	#ØˆØ˜XÑ%¨&°HÑ*<Ø!)¨&Ñ!1ˆF�:ÑÜ×.Ô.ˆEØ˜Ò Ø (¨¡��u’ð /ð	,Ü‘>˜&‘>Ð!ð
 $ H :Ð.ˆÜ˜‹oÐøô ò 	,Ø'¨ zÐ2ˆCÜ˜S“/ tÐ+ð	,ús   Á"
A= Á=Bc            	      ót  — e Zd ZU dZ edd ed«      ¬«      Zded<    ed ed«      ¬«      Z	 e
d	dd ed
«      ¬«      Zded<    ed ed«      ¬«      Z ed ed«      ¬«      j                  d¬«      Zded<    edej"                  d ed«      ¬«      Z edej"                  d ed«      ¬«      Z e e e ej0                  e«      «      «      dgd ed«      ¬«      ZdZ ed«      d„ «       Z ed«      d„ «       Z e
d«      Z d ed!<   d=d"„Z!d>d#„Z"	 	 	 	 	 	 d?d$„Z#d@d%„Z$dAd&„Z%dBd'„Z&dCd(„Z'dDd)„Z(dEd*„Z)dFd+„Z*dGd,„Z+dHd-„Z,	 dI	 	 	 	 	 	 	 	 	 dJd.„Z-dBd/„Z.	 	 	 	 d=d0„Z/ e0jb                  d1e0jd                  «      Z3dKd2„Z4d>d3„Z5dLd4„Z6dMd5„Z7dMd6„Z8	 dN	 	 	 	 	 dOd7„Z9d>d8„Z:e;d9„ «       Z<e;d:„ «       Z=e;d;„ «       Z>dPd<„Z?y	)QÚIdentityProvideraC  
    Interface for providing identity management and authentication.

    Two principle methods:

    - :meth:`~jupyter_server.auth.IdentityProvider.get_user` returns a :class:`~.User` object
      for successful authentication, or None for no-identity-found.
    - :meth:`~jupyter_server.auth.IdentityProvider.identity_model` turns a :class:`~jupyter_server.auth.User` into a JSONable dict.
      The default is to use :py:meth:`dataclasses.asdict`,
      and usually shouldn't need override.

    Additional methods can customize authentication.

    .. versionadded:: 2.0
    r#   TzJName of the cookie to set for persisting login. Default: username-${Host}.©ÚconfigÚhelpzstr | Unicode[str, str | bytes]Úcookie_nameziExtra keyword arguments to pass to `set_secure_cookie`. See tornado's set_secure_cookie docs for details.Nz–Specify whether login cookie should have the `secure` property (HTTPS-only).Only needed when protocol-detection gives the wrong answer due to proxies.)Ú
allow_nonerB   rC   z+bool | Bool[bool | None, bool | int | None]Úsecure_cookieziExtra keyword arguments to pass to `get_secure_cookie`. See tornado's get_secure_cookie docs for details.z<generated>aÔ  Token used for authenticating first-time connections to the server.

        The token can be read from the file referenced by JUPYTER_TOKEN_FILE or set directly
        with the JUPYTER_TOKEN environment variable.

        When no password is enabled,
        the default is to generate a new, random token.

        Setting to an empty string disables authentication altogether, which is NOT RECOMMENDED.

        Prior to 2.0: configured as ServerApp.token
        )rC   )rB   Útokenz*jupyter_server.auth.login.LoginFormHandlerz'The login handler class to use, if any.)Údefault_valueÚklassrB   rC   z(jupyter_server.auth.logout.LogoutHandlerz The logout handler class to use.r   z5List of fields in the User model that can be updated.)ÚtraitrH   rB   rC   Fc                óÀ  — t        j                  d«      rd| _        t         j                  d   S t        j                  d«      r=d| _        t	        t         j                  d   «      5 }|j                  «       cd d d «       S | j                  sd| _        yd| _        t        j                  t        j                  d«      «      j                  d«      S # 1 sw Y   Œ[xY w)NÚJUPYTER_TOKENFÚJUPYTER_TOKEN_FILEr#   Té   Úascii)ÚosÚgetenvÚtoken_generatedÚenvironÚopenÚreadÚ
need_tokenÚbinasciiÚhexlifyÚurandomÚdecode)r)   Ú
token_files     r*   Ú_token_defaultzIdentityProvider._token_defaultÑ   s§   € ä�9‰9�_Ô%Ø#(ˆDÔ Ü—:‘:˜oÑ.Ð.Ü�9‰9Ð)Ô*Ø#(ˆDÔ Ü”b—j‘jÐ!5Ñ6Ô7¸:Ø!—‘Ó(÷ 8Ñ7à�Šà#(ˆDÔ Øà#'ˆDÔ Ü×#Ñ#¤B§J¡J¨r£NÓ3×:Ñ:¸7ÓCÐC÷ 8Ð7ús   Á(CÃCÚupdatable_fieldsc                ó¬   — t        t        j                  t        «      «      }|d   D �cg c]	  }||vsŒ|‘Œ }}|rd|› �}t	        |«      ‚|d   S c c}w )z7Validate that all fields in updatable_fields are valid.Úvaluez$Invalid fields in updatable_fields: )ÚlistÚtÚget_argsÚUpdatableFieldr   )r)   ÚproposalÚvalid_updatable_fieldsr=   Úinvalid_fieldsr/   s         r*   Ú_validate_updatable_fieldsz+IdentityProvider._validate_updatable_fieldsâ   sn   € ô "&¤a§j¡j´Ó&@Ó!AÐà'¨Ò0ó
Ù0�e°EÐAWÒ4WŠEÐ0ð 	ð 
ñ Ø8¸Ð8HÐIˆCÜ˜S“/Ð!Ø˜Ñ Ð ùò
s
   ª	A´Azbool | Bool[bool, bool | int]rV   c                ó$   — | j                  |«      S )zèGet the authenticated user for a request

        Must return a :class:`jupyter_server.auth.User`,
        though it may be a subclass.

        Return None if the request is not authenticated.

        _may_ be a coroutine
        )Ú	_get_user©r)   Úhandlers     r*   Úget_userzIdentityProvider.get_userð   s   € ð �~‰~˜gÓ&Ð&r,   c              ƒ  ó¤  K  — t        |dd«      r t        j                  d|j                  «      S | j	                  |«      }t        |t        j                  «      r
|ƒ d{  –—† }|}| j                  |«      }t        |t        j                  «      r
|ƒ d{  –—† }|}|xs |}|� |�||k7  r| j                  ||«       d|_	        |€‚| j                  |«      }|j                  |«      }|�/| j                  j                  d|› �«       | j                  |«       | j                  s#| j!                  |«      }| j                  ||«       |S 7 Œë7 Œ¶­w)úGet the user.Ú_jupyter_current_userNr    Tz&Clearing invalid/expired login cookie )Úgetattrra   Úcastro   Úget_user_tokenr7   Ú	AwaitableÚget_user_cookieÚset_login_cookieÚ_token_authenticatedÚget_cookie_nameÚ
get_cookieÚlogÚwarningÚclear_login_cookieÚauth_enabledÚgenerate_anonymous_user)	r)   rk   Ú_token_userÚ
token_userÚ_cookie_userÚcookie_userÚuserrD   Úcookies	            r*   ri   zIdentityProvider._get_userÿ   sO  è ø€ ä�7Ð3°TÔ:ä—6‘6˜& '×"?Ñ"?Ó@Ð@Ø>B×>QÑ>QÐRYÓ>ZˆÜ�k¤1§;¡;Ô/Ø +×+ˆKØ"-ˆ
Ø×+Ñ+¨GÓ4ˆÜ�l¤A§K¡KÔ0Ø!-×-ˆLØ#/ˆð Ò(˜[ˆàÐ 
Ð 6ð �{Ò"Ø×%Ñ% g¨tÔ4ð ,0ˆGÔ(àˆ<ð ×.Ñ.¨wÓ7ˆKØ×'Ñ'¨Ó4ˆFØÐ!Ø—‘× Ñ Ð#IÈ+ÈÐ!WÔXØ×'Ñ'¨Ô0Ø×$Ò$ð ×3Ñ3°GÓ<�ð ×%Ñ% g¨tÔ4àˆðI ,øð .ús%   ‚AEÁ EÁ!6EÂEÂB5EÅEc                ó®   — | j                  |«       t        j                  d|j                  «      }| j	                  ||«      }| j                  |«       |S )z3Update user information and persist the user model.r    )Úcheck_updatera   rq   Úcurrent_userÚupdate_user_modelÚpersist_user_model)r)   rk   Ú	user_datar†   Úupdated_users        r*   Úupdate_userzIdentityProvider.update_user,  sN   € ð 	×Ñ˜)Ô$Ü—v‘v˜f g×&:Ñ&:Ó;ˆØ×-Ñ-¨l¸IÓFˆØ×Ñ Ô(ØÐr,   c                óP   — |D ]!  }|| j                   vsŒd|› d�}t        |«      ‚ y)z2Raises if some fields to update are not updatable.zField z is not updatableN)r]   r.   )r)   r‰   r=   r/   s       r*   r…   zIdentityProvider.check_update6  s3   € ãˆEØ˜D×1Ñ1Ò1Ø˜u˜gÐ%6Ð7�Ü  “oÐ%ñ r,   c                ó   — t         ‚©zUpdate user information.©ÚNotImplementedError)r)   r†   r‰   s      r*   r‡   z"IdentityProvider.update_user_model=  ó   € ä!Ð!r,   c                ó   — t         ‚)z'Persist the user model (i.e. a cookie).r�   rj   s     r*   rˆ   z#IdentityProvider.persist_user_modelA  r‘   r,   c                ó   — t        |«      S )z"Return a User as an Identity model)r   )r)   r‚   s     r*   Úidentity_modelzIdentityProvider.identity_modelE  s   € ô �d‹|Ðr,   c                ó®   — g }| j                   r|j                  d| j                  f«       | j                  r|j                  d| j                  f«       |S )zwReturn list of additional handlers for this identity provider

        For example, an OAuth callback handler.
        z/loginz/logout)Úlogin_availableÚappendÚlogin_handler_classÚlogout_availableÚlogout_handler_class)r)   Úhandlerss     r*   Úget_handlerszIdentityProvider.get_handlersJ  sN   € ð
 ˆØ×ÒØ�O‰O˜Y¨×(@Ñ(@ÐAÔBØ× Ò Ø�O‰O˜Z¨×)BÑ)BÐCÔDØˆr,   c           	     ó¶   — t        j                  |j                  |j                  |j                  |j
                  |j                  |j                  dœ«      }|S )z¿Serialize a user to a string for storage in a cookie

        If overriding in a subclass, make sure to define user_from_cookie as well.

        Default is just the user's username.
        )r"   r   r   r   r   r   )ÚjsonÚdumpsr"   r   r   r   r   r   )r)   r‚   rƒ   s      r*   Úuser_to_cookiezIdentityProvider.user_to_cookieV  sJ   € ô —‘à ŸM™MØŸ	™	Ø $× 1Ñ 1Ø ŸM™MØŸ™Ø"Ÿo™oñó	
ˆð ˆr,   c           	     óp   — t        j                  |«      }t        |d   |d   |d   |d   |d   |d   «      S )zInverse of user_to_cookier"   r   r   r   r   r   )rž   Úloadsr    )r)   Úcookie_valuer‚   s      r*   Úuser_from_cookiez!IdentityProvider.user_from_cookiej  sK   € ä�z‰z˜,Ó'ˆÜØ�ÑØ�‰LØ�Ñ Ø�ÑØ�ÑØ�‰Mó
ð 	
r,   c                óŒ   — | j                   r| j                   S t        j                  dd|j                  j                  › �«      S )zõReturn the login cookie name

        Uses IdentityProvider.cookie_name, if defined.
        Default is to generate a string taking host into account to avoid
        collisions for multiple servers on one hostname with different ports.
        Ú-z	username-)rD   Ú_non_alphanumÚsubÚrequestÚhostrj   s     r*   rw   z IdentityProvider.get_cookie_namev  s>   € ð ×ÒØ×#Ñ#Ð#ä ×$Ñ$ S¨I°g·o±o×6JÑ6JÐ5KÐ*LÓMÐMr,   c                óx  — i }|j                  | j                  «       |j                  dd«       | j                  }|€|j                  j
                  dk(  }|r|j                  dd«       |j                  d|j                  «       | j                  |«      } |j                  || j                  |«      fi |¤Ž y)z9Call this on handlers to set the login cookie for successÚhttponlyTNÚhttpsÚsecureÚpath)
ÚupdateÚcookie_optionsÚ
setdefaultrF   r©   ÚprotocolÚbase_urlrw   Úset_secure_cookier    )r)   rk   r‚   r±   rF   rD   s         r*   ru   z!IdentityProvider.set_login_cookie‚  s­   € àˆØ×Ñ˜d×1Ñ1Ô2Ø×!Ñ! *¨dÔ3ð ×*Ñ*ˆØÐ Ø#ŸO™O×4Ñ4¸Ñ?ˆMÙØ×%Ñ% h°Ô5Ø×!Ñ! &¨'×*:Ñ*:Ô;Ø×*Ñ*¨7Ó3ˆØ!ˆ×!Ñ! +¨t×/BÑ/BÀ4Ó/HÑ[ÈNÓ[r,   c                óŽ  — t        j                  |«      }t        j                  j                  t        j                  j
                  ¬«      t        j                  d¬«      z
  }t        «       }|j                  |dd«       t        j                  |«      |d<   ||d<   |r||d<   |j                  d	|j                  «       «       y
)a™  Deletes the cookie with the given name.

        Tornado's cookie handling currently (Jan 2018) stores cookies in a dict
        keyed by name, so it can only modify one cookie with a given name per
        response. The browser can store multiple cookies with the same name
        but different domains and/or paths. This method lets us clear multiple
        cookies with the same name.

        Due to limitations of the cookie protocol, you must pass the same
        path and domain to clear a cookie as were used when that cookie
        was set (but there is no way to find out on the server side
        which values were used for a given cookie).
        )Útzim  )Údaysr#   z""Úexpiresr¯   Údomainz
Set-CookieN)r   Ú
native_strÚdatetimeÚnowÚtimezoneÚutcÚ	timedeltar   Úsetr   Úformat_timestampÚ
add_headerÚOutputString)r)   rk   r   r¯   rº   r¹   Úmorsels          r*   Ú_force_clear_cookiez$IdentityProvider._force_clear_cookie’  s¥   € ô  × Ñ  Ó&ˆÜ×#Ñ#×'Ñ'¬8×+<Ñ+<×+@Ñ+@Ð'ÓAÄH×DVÑDVÐ\_ÔD`Ñ`ˆä &£ˆØ�
‰
�4˜˜TÔ"Ü$×5Ñ5°gÓ>ˆˆyÑØˆˆv‰ÙØ%ˆF�8ÑØ×Ñ˜<¨×)<Ñ)<Ó)>Õ?r,   c                óô   — i }|j                  | j                  «       |j                  d|j                  «      }| j	                  |«      }|j                  ||¬«       |r|dk7  r| j                  ||«       yyy)z<Clear the login cookie, effectively logging out the session.r¯   )r¯   Ú/N)r°   r±   r²   r´   rw   Úclear_cookierÆ   )r)   rk   r±   r¯   rD   s        r*   r{   z#IdentityProvider.clear_login_cookie­  sx   € àˆØ×Ñ˜d×1Ñ1Ô2Ø×(Ñ(¨°×1AÑ1AÓBˆØ×*Ñ*¨7Ó3ˆØ×Ñ˜[¨tÐÔ4Ù�D˜C’Kð
 ×$Ñ$ W¨kÕ:ð  ˆ4r,   c                óL  —  |j                   | j                  |«      fi | j                  ¤Ž}|sy|j                  «       }	 | j	                  |«      S # t
        $ rH}| j                  j                  d|› �d¬«       | j                  j                  d|› �«       Y d}~yd}~ww xY w)z[Get user from a cookie

        Calls user_from_cookie to deserialize cookie value
        Nz)Error unpacking user from cookie: cookie=T)Úexc_infoz"Error unpacking user from cookie: )	Úget_secure_cookierw   Úget_secure_cookie_kwargsrZ   r¤   Ú	Exceptionry   ÚdebugÚerror)r)   rk   Ú_user_cookieÚuser_cookieÚes        r*   rt   z IdentityProvider.get_user_cookie»  s¦   € ð 1�w×0Ñ0Ø× Ñ  Ó)ñ
à×+Ñ+ñ
ˆñ ØØ"×)Ñ)Ó+ˆð	Ø×(Ñ(¨Ó5Ð5øÜò 	à�H‰H�N‰NÐFÀ{ÀmÐTÐ_cˆNÔdØ�H‰H�N‰NÐ?À¸sÐCÔDÜûð		ús   ÁA Á	B#Á>BÂB#z(token|bearer)\s+(.+)c                óÒ   — |j                  dd«      }|sR| j                  j                  |j                  j                  j                  dd«      «      }|r|j                  d«      }|S )z›Get the user token from a request

        Default:

        - in URL parameters: ?token=<token>
        - in header: Authorization: token <token>
        rG   r#   ÚAuthorizationé   )Úget_argumentÚauth_header_patÚmatchr©   ÚheadersÚgetÚgroup)r)   rk   Ú
user_tokenÚms       r*   Ú	get_tokenzIdentityProvider.get_tokenÔ  s]   € ð ×)Ñ)¨'°2Ó6ˆ
Ùà×$Ñ$×*Ñ*¨7¯?©?×+BÑ+B×+FÑ+FÀÐXZÓ+[Ó\ˆAÙØŸW™W Q›Z�
ØÐr,   c              ƒ  ó†  K  — t        j                  d|j                  «      }|sy| j                  |«      }d}||k(  r2| j                  j                  d|j                  j                  «       d}|rL| j                  |«      }t        |t         j                  «      r
|ƒ d{  –—† }|}|€| j                  |«      }|S y7 Œ­w)z–Identify the user based on a token in the URL or Authorization header

        Returns:
        - uuid if authenticated
        - None if not
        r$   NFz-Accepting token-authenticated request from %sT)ra   rq   rG   rß   ry   rÏ   r©   Ú	remote_iprt   r7   rs   r}   )r)   rk   rG   rÝ   ÚauthenticatedÚ_userr‚   s          r*   rr   zIdentityProvider.get_user_tokenä  sµ   è ø€ ô —‘�| W§]¡]Ó3ˆÙØà—^‘^ GÓ,ˆ
ØˆØ˜Òà�H‰H�N‰NØ?Ø—‘×)Ñ)ôð !ˆMáð ×(Ñ(¨Ó1ˆEÜ˜%¤§¡Ô-Ø#Ÿ�Ø %ˆDØˆ|Ø×3Ñ3°GÓ<�ØˆKàð $ús   ‚B CÂ"B?Â#Cc                óÐ   — t        j                  «       j                  }t        «       }d|› �x}}d|d   › �}d}|j                  j                  d|› �«       t        ||||d|«      S )z…Generate a random anonymous user.

        For use when a single shared token is used,
        but does not identify a user.
        z
Anonymous ÚAr   Nz5Generating new user for token-authenticated request: )ÚuuidÚuuid4Úhexr   ry   rÏ   r    )r)   rk   Úuser_idÚmoonr   r   r   r   s           r*   r}   z(IdentityProvider.generate_anonymous_user  ss   € ô —*‘*“,×"Ñ"ˆÜ%Ó'ˆØ *¨4¨&Ð1Ð1ˆˆ|Ø�t˜A‘w�i�=ˆØˆØ�‰×ÑÐQÐRYÐQZÐ[Ô\Ü�G˜T <°¸4ÀÓGÐGr,   c                ó&   — | j                  |«       S )a3  Should the Handler check for CORS origin validation?

        Origin check should be skipped for token-authenticated requests.

        Returns:
        - True, if Handler must check for valid CORS origin.
        - False, if Handler should skip origin check since requests are token-authenticated.
        )Úis_token_authenticatedrj   s     r*   Úshould_check_originz$IdentityProvider.should_check_origin  s   € ð ×.Ñ.¨wÓ7Ð7Ð7r,   c                ó4   — |j                    t        |dd«      S )zÿReturns True if handler has been token authenticated. Otherwise, False.

        Login with a token is used to signal certain things, such as:

        - permit access to REST API
        - xsrf protection
        - skip origin-checks for scripts
        rv   F)r†   rp   rj   s     r*   rì   z'IdentityProvider.is_token_authenticated   s   € ð 	×ÒÜ�wÐ 6¸Ó>Ð>r,   c                ó  — |j                   sNd}|€|j                  j                  |› d�«       | j                  s|j                  j                  |› d�«       yy| j                  s|j                  j                  d«       yy)z~Check the application's security.

        Show messages, or abort if necessary, based on the security configuration.
        z<WARNING: The Jupyter server is listening on all IP addressesNz3 and not using encryption. This is not recommended.zK and not using authentication. This is highly insecure and not recommended.z`All authentication is disabled.  Anyone who can connect to this server will be able to run code.)Úipry   rz   r|   )r)   ÚappÚssl_optionsrz   s       r*   Úvalidate_securityz"IdentityProvider.validate_security-  sƒ   € ð �vŠvØTˆGØÐ"Ø—‘—‘ 7 )Ð+^Ð _Ô`Ø×$Ò$Ø—‘—‘Ø�ið  Cð Cõð %ð
 ×"Ò"Ø�G‰G�O‰OðTõð #r,   c                ó   — |j                  dd¬«      }d}| j                  s,| j                  j                  d«       | j	                  |«      S | j
                  r4| j
                  |k(  r%t        j                  d| j                  |«      «      S |S )ú_Process login form data

        Return authenticated User if successful, None if not.
        Úpasswordr#   ©r   Nú6Accepting anonymous login because auth fully disabled!r    )	r×   r|   ry   rz   r}   rG   ra   rq   Úuser_for_token)r)   rk   Útyped_passwordr‚   s       r*   Úprocess_login_formz#IdentityProvider.process_login_formE  s~   € ð
 !×-Ñ-¨jÀ"Ð-ÓEˆØˆØ× Ò Ø�H‰H×ÑÐUÔVØ×/Ñ/°Ó8Ð8à�:Š:˜$Ÿ*™*¨Ò6Ü—6‘6˜& $×"5Ñ"5°nÓ"EÓFÐFàˆr,   c                 ó   — y)zÓIs authentication enabled?

        Should always be True, but may be False in rare, insecure cases
        where requests with no auth are allowed.

        Previously: LoginHandler.get_login_available
        Tr5   r(   s    r*   r|   zIdentityProvider.auth_enabledU  s   € ð r,   c                ó   — | j                   S ©z\Whether a LoginHandler is needed - and therefore whether the login page should be displayed.©r|   r(   s    r*   r–   z IdentityProvider.login_available`  ó   € ð × Ñ Ð r,   c                 ó   — y)z"Whether a LogoutHandler is needed.Tr5   r(   s    r*   r™   z!IdentityProvider.logout_availablee  s   € ð r,   c                ó   — |S )z÷Update cookie secret input

        Subclasses may call `h.update()` with any credentials that,
        when changed, should invalidate existing cookies, such as a
        password.

        The updated hashlib object should be returned.

        r5   ©r)   Úhs     r*   Úcookie_secret_hookz#IdentityProvider.cookie_secret_hookj  s	   € ð ˆr,   )rk   úweb.RequestHandlerÚreturnz&User | None | t.Awaitable[User | None]©rk   r  r  úUser | None)rk   r  r‰   údict[UpdatableField, str]r  r    )r‰   r
  r  ÚNone©r†   r    r‰   r
  r  r    ©rk   r  r  r  )r‚   r    r  zdict[str, t.Any])r  zlist[tuple[str, object]])r‚   r    r  r!   )r£   r!   r  r	  )rk   r  r  r!   )rk   r  r‚   r    r  r  )rÈ   N)
rk   r  r   r!   r¯   r!   rº   r$   r  r  )rk   r  r  r$   )rk   r  r  r    ©rk   r  r  Úboolr&   ©rñ   út.Anyrò   zdict[str, t.Any] | Noner  r  ©r  ú	hmac.HMACr  r  )@r0   r1   r2   r3   r   r   rD   r4   r   r±   r
   rF   rÍ   ÚtagrG   r   r	   ÚRequestHandlerr˜   rš   r   r   r`   ra   rb   rc   r]   rR   r   r\   r   rg   rV   rl   ri   r‹   r…   r‡   rˆ   r”   rœ   r    r¤   rw   ru   rÆ   r{   rt   ÚreÚcompileÚ
IGNORECASErØ   rß   rr   r}   rí   rì   ró   rû   Úpropertyr|   r–   r™   r  r5   r,   r*   r@   r@   v   sÞ  … ññ  4;Ø
ØÙÐ_Ó`ô4€KÐ0ó ñ ØÙðAó
ô€Nñ BFØØØÙðYó
ô	B€MÐ>ó ñ  $ØÙðAó
ô Ðñ .5ØÙðó
ô.÷  
�c�€cÓð! 
Ð*ó ñ$ ØBØ× Ñ ØÙÐ<Ó=ô	Ðñ  Ø@Ø× Ñ ØÙÐ5Ó6ô	Ðñ Ù‘4˜
˜Ÿ
™
 >Ó2Ó3Ó4Ø�iØÙÐJÓKô	Ðð €OáˆWÓñDó ðDñ  Ð Ó!ñ	!ó "ð	!ñ 15°T³
€JÐ-Ó:ó
'ó+ðZØ)ðØ6Oðà	óó&ó"ó"óó

óó(

ó
Nó\ð" ]að@Ø)ð@Ø14ð@Ø<?ð@ØOYð@à	ó@ó6;ðØ)ðà	/óð. !�b—j‘jÐ!9¸2¿=¹=ÓI€Oóó !óFHó	8ó?ð  04ðàðð -ðð 
ó	ó0ð  ñó ðð ñ!ó ð!ð ñó ðô
r,   r@   c                  ó  ‡ — e Zd ZdZ edd ed«      ¬«      Z edd ed«      ¬«      Z edd ed«      ¬«      Z	 e
d	«      d
„ «       Z e
d«      d„ «       Zedd„«       Zedd„«       Zdd„Zdd„Zd„ Zdd„Z	 d	 	 	 	 	 dˆ fd„Zdd„Zˆ xZS )ÚPasswordIdentityProviderzA password identity provider.r#   Ta  
            Hashed password to use for web authentication.

            To generate, type in a python/IPython shell:

                from jupyter_server.auth import passwd; passwd()

            The string should be of the form type:salt:hashed-password.
            rA   Fao  
            Forces users to use a password for the Jupyter server.
            This is useful in a multi user environment, for instance when
            everybody in the LAN can access each other's machine through ssh.

            In such a case, serving on localhost is not secure since
            any user can connect to the Jupyter server via ssh.

            a�  
            Allow password to be changed at login for the Jupyter server.

            While logging in with a token, the Jupyter server UI will give the opportunity to
            the user to enter a new password at the same time that will replace
            the token login mechanism.

            This can be set to False to prevent changing password from the UI/API.
            rV   c                ó.   — t        | j                  «       S r&   )r  Úhashed_passwordr(   s    r*   Ú_need_token_defaultz,PasswordIdentityProvider._need_token_defaultª  s   € ä˜×,Ñ,Ó-Ð-Ð-r,   r]   c                ó
   — g d¢S )Nr   r5   r(   s    r*   Ú_default_updatable_fieldsz2PasswordIdentityProvider._default_updatable_fields®  s   € ò
ð 	
r,   c                ó   — | j                   S rþ   rÿ   r(   s    r*   r–   z(PasswordIdentityProvider.login_available¸  r   r,   c                óH   — t        | j                  xs | j                  «      S )z"Return whether any auth is enabled)r  r  rG   r(   s    r*   r|   z%PasswordIdentityProvider.auth_enabled½  s   € ô �D×(Ñ(Ò6¨D¯J©JÓ7Ð7r,   c                óR   — | j                   D ]  }||v sŒt        ||||   «       Œ |S rŽ   )r]   Úsetattr)r)   r†   r‰   r=   s       r*   r‡   z*PasswordIdentityProvider.update_user_modelÂ  s3   € à×*Ô*ˆEØ˜	Ò!Ü˜ e¨Y°uÑ-=Õ>ð +ð Ðr,   c                ó<   — | j                  ||j                  «       y)z#Persist the user model to a cookie.N)ru   r†   rj   s     r*   rˆ   z+PasswordIdentityProvider.persist_user_modelÉ  s   € à×Ñ˜g w×';Ñ';Õ<r,   c                ó.   — t        | j                  |«      S )z1Check password against our stored hashed password)r   r  )r)   rö   s     r*   r   z%PasswordIdentityProvider.passwd_checkÍ  s   € ä˜D×0Ñ0°(Ó;Ð;r,   c                ó†  — |j                  dd¬«      }|j                  dd¬«      }d}| j                  s,| j                  j                  d«       | j	                  |«      S | j                  |«      r|s| j	                  |«      S | j                  r°| j                  |k(  r¡| j	                  |«      }|rŽ| j                  r‚|j                  j                  dd«      }t        j                  j                  |d«      }t        ||¬	«      | _        | j                  j                  t!        d
«      j#                  |¬«      «       |S )rõ   rö   r#   r÷   Únew_passwordNrø   Ú
config_dirzjupyter_server_config.json)Úconfig_filezWrote hashed password to {file})Úfile)r×   r|   ry   rz   r}   r   rG   Úallow_password_changeÚsettingsrÛ   rP   r¯   Újoinr   r  Úinfor   Úformat)r)   rk   rú   r(  r‚   r)  r*  s          r*   rû   z+PasswordIdentityProvider.process_login_formÑ  s  € ð
 !×-Ñ-¨jÀ"Ð-ÓEˆØ×+Ñ+¨NÀBÐ+ÓGˆØˆØ× Ò Ø�H‰H×ÑÐUÔVØ×/Ñ/°Ó8Ð8à×Ñ˜^Ô,±\Ø×/Ñ/°Ó8Ð8Ø�ZŠZ˜DŸJ™J¨.Ò8Ø×/Ñ/°Ó8ˆDÙ × :Ò :Ø$×-Ñ-×1Ñ1°,ÀÓC�
Ü Ÿg™gŸl™l¨:Ð7SÓT�Ü'3°LÈkÔ'Z�Ô$Ø—‘—‘œeÐ$EÓF×MÑMÐS^ÐMÓ_Ô`àˆr,   c                ó\  •— t         ‰| �  ||«       | j                  r�| j                  s‚| j                  j                  t        d«      «       | j                  j                  t        d«      «       | j                  j                  t        d«      «       t        j                  d«       yyy)zHandle security validation.ú>Jupyter servers are configured to only be run with a password.ú1Hint: run the following command to set a passwordú)	$ python -m jupyter_server.auth passwordr   N)	Úsuperró   Úpassword_requiredr  ry   Úcriticalr   ÚsysÚexit)r)   rñ   rò   Ú	__class__s      €r*   ró   z*PasswordIdentityProvider.validate_securityé  s†   ø€ ô 	‰Ñ! # {Ô3Ø×!Ò!¨4×+?Ò+?Ø�H‰H×ÑÜÐVÓWôð �H‰H×ÑœeÐ$WÓXÔYØ�H‰H×ÑœeÐ$PÓQÔRÜ�H‰H�Q�Kð ,@Ð!r,   c                óX   — |j                  | j                  j                  «       «       |S )zpInclude password in cookie secret.

        This makes it so changing the password invalidates cookies.
        )r°   r  Úencoder  s     r*   r  z+PasswordIdentityProvider.cookie_secret_hookø  s$   € ð
 	
�‰�×%Ñ%×,Ñ,Ó.Ô/Øˆr,   ©r  r  r  r  r  r&   r  r  )r0   r1   r2   r3   r   r   r  r
   r6  r,  r   r  r   r  r–   r|   r‡   rˆ   r   rû   ró   r  Ú__classcell__)r:  s   @r*   r  r  w  sý   ø„ Ù'áØ
ØÙðó

ô€Oñ  ØØÙðó

ôÐñ  !ØØÙðó

ôÐñ  ˆ\Óñ.ó ð.ñ ÐÓ ñ
ó !ð
ð ò!ó ð!ð ò8ó ð8óó=ò<óð6 04ðàðð -ðð 
õ	÷r,   r  c                  ó¦   — e Zd ZdZ e«       Z ed«      d„ «       Z ed«      d„ «       Ze	d„ «       Z
dd„Ze	dd„«       Zdd	„Zdd
„Z	 d	 	 	 	 	 dd„Zy)ÚLegacyIdentityProviderz¢Legacy IdentityProvider for use with custom LoginHandlers

    Login configuration has moved from LoginHandler to IdentityProvider
    in Jupyter Server 2.0.
    r-  c                ó4   — | j                   | j                  dœS )N)rG   rö   )rG   r  r(   s    r*   Ú_default_settingsz(LegacyIdentityProvider._default_settings  s   € ð —Z‘ZØ×,Ñ,ñ
ð 	
r,   r˜   c                ó   — ddl m} |S )Nr   )ÚLegacyLoginHandler)ÚloginrD  )r)   rD  s     r*   Ú_default_login_handler_classz3LegacyIdentityProvider._default_login_handler_class  s   € å-à!Ð!r,   c                ó   — | j                   S r&   )r–   r(   s    r*   r|   z#LegacyIdentityProvider.auth_enabled  s   € à×#Ñ#Ð#r,   c                óT   — | j                   j                  |«      }|€yt        |«      S )rn   N)r˜   rl   r>   )r)   rk   r‚   s      r*   rl   zLegacyIdentityProvider.get_user  s+   € à×'Ñ'×0Ñ0°Ó9ˆØˆ<ØÜ$ TÓ*Ð*r,   c                ó^   — t        | j                  j                  | j                  «      «      S r&   )r  r˜   Úget_login_availabler-  r(   s    r*   r–   z&LegacyIdentityProvider.login_available#  s*   € äØ×$Ñ$×8Ñ8Ø—‘óó
ð 	
r,   c                óJ   — t        | j                  j                  |«      «      S )zWhether we should check origin.)r  r˜   rí   rj   s     r*   rí   z*LegacyIdentityProvider.should_check_origin+  s   € ä�D×,Ñ,×@Ñ@ÀÓIÓJÐJr,   c                óJ   — t        | j                  j                  |«      «      S )z#Whether we are token authenticated.)r  r˜   rì   rj   s     r*   rì   z-LegacyIdentityProvider.is_token_authenticated/  s   € ä�D×,Ñ,×CÑCÀGÓLÓMÐMr,   Nc                ón  — | j                   r�| j                  s�| j                  j                  t	        d«      «       | j                  j                  t	        d«      «       | j                  j                  t	        d«      «       t        j                  d«       | j                  j                  ||«       y)zValidate security.r2  r3  r4  r   N)	r6  r  ry   r7  r   r8  r9  r˜   ró   )r)   rñ   rò   s      r*   ró   z(LegacyIdentityProvider.validate_security3  s†   € ð ×!Ò!¨4×+?Ò+?Ø�H‰H×ÑÜÐVÓWôð �H‰H×ÑœeÐ$WÓXÔYØ�H‰H×ÑœeÐ$PÓQÔRÜ�H‰H�QŒKØ× Ñ ×2Ñ2Ø�õ	
r,   r  r=  r  r&   r  )r0   r1   r2   r3   r   r-  r   rB  rF  r  r|   rl   r–   rí   rì   ró   r5   r,   r*   r@  r@    s    „ ññ ‹v€HáˆZÓñ
ó ð
ñ Ð"Ó#ñ"ó $ð"ð
 ñ$ó ð$ó+ð ò
ó ð
óKóNð 04ð
àð
ð -ð
ð 
ô	
r,   r@  )r;   r  r  r    )3r3   Ú
__future__r   rW   r¼   Úhmacrž   rP   r  r8  Útypingra   ræ   Údataclassesr   r   Úhttp.cookiesr   Útornador   r   r	   Ú	traitletsr
   r   r   r   r   r   r   r   r   Útraitlets.configr   Újupyter_server.transutilsr   Úsecurityr   r   Úutilsr   ÚTYPE_CHECKINGr  r§   ÚLiteralrc   r    r>   r@   r  r@  r5   r,   r*   Ú<module>r[     sÄ   ðñõ #ã Û Û Û Û 	Û 	Û 
Û Û ß )Ý ç )Ñ )ß Z× ZÕ ZÝ 0å +ç 0Ý )à‡?‚?Ûà�—
‘
˜?Ó+€ð —‘ÐTÑU€ð ÷+*ð +*ó ð+*ó\ô:~Ð*ô ~ôBGÐ/ô GôTA
Ð5õ A
r,   