B
    3\                 @   s   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mZmZmZ ddlmZmZmZ ddlmZ dZdd	d
Zdd ZedddZdddZdS )z'
Password generation for the Notebook.
    )contextmanagerN)
cast_bytesstr_to_bytescast_unicode)ConfigConfigFileNotFoundJSONFileConfigLoader)jupyter_config_dir   sha1c             C   s   | dkrNxDt dD ]0}td}td}||kr:|} P qtd qW tdt|}dtt d t	d	t  }|
t| d
t|d  d||| fS )a  Generate hashed password and salt for use in notebook configuration.

    In the notebook configuration, set `c.NotebookApp.password` to
    the generated string.

    Parameters
    ----------
    passphrase : str
        Password to hash.  If unspecified, the user is asked to input
        and verify a password.
    algorithm : str
        Hashing algorithm to use (e.g, 'sha1' or any argument supported
        by :func:`hashlib.new`).

    Returns
    -------
    hashed_passphrase : str
        Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.

    Examples
    --------
    >>> passwd('mypassword')
    'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'

    N   zEnter password: zVerify password: zPasswords do not match.z'No matching passwords found. Giving up.z%0x   zutf-8ascii:)rangegetpassprint
ValueErrorhashlibnewstrsalt_lenrandomZgetrandbitsupdater   r   join	hexdigest)
passphrase	algorithmiZp0Zp1hsalt r"   5lib/python3.7/site-packages/notebook/auth/security.pypasswd   s    


r$   c          	   C   s   y|  dd\}}}W n ttfk
r.   dS X yt|}W n tk
rR   dS X t|dkrddS |t|dt|d  | |kS )a  Verify that a given passphrase matches its hashed version.

    Parameters
    ----------
    hashed_passphrase : str
        Hashed password, in the format returned by `passwd`.
    passphrase : str
        Passphrase to validate.

    Returns
    -------
    valid : bool
        True if the passphrase matches the hash.

    Examples
    --------
    >>> from notebook.auth.security import passwd_check
    >>> passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
    ...              'mypassword')
    True

    >>> passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
    ...              'anotherpassword')
    False
    r      Fr   zutf-8r   )	splitr   	TypeErrorr   r   lenr   r   r   )Zhashed_passphraser   r   r!   Z	pw_digestr    r"   r"   r#   passwd_checkE   s    r)     c          
   c   s   | dkrt jt d} tt j| t j| }y| }W n tk
rX   t	 }Y nX |V  t
j| ddd}|ttj|dd W dQ R X yt | | W n> tk
r } z t }td| |f t W dd}~X Y nX dS )	zContext manager that can be used to modify a config object

    On exit of the context manager, the config will be written back to disk, 
    by default with user-only (600) permissions.
    Nzjupyter_notebook_config.jsonwutf8)encodingr%   )indentz#Failed to set permissions on %s:
%s)ospathr   r	   r   basenamedirnameZload_configr   r   ioopenwriter   jsondumpschmod	Exception	traceback
format_excwarningswarnRuntimeWarning)config_filemodeloaderconfigfetbr"   r"   r#   persist_configp   s     "rF   c          	   C   s(   t | }t|}||j_W dQ R X dS )zCAsk user for password, store it in notebook json configuration fileN)r$   rF   ZNotebookApppassword)rG   r?   Zhashed_passwordrB   r"   r"   r#   set_password   s    
rH   )Nr   )Nr*   )NN)__doc__
contextlibr   r   r   r3   r6   r/   r   r:   r<   Zipython_genutils.py3compatr   r   r   Ztraitlets.configr   r   r   Zjupyter_core.pathsr	   r   r$   r)   rF   rH   r"   r"   r"   r#   <module>   s$   
-+