B
    3¢\ú'  ã               @   s’   d Z ddlZddlZyddlmZmZ W n$ ek
rL   ddlmZmZ Y nX ddlZddlm	Z	 ddl
mZmZ ddlmZ G d	d
„ d
eƒZdS )z/Tornado handlers for logging into the notebook.é    N)ÚurlparseÚ
urlunparse)Ú
url_escapeé   )Úpasswd_checkÚset_passwordé   )ÚIPythonHandlerc               @   sÆ   e Zd ZdZd"dd„Zd#dd„Zdd„ Zed	d
„ ƒZdd„ Z	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d„ƒZedd„ ƒZed d!„ ƒZdS )&ÚLoginHandlerzfThe basic tornado login handler

    authenticates with a hashed password from the configuration.
    Nc          	   C   s*   |   | jdt| jd| jdƒ|d¡ d S )Nz
login.htmlÚnext)Údefault)r   Úmessage)ÚwriteZrender_templater   Úget_argumentÚbase_url)Úselfr   © r   ú2lib/python3.7/site-packages/notebook/auth/login.pyÚ_render   s    
zLoginHandler._renderc             C   sÞ   |dkr| j }| dd¡}t|ƒ}t|jdddƒ}||ksN|jd  | j ¡sÐd}||kr¸d|j|jf }| 	¡ }|d| j
j| j
jf krd	}n(| jr¢| j|k}n| jr¸t| j |¡ƒ}|sÐ| 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Ú )ÚnetlocÚschemeú/Fz%s://%sTz!Not allowing login redirect to %r)r   Úreplacer   r   Ú_replaceÚpathÚ
startswithr   r   ÚlowerÚrequestÚprotocolZhostZallow_originZallow_origin_patÚboolÚmatchÚlogÚwarningZredirect)r   Zurlr   ZparsedZ	path_onlyZallowÚoriginr   r   r   Ú_redirect_safe!   s(    zLoginHandler._redirect_safec             C   s.   | j r"| jd| jd}|  |¡ n|  ¡  d S )Nr   )r   )Zcurrent_userr   r   r&   r   )r   Únext_urlr   r   r   ÚgetD   s    zLoginHandler.getc             C   s   |   | j¡S )N)Úpassword_from_settingsÚsettings)r   r   r   r   Úhashed_passwordK   s    zLoginHandler.hashed_passwordc             C   s
   t ||ƒS )N)r   )r   ÚaÚbr   r   r   r   O   s    zLoginHandler.passwd_checkc             C   sô   | j ddd}| j ddd}|  | j¡rÖ|  | j|¡rN|sN|  | t ¡ j¡ nˆ| j	r¸| j	|kr¸|  | t ¡ j¡ |rÖ| j 
d¡rÖ| j 
d¡}tj |d¡}t||d | j d	| ¡ n|  d
¡ | jddid d S | j d| jd}|  |¡ d S )NÚpasswordr   )r   Únew_passwordZallow_password_changeÚ
config_dirzjupyter_notebook_config.json)Úconfig_filezWrote hashed password to %si‘  ÚerrorzInvalid credentials)r   r   )r   Úget_login_availabler*   r   r+   Úset_login_cookieÚuuidÚuuid4ÚhexÚtokenr(   Úosr   Újoinr   r#   ÚinfoZ
set_statusr   r   r&   )r   Ztyped_passwordr/   r0   r1   r'   r   r   r   ÚpostR   s"    
zLoginHandler.postc             C   s`   |j  di ¡}| dd¡ |j  d|jjdk¡r<| dd¡ | d|j¡ |j|j|f|Ž |S )z9Call this on handlers to set the login cookie for successÚcookie_optionsZhttponlyTZsecure_cookieZhttpsZsecurer   )r*   r(   Ú
setdefaultr   r    r   Zset_secure_cookieÚcookie_name)ÚclsÚhandlerÚuser_idr=   r   r   r   r4   k   s    zLoginHandler.set_login_cookieztoken\s+(.+)c             C   s:   |  dd¡}|s6| j |jj dd¡¡}|r6| d¡}|S )z›Get the user token from a request

        Default:

        - in URL parameters: ?token=<token>
        - in header: Authorization: token <token>
        r8   r   ZAuthorizationr   )r   Úauth_header_patr"   r   Zheadersr(   Úgroup)r@   rA   Ú
user_tokenÚmr   r   r   Ú	get_tokenz   s    

zLoginHandler.get_tokenc             C   s   |   |¡ 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_authenticated)r@   rA   r   r   r   Úshould_check_originŒ   s    
z LoginHandler.should_check_originc             C   s$   t |ddƒdkr| ¡  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
        Ú_user_idNÚ_token_authenticatedF)ÚgetattrZget_current_user)r@   rA   r   r   r   rH   ˜   s    
z#LoginHandler.is_token_authenticatedc             C   sš   t |ddƒr|jS |  |¡}|dkrD|j di ¡}|j|jf|Ž}n|  ||¡ d|_|dkr| 	|j¡dk	r†|j
 d|j¡ | ¡  |jsd}||_|S )z”Called by handlers.get_current_user for identifying the current user.

        See tornado.web.RequestHandler.get_current_user for details.
        rJ   NÚget_secure_cookie_kwargsTz(Clearing invalid/expired login cookie %sZ	anonymous)rL   rJ   Úget_user_tokenr*   r(   Zget_secure_cookier?   r4   rK   Z
get_cookier#   r$   Zclear_login_cookieZlogin_available)r@   rA   rB   rM   r   r   r   Úget_user§   s     
zLoginHandler.get_userc             C   sP   |j }|sdS |  |¡}d}||kr:|j d|jj¡ d}|rHt ¡ jS dS dS )zžIdentify the user based on a token in the URL or Authorization header
        
        Returns:
        - uuid if authenticated
        - None if not
        NFz0Accepting token-authenticated connection from %sT)	r8   rG   r#   Údebugr   Z	remote_ipr5   r6   r7   )r@   rA   r8   rE   Zauthenticatedr   r   r   rN   Ê   s    

zLoginHandler.get_user_tokenc             C   s\   |j s@d}|dkr"|j |d ¡ |jsX|jsX|j |d ¡ n|jsX|jsX|j d¡ dS )z‡Check the notebook application's security.

        Show messages, or abort if necessary, based on the security configuration.
        z=WARNING: The notebook 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.)Zipr#   r$   r.   r8   )r@   ZappZssl_optionsr$   r   r   r   Úvalidate_securityã   s    zLoginHandler.validate_securityc             C   s   |  dd¡S )zReturn the hashed password from the tornado settings.

        If there is no configured password, an empty string will be returned.
        r.   r   )r(   )r@   r*   r   r   r   r)   ÷   s    z#LoginHandler.password_from_settingsc             C   s   t |  |¡p| d¡ƒS )z_Whether this LoginHandler is needed - and therefore whether the login page should be displayed.r8   )r!   r)   r(   )r@   r*   r   r   r   r3   ÿ   s    z LoginHandler.get_login_available)N)N)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r&   r(   Úpropertyr+   r   r<   Úclassmethodr4   ÚreÚcompileÚ
IGNORECASErC   rG   rI   rH   rO   rN   rQ   r)   r3   r   r   r   r   r
      s&   

##r
   )rU   rX   r9   Zurllib.parser   r   ÚImportErrorr5   Ztornado.escaper   Zsecurityr   r   Zbase.handlersr	   r
   r   r   r   r   Ú<module>   s   