
    Mh>T                       U 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m	Z	 ddl
mZ ddlmZmZ ddlmZ ddlmZ 	 ddlZd	 Zd
 Z ej        ee            ej        de           n # e$ r 	 ddlmZ n# e$ r dZY nw xY wY nw xY wddlmZ ddl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(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1 ej2        Z3d e3D             Z4 G d d          Z5 G d de5          Z6 G d de5e+          Z7d Z8d Z9ed             Z: G d de+          Z;dd dd!iid"fiZ<d#e=d$<   e<>                    e            G d% d e          Z?e?j@        ZAeBd&k    r eA             dS dS )'zUtilities for signing notebooks    )annotationsN)OrderedDict)contextmanager)datetimetimezone)HMAC)Pathc                *    |                                  S )z8Adapt datetime.datetime to timezone-naive ISO 8601 date.)	isoformatvals    M/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/nbformat/sign.pyadapt_datetime_isor      s    }}    c                N    t          j        |                                           S )z6Convert ISO 8601 datetime to datetime.datetime object.)r   fromisoformatdecoder   s    r   convert_datetimer      s    %cjjll333r   r   )dbapi2)encodebytes)
JupyterApp
base_flags)
AnyBoolBytesCallableEnumInstanceIntegerUnicodedefaultobserve)LoggingConfigurableMultipleInstanceError   )
NO_CONVERT__version__readreadsc                <    g | ]}|                     d           |S )shake_)
startswith).0as     r   
<listcomp>r/   1   s)    FFFAq||H/E/EFaFFFr   c                  *    e Zd ZdZd Zd Zd Zd ZdS )SignatureStorez!Base class for a signature store.c                    t           )zrImplement in subclass to store a signature.

        Should not raise if the signature is already stored.
        NotImplementedErrorselfdigest	algorithms      r   store_signaturezSignatureStore.store_signature7   
    
 "!r   c                    t           )zImplement in subclass to check if a signature is known.

        Return True for a known signature, False for unknown.
        r3   r5   s      r   check_signaturezSignatureStore.check_signature>   r:   r   c                    t           )zoImplement in subclass to delete a signature.

        Should not raise if the signature is not stored.
        r3   r5   s      r   remove_signaturezSignatureStore.remove_signatureE   r:   r   c                    dS )zClose any open connections this store may use.

        If the store maintains any open connections (e.g. to a database),
        they should be closed.
        N r6   s    r   closezSignatureStore.closeL   s      r   N)__name__
__module____qualname____doc__r9   r<   r>   rB   r@   r   r   r1   r1   4   sV        ++" " "" " "" " "    r   r1   c                  4    e Zd ZdZdZd Zd Zd Zd Zd Z	dS )	MemorySignatureStorez/Non-persistent storage of signatures in memory.  c                ,    t                      | _        dS )z$Initialize a memory signature store.N)r   datarA   s    r   __init__zMemorySignatureStore.__init__Y   s      MM			r   c                    ||f}| j                             |d           d| j         |<   |                                  dS )zStore a signature.N)rK   pop_maybe_cullr6   r7   r8   keys       r   r9   z$MemorySignatureStore.store_signature_   sE    y!	c4   	#r   c                    t          | j                  | j        k     rdS t          t          | j                  dz            D ]}| j                            d           dS )zDIf more than cache_size signatures are stored, delete the oldest 25%N   F)last)lenrK   
cache_sizerangepopitem)r6   _s     r   rO   z MemorySignatureStore._maybe_cullh   sf    ty>>DO++Fs49~~*++ 	* 	*AI5))))	* 	*r   c                H    ||f}|| j         v r| j         |= d| j         |<   dS dS )zCheck a signature.NTF)rK   rP   s       r   r<   z$MemorySignatureStore.check_signaturep   s7    y!$)	#!DIcN4ur   c                @    | j                             ||fd           dS )zRemove a signature.N)rK   rN   r5   s      r   r>   z%MemorySignatureStore.remove_signaturez   s#    	vy)400000r   N)
rC   rD   rE   rF   rV   rL   r9   rO   r<   r>   r@   r   r   rH   rH   T   sj        99J" " "  * * *  1 1 1 1 1r   rH   c                       e Zd ZdZ edd                              d          Z fdZd Zd	 Z	d
 Z
d Zd Zd Zd Z xZS )SQLiteSignatureStorez'Store signatures in an SQLite database.rI   zThe number of notebook signatures to cache.
        When the number of signatures exceeds this value,
        the oldest 25% of signatures will be culled.
        helpTconfigc                |     t                      j        di | || _        |                     |          | _        dS )z!Initialize a sql signature store.Nr@   )superrL   db_file_connect_dbdb)r6   rd   kwargs	__class__s      r   rL   zSQLiteSignatureStore.__init__   s@    ""6"""""7++r   c                J    | j         | j                                          dS dS )zClose the db.N)rf   rB   rA   s    r   rB   zSQLiteSignatureStore.close   s%    7GMMOOOOO r   c                   dt           j        t           j        z  i}d }	 t          j        |fi |}|                     |           n/# t           j        t           j        f$ r |dk    r|dz   }||                                 | j        	                    d|           	 t          |                              |           t          j        |fi |}|                     |           n# t           j        t           j        t          f$ r` ||                                 | j        	                    d           d| _        t          j        di |}|                     |           Y nw xY w Y nw xY w|S )Ndetect_types:memory:z.bakzThe signatures database cannot be opened; maybe it is corrupted or encrypted. You may need to rerun your notebooks to ensure that they are trusted to run Javascript. The old signatures database has been renamed to %s and a new one has been created.zFailed committing signatures database to disk. You may need to move the database file to a non-networked file system, using config option `NotebookNotary.db_file`. Using in-memory signatures database for the remainder of this session.)rl   )sqlite3PARSE_DECLTYPESPARSE_COLNAMESconnectinit_dbDatabaseErrorOperationalErrorrB   logwarningr	   renameOSErrorrd   )r6   rd   rg   rf   old_db_locations        r   re   z SQLiteSignatureStore._connect_db   s   G3g6LL$
 !	33F33BLL%w'?@ 	 	 	*$$")F"2>HHJJJ  m $  %MM((999 ;;F;;BLL$$$$-w/GQ % % %~


H$$a   $.DL >>v>>BLL$$$$$% =	> 	s8   'A AE4"A	C,+E4,A>E-*E4,E--E43E4c                    |                     d           |                     d           |                                 dS )zInitialize the db.a  
            CREATE TABLE IF NOT EXISTS nbsignatures
            (
                id integer PRIMARY KEY AUTOINCREMENT,
                algorithm text,
                signature text,
                path text,
                last_seen timestamp
            )zb
            CREATE INDEX IF NOT EXISTS algosig ON nbsignatures(algorithm, signature)
            N)executecommit)r6   rf   s     r   rq   zSQLiteSignatureStore.init_db   sM    



	
 
	
 
	
 	

	
 	
 	

 			r   c                   | j         dS |                     ||          s<| j                             d||t          j        t
          j                  f           n;| j                             dt          j        t
          j                  ||f           | j                                          | j                             d                                          \  }|| j	        k    r| 
                                 dS dS )zStore a signature in the db.Nz}
                INSERT INTO nbsignatures (algorithm, signature, last_seen)
                VALUES (?, ?, ?)
                tzz}UPDATE nbsignatures SET last_seen = ? WHERE
                algorithm = ? AND
                signature = ?;
                z!SELECT Count(*) FROM nbsignatures)rf   r<   rz   r   nowr   utcr{   fetchonerV   cull_db)r6   r7   r8   ns       r   r9   z$SQLiteSignatureStore.store_signature   s    7?F##FI66 	GOO FHLHL$A$A$AB    GOO ...	6B   	 wBCCLLNNtLLNNNNN r   c                &   | j         dS | j                             d||f                                          }|dS | j                             dt          j        t
          j                  ||f           | j                                          dS )z!Check a signature against the db.NFzgSELECT id FROM nbsignatures WHERE
            algorithm = ? AND
            signature = ?;
            zqUPDATE nbsignatures SET last_seen = ? WHERE
            algorithm = ? AND
            signature = ?;
            r}   T)rf   rz   r   r   r   r   r   r{   )r6   r7   r8   rs       r   r<   z$SQLiteSignatureStore.check_signature   s    7?5GOO 
 
 (** 	
 95 \X\***Iv>	
 	
 	
 	tr   c                r    | j                             d||f           | j                                          dS )zRemove a signature from the db.zlDELETE FROM nbsignatures WHERE
                algorithm = ? AND
                signature = ?;
            N)rf   rz   r{   r5   s      r   r>   z%SQLiteSignatureStore.remove_signature  sC     	
 	
 	
 	r   c           	         | j                             dt          t          d| j        z            d          f           dS )zHCull oldest 25% of the trusted signatures when the size limit is reachedzDELETE FROM nbsignatures WHERE id IN (
            SELECT id FROM nbsignatures ORDER BY last_seen DESC LIMIT -1 OFFSET ?
        );
        g      ?r%   N)rf   rz   maxintrV   rA   s    r   r   zSQLiteSignatureStore.cull_db  sJ     TDO+,,a002	
 	
 	
 	
 	
r   )rC   rD   rE   rF   r   tagrV   rL   rB   re   rq   r9   r<   r>   r   __classcell__rh   s   @r   r]   r]      s        11    
cc , , , , ,  
' ' 'R  (  6  .
 
 

 
 
 
 
 
 
r   r]   c              #    K   t          | t                    r^t          |           D ]L}| |         }t          |t                    sJ |                                V  t          |          E d{V  MdS t          | t          t          f          r| D ]}t          |          E d{V  dS t          | t                    r|                     d          V  dS t          |                               d          V  dS )zYield every item in a container as bytes

    Allows any JSONable object to be passed to an HMAC digester
    without having to serialize the whole thing.
    Nutf8)
isinstancedictsortedstrencodeyield_everythinglisttuple)objrQ   valueelements       r   r   r     s7      #t &#;; 	/ 	/CHEc3'''''**,,'..........		/ 	/
 
C$	'	' & 	1 	1G'0000000000	1 	1	C		 &jj       #hhoof%%%%%%%r   c              #     K   | j         dk    r| d         D ]}|d         dk    r|V  dS | j         dk    r&| d         D ]}|d         D ]}|d         dk    r|V  dS dS )zSIterator that yields all cells in a notebook

    nbformat version independent
    rS   cells	cell_typecode   
worksheetsN)nbformat)nbcellwss      r   yield_code_cellsr   1  s      
 
{awK 	 	DK F**


	 	 
		\" 	 	B7  $..JJJ 
		 	r   c              #     K   | d                              dd          }	 dV  ||| d         d<   dS dS # ||| d         d<   w xY w)zContext manager for operating on a notebook with its signature removed

    Used for excluding the previous signature when computing a notebook's signature.
    metadata	signatureN)rN   )r   save_signatures     r   signature_removedr   A  sq       
^''T::N9%*8BzN;''' &%>%*8BzN;'8888s	   5 Ac                      e Zd Z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             Z eedd                              d          Z ed          d             Z e            Z ed          d             Z ed                              d          Z ed          d             Z ed                              d          Z ed          d             Z fdZd Zd Zd Zd Zd  Z d! Z!d" Z"d# Z# xZ$S )$NotebookNotaryz8A class for computing and verifying notebook signatures.z5The storage directory for notary secret and database.r^   Tr`   data_dirc                    d }	 t          j                    rt          j                    }n# t          $ r Y nw xY w|$t                      }|                    g            |j        S )N)argv)r   initializedinstancer$   
initializer   )r6   apps     r   _data_dir_defaultz NotebookNotary._data_dir_defaultV  sv    	%'' , )++$ 	 	 	D	;,,CNNN###|s   &+ 
88zoA callable returning the storage backend for notebook signatures.
         The default uses an SQLite database.store_factoryc                      fd}|S )Nc                     t           ( j                            d           t                      S t	           j                  S )Nz1Missing SQLite3, all notebooks will be untrusted!)rm   rt   ru   rH   r]   rd   rA   s   r   factoryz6NotebookNotary._store_factory_default.<locals>.factoryk  sC      G   ,---'555r   r@   )r6   r   s   ` r   _store_factory_defaultz%NotebookNotary._store_factory_defaulti  s#    	6 	6 	6 	6 	6 r   zThe sqlite file in which to store notebook signatures.
        By default, this will be in your Jupyter data directory.
        You can set it to ':memory:' to disable sqlite writing to the filesystem.
        rd   c                \    | j         sdS t          t          | j                   dz            S )Nrl   znbsignatures.dbr   r   r	   rA   s    r   _db_file_defaultzNotebookNotary._db_file_default|  s/    } 	:4&&)::;;;r   sha256z-The hashing algorithm used to sign notebooks.)default_valuer_   r8   c                F    t          t          |d                   | _        d S )Nnew)getattrhashlib	digestmod)r6   changes     r   _algorithm_changedz!NotebookNotary._algorithm_changed  s     &-88r   r   c                6    t          t          | j                  S )N)r   r   r8   rA   s    r   _digestmod_defaultz!NotebookNotary._digestmod_default  s    w///r   z(The file where the secret key is stored.secret_filec                \    | j         sdS t          t          | j                   dz            S )N notebook_secretr   rA   s    r   _secret_file_defaultz#NotebookNotary._secret_file_default  s/    } 	24&&)::;;;r   z/The secret key with which notebooks are signed.secretc                h   t          | j                                                  rUt          | j                                      d          5 }|                                cd d d            S # 1 swxY w Y   d S t          t          j        d                    }|                     |           |S )Nrb   )	r	   r   existsopenr(   r   osurandom_write_secret_file)r6   fr   s      r   _secret_defaultzNotebookNotary._secret_default  s      !!((** 	d&'',,T22  avvxx                                    !D!1!122F##F+++Ms   A//A36A3c                l     t                      j        di | |                                 | _        dS )zInitialize the notary.Nr@   )rc   rL   r   store)r6   rg   rh   s     r   rL   zNotebookNotary.__init__  s7    ""6"""''))


r   c                   | j                             d| j                   t          | j                                      d          5 }|                    |           ddd           n# 1 swxY w Y   	 t          | j                                      d           n0# t          $ r# | j                             d| j                   Y nw xY w|S )z!write my secret to my secret_filez"Writing notebook-signing key to %swbNi  zCould not set permissions on %s)	rt   infor   r	   r   writechmodrw   ru   )r6   r   r   s      r   r   z!NotebookNotary._write_secret_file  s
   :D<LMMM$"##((.. 	!GGFOOO	 	 	 	 	 	 	 	 	 	 	 	 	 	 		R!""((//// 	R 	R 	RH>@PQQQQQ	Rs$   A**A.1A.6'B *C
Cc                    t          | j        | j                  }t          |          5  t	          |          D ]}|                    |           	 ddd           n# 1 swxY w Y   |                                S )zpCompute a notebook's signature

        by hashing the entire contents of the notebook via HMAC digest.
        )r   N)r   r   r   r   r   update	hexdigest)r6   r   hmacbs       r   compute_signaturez NotebookNotary.compute_signature  s    
 DK4>:::r"" 	 	%b))  A	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
 ~~s   (A  A$'A$c                    |j         dk     rdS |                     |          }| j                            || j                  S )aM  Check a notebook's stored signature

        If a signature is stored in the notebook's metadata,
        a new signature is computed and compared with the stored value.

        Returns True if the signature is found and matches, False otherwise.

        The following conditions must all be met for a notebook to be trusted:
        - a signature is stored in the form 'scheme:hexdigest'
        - the stored scheme matches the requested scheme
        - the requested scheme is available from hashlib
        - the computed hash from notebook_signature matches the stored hash
        r   F)r   r   r   r<   r8   r6   r   r   s      r   r<   zNotebookNotary.check_signature  sA     ;??5**2..	z)))T^DDDr   c                    |j         dk     rdS |                     |          }| j                            || j                   dS )zSign a notebook, indicating that its output is trusted on this machine

        Stores hash algorithm and hmac digest in a local database of trusted notebooks.
        r   N)r   r   r   r9   r8   r   s      r   signzNotebookNotary.sign  sG    
 ;??F**2..	
""9dn=====r   c                p    |                      |          }| j                            || j                   dS )zvEnsure that a notebook is untrusted

        by removing its signature from the trusted database, if present.
        N)r   r   r>   r8   r   s      r   unsignzNotebookNotary.unsign  s7    
 **2..	
##It~>>>>>r   c                Z    |j         dk     rdS t          |          D ]}||d         d<   dS )aJ  Mark cells as trusted if the notebook's signature can be verified

        Sets ``cell.metadata.trusted = True | False`` on all code cells,
        depending on the *trusted* parameter. This will typically be the return
        value from ``self.check_signature(nb)``.

        This function is the inverse of check_cells
        r   Nr   trusted)r   r   r6   r   r   r   s       r   
mark_cellszNotebookNotary.mark_cells  sG     ;??F$R(( 	2 	2D*1DY''	2 	2r   c                    |d                              dd          rdS |dk    r	ddg}h d}nd	dg}h d
}|d         D ]5}|d         }||v r't          |          }|                    |          r dS 6dS )a  Do we trust an individual cell?

        Return True if:

        - cell is explicitly trusted
        - cell has no potentially unsafe rich output

        If a cell has no output, or only simple print statements,
        it will always be trusted.
        r   r   FTrS   execute_resultdisplay_data>   r   output_typeexecution_countpyout>   r   r   prompt_numberoutputsr   )rN   set
difference)r6   r   nbformat_versionunsafe_output_types	safe_keysoutputr   output_keyss           r   _check_cellzNotebookNotary._check_cell  s     
	511 	4 q  #3^"DFFFII#*N";DDDI9o 	! 	!F /K111!&kk)))44 ! 55tr   c                    |j         dk     rdS d}t          |          D ]}|                     ||j                   sd} |S )a  Return whether all code cells are trusted.

        A cell is trusted if the 'trusted' field in its metadata is truthy, or
        if it has no potentially unsafe outputs.
        If there are no code cells, return True.

        This function is the inverse of mark_cells.
        r   FT)r   r   r   r   s       r   check_cellszNotebookNotary.check_cells  sU     ;??5$R(( 	  	 D##D"+66  r   )%rC   rD   rE   rF   r    r   r   r!   r   r   r   r   rd   r   r   
algorithmsr8   r"   r   r   r   r   r   r   r   r   r   rL   r   r   r<   r   r   r   r   r   r   r   s   @r   r   r   O  s       BBwWXXX\\ ]  H WZ   H1   
cc 
 W_	 	 	 g  
 
cc  WY< < <
 @   
cc	  W[9 9 9 IW[0 0 0 'MNNNRRZ^R__KW]< < <
 UMNNNRRZ^R__FWX  * * * * *
	 	 	     E E E&> > >? ? ?2 2 2  B      r   r   resetTrustNotebookAppTzjDelete the trusted notebook cache.
        All previously signed notebooks will become untrusted.
        zdict[str, t.Any]trust_flagsc                      e Zd ZdZeZdZ ed          d             ZdZ	e
Z edd                              d	
          Z ee          Z ed          d             Zd ZddZd Zd ZdS )r  z+An application for handling notebook trust.zSign one or more Jupyter notebooks with your key,
    to trust their dynamic (HTML, Javascript) output.

    Otherwise, you will have to re-execute the notebook to see output.
    config_file_namec                    dS )Njupyter_notebook_configr@   rA   s    r   _config_file_name_defaultz*TrustNotebookApp._config_file_name_defaultD  s    ((r   z;
    jupyter trust mynotebook.ipynb and_this_one.ipynb
    FzIf True, delete the trusted signature cache.
        After reset, all previously signed notebooks will become untrusted.
        r^   Tr`   notaryc                .    t          | | j                  S )N)parentr   )r   r   rA   s    r   _notary_defaultz TrustNotebookApp._notary_defaultW  s    TDMBBBBr   c                t   t          |                                          s0| j                            d|           |                     d           t          |                              d          5 }t          |t                    }ddd           n# 1 swxY w Y   |                     ||           dS )z#Sign a notebook from the filesystemzNotebook missing: %sr%   r   )encodingN)	r	   r   rt   errorexitr   r(   r&   sign_notebook)r6   notebook_pathr   r   s       r   sign_notebook_filez#TrustNotebookApp.sign_notebook_file[  s    M""))++ 	HNN1=AAAIIaLLL-  %%v%66 	%!a$$B	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	%2}-----s   5BBB<stdin>c                    | j                             |          rt          d|z             dS t          d|z             | j                             |           dS )z"Sign a notebook that's been loadedzNotebook already signed: %szSigning notebook: %sN)r	  r<   printr   )r6   r   r  s      r   r  zTrustNotebookApp.sign_notebookd  sd    ;&&r** 	!/-?@@@@@(=8999KR     r   c                    t          d| j        j        z             | j                            t	          j        d                     dS )z%Generate a new notebook signature keyzGenerating new notebook key: %sr   N)r  r	  r   r   r   r   rA   s    r   generate_new_keyz!TrustNotebookApp.generate_new_keyl  sA    /$+2IIJJJ&&rz$'7'788888r   c                h   | j         rt          | j        j                                                  rGt          d| j        j        z             t          | j        j                                                   |                                  dS | j        s|| j	        
                    d           t          j                                        }t          |t                    sJ t!          |t"                    }|                     |d           dS | j        D ]}|                     |           dS )zStart the trust notebook app.z$Removing trusted signature cache: %sNzReading notebook from stdinr  )r  r	   r	  rd   r   r  unlinkr  
extra_argsrt   debugsysstdinr(   r   r   r)   r&   r  r  )r6   nb_sr   r  s       r   startzTrustNotebookApp.startq  s   : 	DK'((//11 3<t{?RRSSST[())00222!!###F 	7HNN89999>>##DdC(((((tZ((Br9-----!% 7 7''66667 7r   N)r  )rC   rD   rE   rF   r'   versiondescriptionr!   r  examplesr  flagsr   r   r  r   r   r	  r  r  r  r  r   r@   r   r   r  r  9  s       55GK W  ) ) ! )H ED  
 
cc 
 Xn%%FWXC C C. . .! ! ! !9 9 9
7 7 7 7 7r   __main__)CrF   
__future__r   r   r   r  typingtcollectionsr   
contextlibr   r   r   r   r   pathlibr	   rm   r   r   register_adapterregister_converterImportError	pysqlite2r   base64r   jupyter_core.applicationr   r   	traitletsr   r   r   r   r   r   r   r    r!   r"   traitlets.configr#   r$   r   r&   r'   r(   r)   algorithms_guaranteedalgorithms_setr   r1   rH   r]   r   r   r   r   r  __annotations__r   r  launch_instancemainrC   r@   r   r   <module>r9     s   % % % # " " " " "  				 



     # # # # # # % % % % % % ' ' ' ' ' ' ' '            NNN  4 4 4 GX'9:::Gz+;<<<<   ///////          ; ; ; ; ; ; ; ; d d d d d d d d d d d d d d d d d d d d d d d d G G G G G G G G 2 2 2 2 2 2 2 2 2 2 2 2. GFFFF
       @(1 (1 (1 (1 (1> (1 (1 (1VZ
 Z
 Z
 Z
 Z
>+> Z
 Z
 Z
z& & &*    
9 
9 
9\ \ \ \ \( \ \ \@ 	gt_-	!       :   H7 H7 H7 H7 H7z H7 H7 H7V 'zDFFFFF s5   ,A( (B.A54B5A?<B>A??BB