
    AHj6                        d 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 	 ej                  Z ej                  e      Zd Zd Z G d	 d
e      Z G d de      Z G d de      Z G d de      Zd Z G d de      Zd Z G d de      Z G d de      Z G d de      Z G d de      Zy# e	$ r	 ddl
mZ Y w xY w# e$ r  ej                  defddi      ZY w xY w)aP  A generic persistence layer, optionally encrypted on Windows, OSX, and Linux.

Should a certain encryption is unavailable, exception will be raised at run-time,
rather than at import time.

By successfully creating and using a certain persistence object,
app developer would naturally know whether the data are protected by encryption.
    N)PathABC	__slots__ c                 4   | syt         j                  dk\  rt        j                  | d       y	 t        j                  |        y# t        $ rH}|j
                  t
        j                  k(  r t        j                  j                  |       rn Y d}~yd}~ww xY w)zCreates a directory, and any necessary parents.

    If the path provided is an existing file, this function raises an exception.
    :param path: The directory name that should be created.
    N)      T)exist_ok)	sysversion_infoosmakedirsOSErrorerrnoEEXISTpathisdir)r   exps     S/root/tools/cai/cai_env/lib/python3.12/site-packages/msal_extensions/persistence.py_mkdir_pr      st     
6!
D4(

D 99$t)< s   A 	B>BBc                 f    t        j                  | j                  d            j                         S )Nzutf-8)hashlibsha256encode	hexdigest)input_strings    r   
_auto_hashr   6   s%    >>,--g67AACC    c                   $     e Zd ZdZd fd	Z xZS )PersistenceErrorz#The base exception for persistence.c                 0    t         t        |   |||       y N)superr    __init__selferr_nomessagelocation	__class__s       r   r$   zPersistenceError.__init__C   s    .vwIr   NNN__name__
__module____qualname____doc__r$   __classcell__r*   s   @r   r    r    =   s    -
J Jr   r    c                   $     e Zd ZdZd fd	Z xZS )PersistenceNotFoundzZThis happens when attempting BasePersistence.load() on a non-existent persistence instancec                 V    t         t        |   t        j                  |xs d|       y )NzPersistence not foundr'   r(   r)   )r#   r4   r$   r   ENOENTr%   s       r   r$   zPersistenceNotFound.__init__I   s+    !41<<66 	2 	r   r+   r,   r2   s   @r   r4   r4   G   s    d r   r4   c                       e Zd ZdZy)PersistenceEncryptionErrorz*This could be raised by persistence.save()Nr-   r.   r/   r0   r   r   r   r9   r9   O       4r   r9   c                       e Zd ZdZy)PersistenceDecryptionErrorz*This could be raised by persistence.load()Nr:   r   r   r   r=   r=   R   r;   r   r=   c                 N   t         j                  j                  d      rt        |       S t         j                  j                  d      rt	        |       S t         j                  j                  d      rt        |       S t        dj                  t         j                              )zBuild a suitable encrypted persistence instance based your current OS.

    If you do not need encryption, then simply use ``FilePersistence`` constructor.
    windarwinlinuxzUnsupported platform: {})r   platform
startswith!FilePersistenceWithDataProtectionKeychainPersistenceLibsecretPersistenceRuntimeErrorformatr)   s    r   build_encrypted_persistencerJ   V   sv     ||u%0::
||x("8,,
||w'#H--
188F
GGr   c                       e Zd ZdZdZej                  d        Zej                  d        Zej                  d        Z	ej                  d        Z
y)BasePersistencezDAn abstract persistence defining the common interface of this familyFc                     t         )&Save the content into this persistenceNotImplementedErrorr&   contents     r   savezBasePersistence.savek   s
     "!r   c                     t         )zuLoad content from this persistence.

        Could raise PersistenceNotFound if no save() was called before.
        rO   r&   s    r   loadzBasePersistence.loadq   s
     "!r   c                     t         )zGet the last time when this persistence has been modified.

        Could raise PersistenceNotFound if no save() was called before.
        rO   rU   s    r   time_last_modifiedz"BasePersistence.time_last_modifiedz   s
     "!r   c                     t         )zBReturn the file path which this persistence stores (meta)data intorO   rU   s    r   get_locationzBasePersistence.get_location   s
     "!r   N)r-   r.   r/   r0   is_encryptedabcabstractmethodrS   rV   rX   rZ   r   r   r   rL   rL   f   sp    NL" "
 	" " 	" " 	" "r   rL   c                     t        j                  | t         j                  t         j                  z  t         j                  z  d      S )Ni  )r   openO_RDWRO_CREATO_TRUNCrI   s    r   _openrc      s+    778RYY3bjj@%HHr   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	FilePersistencez8A generic persistence, storing data in a plain-text filec                     |st        d      t        j                  j                  |      | _        t        t        j                  j                  | j                               y )NzRequires a file path)
ValueErrorr   r   
expanduser	_locationr   dirname)r&   r)   s     r   r$   zFilePersistence.__init__   s@    344++H501r   c                     t        j                  t        | j                        d      5 }|j	                  |       ddd       y# 1 sw Y   yxY w)rN   zw+N)r   fdopenrc   ri   write)r&   rR   handles      r   rS   zFilePersistence.save   s>     YYuT^^,d3 	"vLL!	" 	" 	"s   AAc                    	 t        | j                  d      5 }|j                         cddd       S # 1 sw Y   yxY w# t        $ r:}|j                  t        j
                  k(  rt        d| j                         d}~ww xY w)z"Load content from this persistencerNGPersistence not initialized. You can recover by calling a save() first.r(   r)   )r_   ri   readEnvironmentErrorr   r7   r4   )r&   rn   r   s      r   rV   zFilePersistence.load   ss    	dnnc* %f{{}% % % 	yyELL()E!^^	  	s)   > 2	> ;> > 	B5A<<Bc                     	 t         j                  j                  | j                        S # t        $ r:}|j
                  t
        j                  k(  rt        d| j                         d }~ww xY w)Nrq   rr   )r   r   getmtimeri   rt   r   r7   r4   )r&   r   s     r   rX   z"FilePersistence.time_last_modified   s_    
	77##DNN33 	yyELL()E!^^	  	s   (+ 	A.5A))A.c                 J    t        | j                        j                          y)zDTo touch this file-based persistence without writing content into itN)r   ri   touchrU   s    r   rx   zFilePersistence.touch   s    T^^""$r   c                     | j                   S r"   )ri   rU   s    r   rZ   zFilePersistence.get_location   s    ~~r   N)
r-   r.   r/   r0   r$   rS   rV   rX   rx   rZ   r   r   r   re   re      s#    B2""%r   re   c                   4     e Zd ZdZdZd fd	Zd Zd Z xZS )rD   zcA generic persistence with data stored in a file,
    protected by Win32 encryption APIs on WindowsTc                 T    ddl m}  ||      | _        t        t        |   |       y)z7Initialization could fail due to unsatisfied dependency   )WindowsDataProtectionAgent)entropyN)windowsr}   	_dp_agentr#   rD   r$   )r&   r)   r~   r}   r*   s       r   r$   z*FilePersistenceWithDataProtection.__init__   s$     	83GD/?Ir   c                 J   	 | j                   j                  |      }t        j                  t        | j                        d      5 }|j                  |       d d d        y # t        $ r,}t        t	        |dd       dj                  |            d }~ww xY w# 1 sw Y   y xY w)Nwinerrorz2Encryption failed: {} Consider disable encryption.)r'   r(   zwb+)r   protectr   r9   getattrrH   r   rl   rc   ri   rm   )r&   rR   data	exceptionrn   s        r   rS   z&FilePersistenceWithDataProtection.save   s    	>>))'2D YYuT^^,e4 	LL	 	  	,y*d;LSST]^ 	
	 	s#   A! B!	B*'BBB"c                    	 t        | j                  d      5 }|j                         }d d d        	 | j                  j                        S # 1 sw Y   %xY w# t        $ rO}|j                  t        j
                  k(  rt        d| j                        t        j                  d        d }~ww xY w# t        $ r7}t        t        |dd       dj                  |      | j                        d }~ww xY w)Nrbrq   rr   zDPAPI error likely caused by file content not previously encrypted. App developer should migrate by calling save(plaintext) first.r   zDecryption failed: {} App developer may consider this guidance: https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/PersistenceDecryptionErrorr6   )r_   ri   rs   rt   r   r7   r4   loggerr   r   	unprotectr   r=   r   rH   )r&   rn   r   r   r   s        r   rV   z&FilePersistenceWithDataProtection.load   s    	dnnd+ %v{{}%
	>>++D11% % 	yyELL()E!^^	  QR 	  	,y*d;@ VI& 	sE   A AA B4 AA 	B1"A
B,,B14	C4=2C//C4) )	r-   r.   r/   r0   r[   r$   rS   rV   r1   r2   s   @r   rD   rD      s    5LJ
r   rD   c                   4    e Zd ZdZdZd	dZd Zd Zd Zd Z	y)
rE   z`A generic persistence with data stored in,
    and protected by native Keychain libraries on OSXTNc                     ddl m}m} t        |      | _        || _        || _        d}|xs || _        |xs t        |      | _	        y)zInitialization could fail due to unsatisfied dependency.

        :param signal_location: See :func:`persistence.LibsecretPersistence.__init__`
        r|   )KeychainKeychainErrorzmsal-extensionsN)
osxr   r   re   _file_persistence	_Keychain_KeychainError_service_namer   _account_name)r&   signal_locationservice_nameaccount_namer   r   default_service_names          r   r$   zKeychainPersistence.__init__   sI    
 	1!0!A!+0)A-A)HZ-Hr   c                     | j                         5 }|j                  | j                  | j                  |       d d d        | j                  j                          y # 1 sw Y   $xY wr"   )r   set_generic_passwordr   r   r   rx   )r&   rR   lockers      r   rS   zKeychainPersistence.save
  s]    ^^ 	A''""D$6$6A	A 	$$&	A 	As   (AA%c                 t   | j                         5 }	 |j                  | j                  | j                        cd d d        S # | j                  $ rZ}|j
                  | j                  j                  k(  r1t        dj                  | j                  | j                        d       d }~ww xY w# 1 sw Y   y xY w)NzService:{} Account:{}zMKeychain persistence not initialized. You can recover by call a save() first.)r)   r(   )	r   get_generic_passwordr   r   r   exit_statusITEM_NOT_FOUNDr4   rH   )r&   r   exs      r   rV   zKeychainPersistence.load  s    ^^ 	22&&(:(:<	 	 && >>T%8%8%G%GG .!8!?!? ..0B0B"DF	  		 	s)   B.%AB+AB&&B++B..B7c                 6    | j                   j                         S r"   r   rX   rU   s    r   rX   z&KeychainPersistence.time_last_modified"      %%88::r   c                 6    | j                   j                         S r"   r   rZ   rU   s    r   rZ   z KeychainPersistence.get_location%      %%2244r   NN
r-   r.   r/   r0   r[   r$   rS   rV   rX   rZ   r   r   r   rE   rE      s&    9LI'$;5r   rE   c                   4    e Zd ZdZdZd	dZd Zd Zd Zd Z	y)
rF   zcA generic persistence with data stored in,
    and protected by native libsecret libraries on LinuxTNc                     ddl m}m}  |         ||xs t        |      |xs i fi || _        t        |      | _        y)aQ  Initialization could fail due to unsatisfied dependency.

        :param string signal_location:
            Besides saving the real payload into encrypted storage,
            this class will also touch this signal file.
            Applications may listen a FileSystemWatcher.Changed event for reload.
            https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.changed?view=netframework-4.8#remarks
        :param string schema_name: See :func:`libsecret.LibSecretAgent.__init__`
        :param dict attributes: See :func:`libsecret.LibSecretAgent.__init__`
        r|   )LibSecretAgent	trial_runN)	libsecretr   r   r   _agentre   r   )r&   r   schema_name
attributeskwargsr   r   s          r   r$   zLibsecretPersistence.__init__.  sC    	'$6:o6
8HbTLRT!0!Ar   c                 p    | j                   j                  |      r| j                  j                          y y r"   )r   rS   r   rx   rQ   s     r   rS   zLibsecretPersistence.saveA  s+    ;;G$""((* %r   c                 V    | j                   j                         }|t        d      |S )NzLKeyring persistence not initialized. You can recover by call a save() first.)r(   )r   rV   r4   )r&   r   s     r   rV   zLibsecretPersistence.loadE  s4    {{!< &:< < r   c                 6    | j                   j                         S r"   r   rU   s    r   rX   z'LibsecretPersistence.time_last_modifiedO  r   r   c                 6    | j                   j                         S r"   r   rU   s    r   rZ   z!LibsecretPersistence.get_locationR  r   r   r   r   r   r   r   rF   rF   )  s&    <LB&+;5r   rF   ) r0   r\   r   r   r   loggingr   pathlibr   ImportErrorpathlib2r   AttributeErrorABCMetaobject	getLoggerr-   r   r   r   IOErrorr    r4   r9   r=   rJ   rL   rc   re   rD   rE   rF   r   r   r   <module>r      s    	    

;
''C
 
		8	$0DJw J* 5!1 55!1 5H "c "DI
2o 2j3 3l.5/ .5b*5? *5q    ;
#++efYb(9
:C;s"   B1 C 1B?>B?C! C!