o
    º¼tfò/  ã                   @   s„   d Z ddlZddlZddl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 G d
d„ de	ƒZG dd„ deƒZeZdS )z5Tornado handlers for logging into the Jupyter Server.é    N)Úurlparse)Ú
url_escapeé   )ÚJupyterHandleré   )Úallow_unauthenticated)Úpasswd_checkÚset_passwordc                   @   s<   e Zd ZdZddd„Zddd„Zedd„ ƒZed	d
„ ƒZdS )ÚLoginFormHandlerzlThe basic tornado login handler

    accepts login form, passed to IdentityProvider.process_login_form.
    Nc              	   C   s*   |   | jdt| jd| jdƒ|d¡ dS )zRender the login form.z
login.htmlÚnext©Údefault)r   ÚmessageN)ÚwriteZrender_templater   Úget_argumentÚbase_url)Úselfr   © r   úb/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/jupyter_server/auth/login.pyÚ_render   s   ýÿzLoginFormHandler._renderc           	      C   sæ   |du r| j }| dd¡}d|v r#| d¡\}}}|› d| d¡› }t|ƒ}|js6|js6|jd  | j ¡sld}|js>|jr`|j› d|j› }| 	¡ }| j
rT| j
|k}n| jr`tt | j|¡ƒ}|sl| j d| ¡ |}|  |¡ dS )	z¶Redirect if url is on our PATH

        Full-domain redirects are allowed if they pass our CORS origin checks.

        Otherwise use default (self.base_url if unspecified).
        Nú\z%5Cú:z://ú/Fz!Not allowing login redirect to %r)r   ÚreplaceÚ	partitionÚlstripr   ÚschemeÚnetlocÚpathÚ
startswithÚlowerZallow_originZallow_origin_patÚboolÚreÚmatchÚlogÚwarningÚredirect)	r   Úurlr   r   Ú_ÚrestÚparsedZallowÚoriginr   r   r   Ú_redirect_safe!   s(   zLoginFormHandler._redirect_safec                 C   s0   | j r| jd| jd}|  |¡ dS |  ¡  dS )zGet the login form.r   r   N)Úcurrent_userr   r   r,   r   )r   Únext_urlr   r   r   ÚgetN   s   zLoginFormHandler.getc                 C   sz   | j  | ¡ }| _|du r|  d¡ | jddid dS | j d|j› d¡ | j  | |¡ | j	d| j
d	}|  |¡ dS )
zPost a login.Né‘  ÚerrorúInvalid credentials©r   zUser z logged in.r   r   )Úidentity_providerZprocess_login_formr-   Ú
set_statusr   r$   ÚinfoÚusernameÚset_login_cookier   r   r,   )r   Úuserr.   r   r   r   ÚpostW   s   
zLoginFormHandler.post©N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r,   r   r/   r:   r   r   r   r   r
      s    


-
r
   c                   @   sº   e Zd ZdZedd„ ƒZdd„ Zedd„ ƒZe	dd	d
„ƒZ
e dej¡Ze	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	ddd„ƒZe	dd„ ƒZe	dd„ ƒZdS )ÚLegacyLoginHandlerz¤Legacy LoginHandler, implementing most custom auth configuration.

    Deprecated in jupyter-server 2.0.
    Login configuration has moved to IdentityProvider.
    c                 C   s   |   | j¡S r;   )Úpassword_from_settingsÚsettings)r   r   r   r   Úhashed_passwordm   s   z"LegacyLoginHandler.hashed_passwordc                 C   s
   t ||ƒS )zCheck a passwd.)r   )r   ÚaÚbr   r   r   r   q   s   
zLegacyLoginHandler.passwd_checkc                 C   s  | j ddd}| j ddd}|  | j¡rz|  | j|¡r'|s'|  | t ¡ j¡ nS| j	rk| j	|krk|  | t ¡ j¡ |rjt
| jddƒrj| j dd¡}tj |d¡}t| jd	ƒrbt||d
 | j_| jd< | j d| ¡ n|  d¡ | jddid dS | j d| jd}|  |¡ dS )zPost a login form.ÚpasswordÚ r   Únew_passwordZallow_password_changeFÚ
config_dirzjupyter_server_config.jsonrC   )Úconfig_filezWrote hashed password to %sr0   r1   r2   r3   Nr   )r   Úget_login_availablerB   r   rC   r8   ÚuuidÚuuid4ÚhexÚtokenÚgetattrr4   r/   Úosr   ÚjoinÚhasattrr	   r$   r6   r5   r   r   r,   )r   Ztyped_passwordrH   rI   rJ   r.   r   r   r   r:   u   s(   
ÿ€
zLegacyLoginHandler.postNc                 C   sd   |j  di ¡}| dd¡ |j  d|jjdk¡r| dd¡ | d|j¡ |j|j|fi |¤Ž |S )z9Call this on handlers to set the login cookie for successÚcookie_optionsÚhttponlyTZsecure_cookieÚhttpsÚsecurer   )rB   r/   Ú
setdefaultÚrequestÚprotocolr   Zset_secure_cookieÚcookie_name)ÚclsÚhandlerÚuser_idrT   r   r   r   r8      s   z#LegacyLoginHandler.set_login_cookieztoken\s+(.+)c                 C   s:   |  dd¡}|s| j |jj dd¡¡}|r| d¡}|S )z›Get the user token from a request

        Default:

        - in URL parameters: ?token=<token>
        - in header: Authorization: token <token>
        rO   rG   ÚAuthorizationr   )r   Úauth_header_patr#   rY   Úheadersr/   Úgroup)r\   r]   Ú
user_tokenÚmr   r   r   Ú	get_tokenŸ   s   

zLegacyLoginHandler.get_tokenc                 C   s   |   |¡ S )ú+DEPRECATED in 2.0, use IdentityProvider API)Úis_token_authenticated©r\   r]   r   r   r   Úshould_check_origin±   ó   z&LegacyLoginHandler.should_check_originc                 C   s"   t |ddƒdu r|j t |ddƒS )rf   Ú_user_idNÚ_token_authenticatedF)rP   r-   rh   r   r   r   rg   ¶   s   z)LegacyLoginHandler.is_token_authenticatedc                 C   s   t |ddƒr	|jS |  |¡}|  |¡}|p|}|r&||kr#|  ||¡ d|_|du rC| |j¡dur>|j 	d|j¡ | 
¡  |jsCd}||_|S )rf   rk   NTz(Clearing invalid/expired login cookie %sZ	anonymous)rP   rk   Úget_user_tokenÚget_user_cookier8   rl   Z
get_cookier[   r$   r%   Zclear_login_cookieZlogin_available)r\   r]   Ztoken_user_idZcookie_user_idr^   r   r   r   Úget_user¾   s"   

zLegacyLoginHandler.get_userc                 C   s2   |j  di ¡}|j|jfi |¤Ž}|r| ¡ }|S )rf   Úget_secure_cookie_kwargs)rB   r/   Zget_secure_cookier[   Údecode)r\   r]   rp   r^   r   r   r   rn   ã   s
   z"LegacyLoginHandler.get_user_cookiec                 C   st   |j }|sdS |  |¡}d}||kr|j d|jj¡ d}|r8|  |¡}|du r6t ¡ j	}|j 
d|› ¡ |S dS )rf   NFz0Accepting token-authenticated connection from %sTz8Generating new user_id for token-authenticated request: )rO   re   r$   ÚdebugrY   Z	remote_iprn   rL   rM   rN   r6   )r\   r]   rO   rc   Úauthenticatedr^   r   r   r   rm   ì   s(   
þ

ÿz!LegacyLoginHandler.get_user_tokenc                 C   sr   |j s'd}|du r|j |› d¡ |js#|js%|j |› d¡ dS dS dS |js5|js7|j d¡ dS dS dS )rf   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.)Úipr$   r%   rF   rO   )r\   ZappZssl_optionsr%   r   r   r   Úvalidate_security  s   ÿÿÿÿz$LegacyLoginHandler.validate_securityc                 C   s   |  dd¡S )rf   rF   rG   )r/   ©r\   rB   r   r   r   rA     rj   z)LegacyLoginHandler.password_from_settingsc                 C   s   t |  |¡p
| d¡ƒS )rf   rO   )r!   rA   r/   rv   r   r   r   rK   #  s   z&LegacyLoginHandler.get_login_availabler;   )r<   r=   r>   r?   ÚpropertyrC   r   r   r:   Úclassmethodr8   r"   ÚcompileÚ
IGNORECASEr`   re   ri   rg   ro   rn   rm   ru   rA   rK   r   r   r   r   r@   f   s8    





$


r@   )r?   rQ   r"   rL   Úurllib.parser   Ztornado.escaper   Zbase.handlersr   Ú	decoratorr   Úsecurityr   r	   r
   r@   ZLoginHandlerr   r   r   r   Ú<module>   s    U F