
    ^h                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKJr  SSKJrJr  SrSS jrS	 r\	SS
 j5       rSS jrg)z-
Password generation for the Jupyter Server.
    N)contextmanager)jupyter_config_dir)Config)ConfigFileNotFoundJSONFileConfigLoader   c                 f   U ci  [        S5       HM  n[        R                  " S5      n[        R                  " S5      nX4:X  a  Un   O&[        R                  " SSS9  MO     Sn[	        U5      eUS	:X  a-  S
SKnUR                  SSSS9nUR                  U 5      nU SU 3$ [        R                  " U5      n	S[        [        5      -   S-   [        R                  " S[        -  5      -  n
U	R                  U R                  S5      U
R                  S5      -   5        U SU
 SU	R!                  5        3$ )a[  Generate hashed password and salt for use in server configuration.

In the server configuration, set `c.ServerApp.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`, or 'argon2').

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

Examples
--------
>>> passwd("mypassword")  # doctest: +ELLIPSIS
'argon2:...'

N   zEnter password: zVerify password: zPasswords do not match.   
stacklevelz'No matching passwords found. Giving up.argon2r   i (  
      )memory_cost	time_costparallelism:z%0x   utf-8ascii)rangegetpasswarningswarn
ValueErrorr   PasswordHasherhashhashlibnewstrsalt_lenrandomgetrandbitsupdateencode	hexdigest)
passphrase	algorithm_p0p1msgr   phh_phhsalts              V/home/james-whalen/.local/lib/python3.13/site-packages/jupyter_server/auth/security.pypasswdr4      s$   4 qA!34B!45Bx
MM3B  <CS/!H"" # 

 wwz"AdV$$IA3x= 3&&*<*<Q\*JJDHHZw'$++g*>>?[$q00    c                    U R                  S5      (       a.  SSKnSSKnUR                  5       n UR	                  U SS U5      $  U R                  SS5      u  pEn [        R                  " U5      n[        U5      S:X  a  gUR                  UR                  S5      UR                  S	5      -   5        UR                  5       U:H  $ ! UR
                  R                   a     gf = f! [        [        4 a     gf = f! [         a     gf = f)
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
--------
>>> myhash = passwd("mypassword")
>>> passwd_check(myhash, "mypassword")
True

>>> passwd_check(myhash, "otherpassword")
False

>>> passwd_check("sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a", "mypassword")
True
zargon2:r   N   Fr   r   r   r   )
startswithr   argon2.exceptionsr   verify
exceptionsVerificationErrorsplitr   	TypeErrorr    r!   lenr&   r'   r(   )hashed_passphraser)   r   r/   r*   r2   	pw_digestr1   s           r3   passwd_checkrB   P   s   6 ##I.. ""$	99.qr2J??%6%<%<S!%D"	KK	" 9~HHZw'$++g*>>?;;=I%%%   22 		
 	" 
  s5   C C' C= C$#C$'C:9C:=
D
	D
c              #     #    U c(  [         R                  R                  [        5       S5      n [         R                  " [         R                  R                  U 5      SS9  [        [         R                  R                  U 5      [         R                  R                  U 5      5      n UR                  5       nUv   [        U SSS9 nUR                  [        R                  " USS	95        SSS5         [         R                  " X5        g! [         a    [        5       n Njf = f! , (       d  f       N@= f! [          a8    ["        R$                  " 5       n[&        R(                  " S
U  SU 3[*        SS9   gf = f7f)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_server_config.jsonT)exist_okwutf8)encodingr   )indentzFailed to set permissions on z:
r   )ospathjoinr   makedirsdirnamer   basenameload_configr   r   openwritejsondumpschmod	Exception	traceback
format_excr   r   RuntimeWarning)config_filemodeloaderconfigftbs         r3   persist_configr_      s     ggll#5#79UVKK,t<!"''"2"2;"?Q\A]^F##% L	k3	0A	

6!,- 
1

#  
 
1	0
  
!!#+K=B4@.]^	

sf   B$E;'D 7E;%D%+E;4D6 
E;D"E;!D""E;%
D3/E;6?E85E;7E88E;c                     [        U 5      n[        U5       nX#R                  l        SSS5        U$ ! , (       d  f       U$ = f)z:Ask user for password, store it in JSON configuration fileN)r4   r_   IdentityProviderhashed_password)passwordrY   rb   r\   s       r3   set_passwordrd      s>     X&O		$2A/ 
% 
%	$s	   2
A)Nr   )Ni  )NN)__doc__r   r    rR   rI   r$   rV   r   
contextlibr   jupyter_core.pathsr   traitlets.configr   traitlets.config.loaderr   r   r#   r4   rB   r_   rd    r5   r3   <module>rk      sZ       	    % 1 # L 61r5&p 
 
@r5   