
    0jUg                         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 ddl	m
Z
mZ ddlmZ  ej        e          ZdZ eh d          Zd Zd	 Zd
 Z G d de          Z G d de          ZdS )    N   )canonicalize)decode_partdecode_id_token)Clientbroker>   codescopeclaimskey_idreq_cnfuser_idpasswordusername	assertion	client_id
grant_type
token_typeclient_infodevice_coderedirect_uriclient_secretcode_verifierrefresh_tokenclient_assertionrequested_token_useclient_assertion_type"user_federated_identity_credentialc                    | sdS d |                                  D             sdS d                    fdt                                                    D                       }t	          j        |                    d                                                    }t          j	        |          
                    d                              d                                          S )a2  Compute an extended cache key hash from extra body parameters in *data*.

    All fields in *data* that go on the wire are included in the hash,
    EXCEPT those listed in ``_EXT_CACHE_KEY_EXCLUDED_FIELDS``.
    This ensures tokens acquired with different parameter values
    (e.g., different FMI paths) are cached separately.

    Returns an empty string when *data* has no hashable fields.

    The algorithm matches the Go MSAL implementation (CacheExtKeyGenerator):
    sorted key+value pairs are concatenated and SHA256 hashed, then base64url encoded.
     c                 J    i | ] \  }}|t           v||t          |          !S  )_EXT_CACHE_KEY_EXCLUDED_FIELDSstr.0kvs      X/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/msal/token_cache.py
<dictcomp>z*_compute_ext_cache_key.<locals>.<dictcomp>[   s?       a222q2 	
3q66222    c              3   .   K   | ]}||         z   V  d S Nr"   )r&   r'   cache_componentss     r)   	<genexpr>z)_compute_ext_cache_key.<locals>.<genexpr>b   s?        $%Q     r+   zutf-8   =ascii)itemsjoinsortedkeyshashlibsha256encodedigestbase64urlsafe_b64encoderstripdecodelower)datakey_str
hash_bytesr.   s      @r)   _compute_ext_cache_keyrB   L   s      r "jjll    rgg    )/0@0E0E0G0G)H)H    G w 7 788??AAJ#J//66t<<CCGLLRRTTTr+   c                 $    t          |fi | |k    S r-   )dict)smallbigs     r)   is_subdict_ofrG   i   s    u$$r+   c                 T    |                      d|                      d                    S )Npreferred_usernameupn)get)id_token_claimss    r)   _get_usernamerM   l   s.    E""$ $ $r+   c            
           e Zd ZdZ G d d          Z G d d          Zd Z	 	 ddZdd	Zdd
Z	e
ddedededefd            ZddddZddddZddZd ZddZddZd Zd Zd Zd Zd ZdS )
TokenCachea  This is considered as a base class containing minimal cache behavior.

    Although it maintains tokens using unified schema across all MSAL libraries,
    this class does not serialize/persist them.
    See subclass :class:`SerializableTokenCache` for details on serialization.
    c                   &    e Zd ZdZdZdZdZdZdZdS )TokenCache.CredentialTypeAccessTokenatextRefreshTokenAccountIdTokenAppMetadataN)	__name__
__module____qualname__ACCESS_TOKENACCESS_TOKEN_EXTENDEDREFRESH_TOKENACCOUNTID_TOKENAPP_METADATAr"   r+   r)   CredentialTyperQ   y   s-        $ '&$r+   ra   c                       e Zd ZdZdZdS )TokenCache.AuthorityTypeADFSMSSTSN)rX   rY   rZ   rd   re   r"   r+   r)   AuthorityTyperc      s        r+   rf   c                      t          j                     _        i  _         j        j        	 	 d fd	 j        j        	 	 	 dd j        j        	 	 d fd	 j        j        dd j        j	        d	di _
        d S )
Nc                     d                     | pd|pdj        j        |pdd|pdg                                          S N-r    )r3   ra   r]   r>   )home_account_idenvironmentr   target!ignored_payload_from_a_real_tokenselfs        r)   <lambda>z%TokenCache.__init__.<locals>.<lambda>   sS    HH'-2#)r+9!R"   !577 r+   c                     d                     | pd|pd|rdnd|pd|pd|pdg|r|gng z                                             S )Nrj   r    rS   rR   r3   r>   )rk   rl   r   realmrm   ext_cache_keyrn   s          r)   rp   z%TokenCache.__init__.<locals>.<lambda>   ss     HH'-2#)r $1Cm!R"
 1>Em__2
G    %''# r+   c                     d                     | pd|pdj        j        |pd|pddg                                          S ri   )r3   ra   r_   r>   )rk   rl   r   rs   rn   ro   s        r)   rp   z%TokenCache.__init__.<locals>.<lambda>   sS    HH'-2#)r+4!R   !577 r+   c                 b    d                     | pd|pd|pdg                                          S ri   rr   )rk   rl   rs   !ignored_payload_from_a_real_entrys       r)   rp   z%TokenCache.__init__.<locals>.<lambda>   s?    HH'-2#)r   !577 r+   c                 6    d                     | pd|pd          S )Nzappmetadata-{}-{}r    )format)rl   r   kwargss      r)   rp   z%TokenCache.__init__.<locals>.<lambda>   s#    '..{/@b)/rRR r+   )NNNN)NNNNNN)NNNNN)	threadingRLock_lock_cachera   r]   r[   r_   r^   r`   
key_makersro   s   `r)   __init__zTokenCache.__init__   s    _&&
 -IM#	# 	# 	# 	# 	# ,IM+/&*" " "$ (IM"	# 	# 	# 	# 	# '# # # ,S S Sk7r+   Nc                     |                      | j        j         | j        t          j        j                 ||||d                    |          |          |          S )N )rk   rl   r   rs   rm   rt   default)_getra   r[   r   rO   r3   )ro   rk   rl   r   rs   rm   rt   r   s           r)   _get_access_tokenzTokenCache._get_access_token   sl     yy,CDOJ5BC /'#xx''+     
 
 
	r+   c                     |                      | j        j         | j        t          j        j                 ||          |          S )N)rl   r   r   )r   ra   r`   r   rO   )ro   rl   r   r   s       r)   _get_app_metadatazTokenCache._get_app_metadata   sR    yy,CDOJ5BC'#       	r+   c                     | j         5  | j                            |i                               ||          cd d d            S # 1 swxY w Y   d S r-   )r~   r   rK   )ro   credential_typekeyr   s       r)   r   zTokenCache._get   s    Z 	J 	J;???B77;;CII	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	Js   /AAAentryquery
target_setreturnc                     |rd |                                 D             ni }t          ||           o<|r9|t          |                     dd                                                    k    ndS )Nc                 x    i | ]7\  }}||d k    r)t          |t                    r|                                n|8S )rl   )
isinstancer$   r>   r%   s      r)   r*   z+TokenCache._is_matching.<locals>.<dictcomp>   sU     ,
 ,
 ,
 1 A..:a3E3E.qwwyyy1,
 ,
 ,
r+   rm   r    T)r2   rG   setrK   split)r   r   r    query_with_lowercase_environments       r)   _is_matchingzTokenCache._is_matching   s     , ,
 ,
 	,
 ,
 ,
 ,

  	) =uEE %$J#eii"55;;==>>>>#	%r+   nowc          
   #     K   t          |pg           }t          |t                    s
J d            d}|| j        j        k    rt          |t
                    rtd|v rpd|v rld|v rhd|v rd|rb|                     |d         |d         |d         |d         ||                    d                    }|r|                     ||          r|V  t          |          }| j
        5  t          |t          j                    n|          }g }| j                            |i                                           D ]~}|| j        j        k    r/t          |d	                   |k     r|                    |           A||k    r7|                     |||
          r|| j        j        k    rd|v rd|pi vrz|V  |D ]}	|                     |	           	 ddd           dS # 1 swxY w Y   dS )zReturns a generator of matching entries.

        It is O(1) for AT hits, and O(n) for other types.
        Note that it holds a lock during the entire search.
        zInvalid parameter typeNrk   rl   r   rs   rt   )rt   
expires_on)r   )r4   r   listra   r[   rD   r   rK   r   r   r~   inttimer   valuesappend	remove_at)
ro   r   rm   r   r   preferred_resultr   expired_access_tokensr   ats
             r)   searchzTokenCache.search   s      "%%&$''AA)AAA't2???5$'' @!U**}/E/Eu$$E)9)9f)9#55'(%*>k"E'NF#ii88  6  :  :   'D$5$5 %% % ' '&&&[[
Z 	# 	#S[dikkkc::C%!
 "==DDFF    #t':'GGGE,/00366)00777---))%:)NN .
 (4+>+KKK+u44+EKR@@ KKK+ # #r""""#5	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s   $C-GG#&G#c                    t          j        dt                     t          |                     ||||                    S )z Equivalent to list(search(...)).z7Use list(search(...)) instead to explicitly get a list.)rm   r   r   )warningswarnDeprecationWarningr   r   )ro   r   rm   r   r   s        r)   findzTokenCache.find#  sA    E	  	  	  DKKeQTKUUVVVr+   c           
      >   d }t          | ||                    di           d           ||                    di           d                    }t                              dt	          j        |dd	t          
                     |                     ||          S )z:Handle a token obtaining event, and add tokens into cache.c                 D    fd|                                  D             S )Nc                 (    i | ]\  }}||v rd n|S )z********r"   )r&   r'   r(   sensitive_fieldss      r)   r*   z;TokenCache.add.<locals>.make_clean_copy.<locals>.<dictcomp>-  s>       Aq &6!6!6::A  r+   )r2   )
dictionaryr   s    `r)   make_clean_copyz'TokenCache.add.<locals>.make_clean_copy,  s:       &,,..   r+   r?   )r   r   r   r   r   response)rL   access_tokenr   id_tokenr   )r?   r   zevent=%s   T)indent	sort_keysr   r   )rD   rK   loggerdebugjsondumpsr$   _TokenCache__add)ro   eventr   r   clean_events        r)   addzTokenCache.add*  s    	 	 	
  62!6!6 9   %_UYYz2%>%> A  

 

 

 	Z "
 "
 "
 	 	 	 zz%Sz)))r+   c                     d|v r>t          j        t          |d                             }d|v rd|v r| dj        di |fS |r|d         }d|i|fS i dfS )z&Return client_info and home_account_idr   uidutidz{uid}.{utid}subNr"   )r   loadsr   ry   )ro   r   rL   r   r   s        r)   __parse_accountzTokenCache.__parse_accountE  s    H$$*[-1H%I%IJJK##+(=(="$9N$9$H$HK$H$HHH 	%!%(C3<$$4xr+   c                 	   d x}}d|v rt          |d                   \  }}}d|v r|d         }|                    di           }|                    di           |                    d          }|                    d          }|                    d          }	|                    d          p|	rt          |	|d	         
          ni }
|                     ||
          \  }}d                    t          |                    d          pg                     }| j        5  t          |t          j                    n|          }|rg|                    d          r%t          |                    d                    |z
  nd}t          |                    d|                    }t          |                    d|                    }| j	        j
        ||||                    d	          |||                    dd          t          |          t          ||z             t          ||z             d}|                    fdD                        t                    }|r||d<   d|v r|d         }t          ||z             |d<   |                     | j	        j
        ||           |r"|                    d          s||||                    d|
                    d|
                    d                              t          |
          p+                    d          p|                    d          pd|                    d|dk    r| j        j        n| j        j                  d }t&          d!d"t(          j        d#         d$f}|                    d%          |v r|d%         |d&<   |                     | j	        j        ||           |	rG| j	        j        |	||||                    d	          d'}|                     | j	        j        ||           |rd| j	        j        ||||                    d	          |t          |          d(}d)|v r|d)         |d*<   |                     | j	        j        ||           |                    d	          |d+}d)|v r|                    d)          |d*<   |                     | j	        j        ||           d d d            d S # 1 swxY w Y   d S ),Ntoken_endpointrl   r   r?   r   r   r   rL   r   )r   r   r
   r   iX  
expires_inext_expires_inr   Bearer)r   secretrk   rl   r   rm   rs   r   	cached_atr   extended_expires_onc                 *    i | ]}|d v ||         S )>   r   r"   )r&   r'   r?   s     r)   r*   z$TokenCache.__add.<locals>.<dictcomp>~  s<       !q = 8 81d1g 8 8 8r+   rt   
refresh_in
refresh_onskip_account_creation_account_idoidr   r   r    authority_typeadfs)rk   rl   rs   local_account_idr   r   authorization_coder   
GRANT_TYPEuser_ficr   account_source)r   r   rk   rl   rs   r   )r   r   rk   rl   r   rm   last_modification_timefoci	family_id)r   rl   )r   rK   r   _TokenCache__parse_accountr3   r4   r~   r   r   ra   r[   r$   updaterB   modifyrM   rf   rd   re   _GRANT_TYPE_BROKERr   DEVICE_FLOWr^   r_   r]   r`   )ro   r   r   rl   rs   _r   r   r   r   rL   r   rk   rm   default_expires_inr   r   r   rt   r   account%grant_types_that_establish_an_accountidtrtapp_metadatar?   s                            @r)   __addzTokenCache.__addR  s    #"eu$$$07G1H$I$I!A{EE!!.K99Z,,yy$$||N33 _55<<
++",,'899 YGOWOHk0BCCCCUW 	 (,';';Ho'V'V$_&7!3!3!9r::;;Z b	V b	VS[dikkkc::C #F "l33&=\2233c999< # !LL/ABBD D
!$<< *--"/ "/ (,':'G*'6#.!&;!7!7$""*,,|X"F"F!$S"%cJ&6"7"7+.s^/C+D+D  		    t       !7t < <  8*7B'8++!),!7J'*3+;'<'<B|$D/<b"EEE K599-D#E#E K'6#."(-		%'++E?3F3Fu3M3MNN)P )P !.o > > !88J//! 99Z00! &+ii(38F??*//!%!3!9'; '; & '(<j&|4j9B5 99\**.SSS05l0CG,-D/7'JJJ 
D'+':'C&'6#."!&;!7!7  D/8#sCCC G'+':'H+'6#.!&;!7!7$.1#hh  X%%&.v&6B{OD/=r2FFF #YY{33* L !!,4LL,@,@[)KK+8,UUUEb	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	V b	Vs   !N8S&&S*-S*c                 &    | j         |         di |}| j        5  |r,| j                            |i           }t	          |fi |||<   n/| j                            |i                               |d            d d d            d S # 1 swxY w Y   d S )Nr"   )r   r~   r   
setdefaultrD   pop)ro   r   	old_entrynew_key_value_pairsr   entriess         r)   r   zTokenCache.modify  s    /doo.;;;;Z 	K 	K" K+00"EE# +  +) +  + &&;;??TJJJ	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	Ks   ABB
B
c                     |                     d          | j        j        k    sJ |                     | j        j        |          S Nr   )rK   ra   r]   r   )ro   rt_items     r)   	remove_rtzTokenCache.remove_rt  s@    {{,--1D1RRRRR{{4.<gFFFr+   c                     |                     d          | j        j        k    sJ |                     | j        j        ||t	          t          t          j                                        d          S )Nr   )r   r   )rK   ra   r]   r   r$   r   r   )ro   r   new_rts      r)   	update_rtzTokenCache.update_rt  sn    {{,--1D1RRRRR{{4.<g&)#dikk*:*:&;&;H H   	r+   c                     |                     d          | j        j        k    sJ |                     | j        j        |          S r   )rK   ra   r[   r   )ro   at_items     r)   r   zTokenCache.remove_at  s@    {{,--1D1QQQQQ{{4.;WEEEr+   c                     |                     d          | j        j        k    sJ |                     | j        j        |          S r   )rK   ra   r_   r   )ro   idt_items     r)   
remove_idtzTokenCache.remove_idt  s@    ||-..$2E2NNNNN{{4.7BBBr+   c                 N    d|v sJ |                      | j        j        |          S )Nr   )r   ra   r^   )ro   account_items     r)   remove_accountzTokenCache.remove_account  s-    <////{{4.6EEEr+   r{   r-   )rX   rY   rZ   __doc__ra   rf   r   r   r   r   staticmethodrD   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r"   r+   r)   rO   rO   q   s        % % % % % % % %       : : :~ 	   $   J J J J 	% 	%D 	% 	%3 	%$ 	% 	% 	% \	%5#d 5# 5# 5# 5# 5#nWD W W W W W* * * *6  vV vV vV vVpK K K K$G G G  F F FC C CF F F F Fr+   rO   c                   >     e Zd ZdZdZ fdZd fd	Zd Zd Z xZ	S )	SerializableTokenCachea  This serialization can be a starting point to implement your own persistence.

    This class does NOT actually persist the cache on disk/db/etc..
    Depending on your need,
    the following simple recipe for file-based, unencrypted persistence may be sufficient::

        import os, atexit, msal
        cache_filename = os.path.join(  # Persist cache into this file
            os.getenv(
                # Automatically wipe out the cache from Linux when user's ssh session ends.
                # See also https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/690
                "XDG_RUNTIME_DIR", ""),
            "my_cache.bin")
        cache = msal.SerializableTokenCache()
        if os.path.exists(cache_filename):
            cache.deserialize(open(cache_filename, "r").read())
        atexit.register(lambda:
            open(cache_filename, "w").write(cache.serialize())
            # Hint: The following optional line persists only when state changed
            if cache.has_state_changed else None
            )
        app = msal.ClientApplication(..., token_cache=cache)
        ...

    Alternatively, you may use a more sophisticated cache persistence library,
    `MSAL Extensions <https://github.com/AzureAD/microsoft-authentication-extensions-for-python>`_,
    which provides token cache persistence with encryption, and more.

    :var bool has_state_changed:
        Indicates whether the cache state in the memory has changed since last
        :func:`~serialize` or :func:`~deserialize` call.
    Fc                 X     t          t          |           j        |fi | d| _        d S NT)superr  r   has_state_changed)ro   r   rz   	__class__s      r)   r   zSerializableTokenCache.add  s7    /$d++/@@@@@!%r+   Nc                 j    t          t          |                               |||           d| _        d S r  )r  r  r   r  )ro   r   r   r   r	  s       r)   r   zSerializableTokenCache.modify  s<    $d++22Y(;	= 	= 	=!%r+   c                     | j         5  |rt          j        |          ni | _        d| _        ddd           dS # 1 swxY w Y   dS )zEDeserialize the cache from a state previously obtained by serialize()FN)r~   r   r   r   r  )ro   states     r)   deserializez"SerializableTokenCache.deserialize   s     Z 	+ 	+/4<$*U+++"DK%*D"	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+s   %:>>c                     | j         5  d| _        t          j        | j        d          cddd           S # 1 swxY w Y   dS )z0Serialize the current cache state into a string.Fr   )r   N)r~   r  r   r   r   r   s    r)   	serializez SerializableTokenCache.serialize'  s     Z 	5 	5%*D":dk!444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5s   "7;;r-   )
rX   rY   rZ   r   r  r   r   r  r  __classcell__)r	  s   @r)   r  r    s         @ & & & & && & & & & &
+ + +5 5 5 5 5 5 5r+   r  )r:   r6   r   r|   r   loggingr   	authorityr   oauth2cli.oidcr   r   oauth2cli.oauth2r   	getLoggerrX   r   r   	frozensetr#   rB   rG   rM   objectrO   r  r"   r+   r)   <module>r     s_             # # # # # # 8 8 8 8 8 8 8 8 $ $ $ $ $ $ 
	8	$	$ < "+ , , , " " >U U U:% % %$ $ $
@F @F @F @F @F @F @F @FF85 85 85 85 85Z 85 85 85 85 85r+   