
    AHjUg                         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y)    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y| j                         D ci c]  \  }}|t        vr|r|t        |       c}}sydj                  fdt	        j                               D              }t        j                  |j                  d            j                         }t        j                  |      j                  d      j                  d      j                         S c c}}w )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              3   .   K   | ]  }||   z     y wN ).0kcache_componentss     H/root/tools/cai/cai_env/lib/python3.12/site-packages/msal/token_cache.py	<genexpr>z)_compute_ext_cache_key.<locals>.<genexpr>b   s!      $%Qs   zutf-8   =ascii)items_EXT_CACHE_KEY_EXCLUDED_FIELDSstrjoinsortedkeyshashlibsha256encodedigestbase64urlsafe_b64encoderstripdecodelower)datar%   vkey_str
hash_bytesr&   s        @r'   _compute_ext_cache_keyr>   L   s     "jjla22q 	
3q6	 gg )/0@0E0E0G)H G w 78??AJ##J/66t<CCGLRRTTs    C#c                      t        |fi | |k(  S r"   )dict)smallbigs     r'   is_subdict_ofrC   i   s    u$$    c                 D    | j                  d| j                  d            S )Npreferred_usernameupn)get)id_token_claimss    r'   _get_usernamerJ   l   s&    E"$ $rD   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y)
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y)TokenCache.CredentialTypeAccessTokenatextRefreshTokenAccountIdTokenAppMetadataN)	__name__
__module____qualname__ACCESS_TOKENACCESS_TOKEN_EXTENDEDREFRESH_TOKENACCOUNTID_TOKENAPP_METADATAr#   rD   r'   CredentialTyperN   y   s!    $ '&$rD   r^   c                       e Zd ZdZdZy)TokenCache.AuthorityTypeADFSMSSTSN)rU   rV   rW   ra   rb   r#   rD   r'   AuthorityTyper`      s    rD   rc   c                 Z    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 _
        y )
Nc           	          dj                  | xs d|xs dj                  j                  |xs dd|xs dg      j                         S N-r    )r.   r^   rZ   r9   )home_account_idenvironmentr   target!ignored_payload_from_a_real_tokenselfs        r'   <lambda>z%TokenCache.__init__.<locals>.<lambda>   sR    HH'-2#)r++99!R"  !57 rD   c           	          dj                  | xs d|xs d|rdnd|xs d|xs d|xs dg|r|gng z         j                         S )Nrg   r    rP   rO   r.   r9   )rh   ri   r   realmrj   ext_cache_keyrk   s          r'   rm   z%TokenCache.__init__.<locals>.<lambda>   sb     HH'-2#)r $1m!R"
 1>m_2
G   %'# rD   c                     dj                  | xs d|xs dj                  j                  |xs d|xs ddg      j                         S rf   )r.   r^   r\   r9   )rh   ri   r   rp   rk   rl   s        r'   rm   z%TokenCache.__init__.<locals>.<lambda>   sR    HH'-2#)r++44!R  !57 rD   c                 ^    dj                  | xs d|xs d|xs dg      j                         S rf   ro   )rh   ri   rp   !ignored_payload_from_a_real_entrys       r'   rm   z%TokenCache.__init__.<locals>.<lambda>   s8    HH'-2#)r  !57 rD   c                 6    dj                  | xs d|xs d      S )Nzappmetadata-{}-{}r    )format)ri   r   kwargss      r'   rm   z%TokenCache.__init__.<locals>.<lambda>   s     '..{/@b)/rR rD   )NNNN)NNNNNN)NNNNN)	threadingRLock_lock_cacher^   rZ   rX   r\   r[   r]   
key_makersrl   s   `r'   __init__zTokenCache.__init__   s    __&
 --IM#	# ,,IM+/&*"$ ((IM"	# ''# ,,Sk7rD   Nc                     | j                  | j                  j                   | j                  t        j                  j                     ||||dj                  |      |      |      S )N )rh   ri   r   rp   rj   rq   default)_getr^   rX   r}   rL   r.   )rl   rh   ri   r   rp   rj   rq   r   s           r'   _get_access_tokenzTokenCache._get_access_token   sh     yy,,CDOOJ55BBC /'#xx'+   
 
	rD   c                     | j                  | j                  j                   | j                  t        j                  j                     ||      |      S )N)ri   r   r   )r   r^   r]   r}   rL   )rl   ri   r   r   s       r'   _get_app_metadatazTokenCache._get_app_metadata   sQ    yy,,CDOOJ55BBC'#    	rD   c                     | j                   5  | j                  j                  |i       j                  ||      cd d d        S # 1 sw Y   y xY wr"   )r{   r|   rH   )rl   credential_typekeyr   s       r'   r   zTokenCache._get   sA    ZZ 	J;;???B7;;CI	J 	J 	Js   ,AAentryquery
target_setreturnc           	      $   |rI|j                         D ci c]-  \  }}||dk(  r t        |t              r|j                         n|/ c}}ni }t	        ||       xr0 |r,|t        | j                  dd      j                               k  S dS c c}}w )Nri   rj   r    T)r+   
isinstancer-   r9   rC   setrH   split)r   r   r   r%   r;    query_with_lowercase_environments         r'   _is_matchingzTokenCache._is_matching   s      	,
 1 A.:a3Eqwwy1L,

  	) =uE % #eii"5;;=>>	%#	%,
s   2Bnowc          
   #     K   t        |xs g       }t        |t              sJ d       d}|| j                  j                  k(  rlt        |t
              r\d|v rXd|v rTd|v rPd|v rL|rJ| j                  |d   |d   |d   |d   ||j                  d            }|r| j                  ||      r| t        |      }| j                  5  t        |t        j                         n|      }g }| j                  j                  |i       j                         D ]  }|| j                  j                  k(  r#t        |d	         |k  r|j                  |       ?||k7  sE| j                  |||
      sZ|| j                  j                  k(  rd|v r	d|xs i vr|  |D ]  }	| j!                  |	        	 ddd       y# 1 sw Y   yxY ww)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 typeNrh   ri   r   rp   rq   )rq   
expires_on)r   )r/   r   listr^   rX   r@   r   rH   r   r   r{   inttimer|   valuesappend	remove_at)
rl   r   rj   r   r   preferred_resultr   expired_access_tokensr   ats
             r'   searchzTokenCache.search   s     "%&$'A)AA't22???5$'!U*}/Eu$E)9f#55'(%*>k"E'NF#ii8  6  :  D$5$5 %% '&[
ZZ 	#S[diikc:C%!
 "=DDF  #t':':'G'GGE,/036)007--))%:)N (4+>+>+K+KK+u4+EKR@ K# $ , #r"#5	# 	# 	#s,   CG	BF=F=/AF=4	G	=GG	c                r    t        j                  dt               t        | j	                  ||||            S )z Equivalent to list(search(...)).z7Use list(search(...)) instead to explicitly get a list.)rj   r   r   )warningswarnDeprecationWarningr   r   )rl   r   rj   r   r   s        r'   findzTokenCache.find#  s3    E	  DKKeQTKUVVrD   c           
         d }t        | ||j                  di       d       ||j                  di       d            }t        j                  dt	        j
                  |dd	t        
             | j                  ||      S )z:Handle a token obtaining event, and add tokens into cache.c                 b    | j                         D ci c]  \  }}|||v rdn| c}}S c c}}w )Nz********)r+   )
dictionarysensitive_fieldsr%   r;   s       r'   make_clean_copyz'TokenCache.add.<locals>.make_clean_copy,  s@     ',,.Aq &6!6:A=  s   +r:   )r   r   r   r   r   response)rI   access_tokenr   id_tokenr   )r:   r   zevent=%s   T)indent	sort_keysr   r   )r@   rH   loggerdebugjsondumpsr-   _TokenCache__add)rl   eventr   r   clean_events        r'   addzTokenCache.add*  s    	
  62!6 9  %UYYz2%> A 

 	Z "
 	 zz%Sz))rD   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   rv   )rl   r   rI   r   r   s        r'   __parse_accountzTokenCache.__parse_accountE  sr    H$**[-1H%IJK#+(="$9N$9$9$HK$HHH!%(C3<$$4xrD   c                 D	   d x}}d|v rt        |d         \  }}}d|v r|d   }|j                  di       }|j                  di       }|j                  d      }|j                  d      }	|j                  d      }
|j                  d      xs |
rt        |
|d	   
      ni }| j                  ||      \  }}dj	                  t        |j                  d      xs g             }| j                  5  t        |t        j                         n|      }|rC|j                  d      rt        |j                  d            |z
  nd}t        |j                  d|            }t        |j                  d|            }| j                  j                  ||||j                  d	      |||j                  dd      t        |      t        ||z         t        ||z         d}|j                  |D ci c]  }|dv s|||    c}       t        |      }|r||d<   d|v r|d   }t        ||z         |d<   | j                  | j                  j                  ||       |r|j                  d      s||||j                  d|j                  d|j                  d                  t        |      xs( |j                  d      xs |j                  d      xs d|j                  d|dk(  r| j                   j"                  n| j                   j$                        d }t&        d!d"t(        j*                  d#   d$f}|j                  d%      |v r|d%   |d&<   | j                  | j                  j,                  ||       |
rS| j                  j.                  |
||||j                  d	      d'}| j                  | j                  j.                  ||       |	ri| j                  j0                  |	|||j                  d	      |t        |      d(}d)|v r|d)   |d*<   | j                  | j                  j0                  ||       |j                  d	      |d+}d)|v r|j                  d)      |d*<   | j                  | j                  j2                  ||       d d d        y c c}w # 1 sw Y   y xY w),Ntoken_endpointri   r   r:   r   r   r   rI   r   )r   r   r
   r   iX  
expires_inext_expires_inr   Bearer)r   secretrh   ri   r   rj   rp   r   	cached_atr   extended_expires_on>   r   rq   
refresh_in
refresh_onskip_account_creation_account_idoidr   r   r    authority_typeadfs)rh   ri   rp   local_account_idr   r   authorization_coder   
GRANT_TYPEuser_ficr   account_source)r   r   rh   ri   rp   r   )r   r   rh   ri   r   rj   last_modification_timefoci	family_id)r   ri   )r   rH   r   _TokenCache__parse_accountr.   r/   r{   r   r   r^   rX   r-   updater>   modifyrJ   rc   ra   rb   _GRANT_TYPE_BROKERr   DEVICE_FLOWr[   r\   rZ   r]   )rl   r   r   ri   rp   _r   r:   r   r   r   rI   r   rh   rj   default_expires_inr   r   r   r%   rq   r   account%grant_types_that_establish_an_accountidtrtapp_metadatas                              r'   __addzTokenCache.__addR  s    #"eu$$07G1H$I!A{EE!.K99Z,yy$||N3 _5<<
+",,'89 YGOOHk0BCUW 	 (,';';Ho'V$_&7!3!9r:;ZZ b	VS[diikc:C "l3 \23c99< # !LL/ABD
!$<< *-"/ (,':':'G'G*'6#.!&;!7$""*,,|X"F!$S"%cJ&6"7+.s^/C+D 		t !q = 81d1g:   !7t < *7B'8+!),!7J'*3+;'<B|$D//<<b"E599-D#E'6#."(-		%'++E?3F3Fu3MN)P !.o > !88J/! 99Z0! &+ii(38F?**//!%!3!3!9!9';& '(<j&&|4j9B5 99\*.SS05l0CG,-D//77'J'+':':'C'C&'6#."!&;!7 D//88#sC'+':':'H'H+'6#.!&;!7$.1#h X%&.v&6B{OD//==r2F #YY{3*L !,4LL,@[)KK++88,UEb	V b	V01b	V b	Vs&   0C<R,	R
6R
>J
RRRc                 $    | j                   |   di |}| j                  5  |r,| j                  j                  |i       }t	        |fi |||<   n,| j                  j                  |i       j                  |d        d d d        y # 1 sw Y   y xY w)Nr#   )r}   r{   r|   
setdefaultr@   pop)rl   r   	old_entrynew_key_value_pairsr   entriess         r'   r   zTokenCache.modify  s     /dooo.;;ZZ 	K"++00"E# +) + &&;??TJ	K 	K 	Ks   ABBc                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  |      S Nr   )rH   r^   rZ   r   )rl   rt_items     r'   	remove_rtzTokenCache.remove_rt  sC    {{,-1D1D1R1RRRR{{4..<<gFFrD   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  ||t	        t        t        j                                     d      S )Nr   )r   r   )rH   r^   rZ   r   r-   r   r   )rl   r   new_rts      r'   	update_rtzTokenCache.update_rt  sc    {{,-1D1D1R1RRRR{{4..<<g&)#diik*:&;H  	rD   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  |      S r   )rH   r^   rX   r   )rl   at_items     r'   r   zTokenCache.remove_at  sC    {{,-1D1D1Q1QQQQ{{4..;;WEErD   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  |      S r   )rH   r^   r\   r   )rl   idt_items     r'   
remove_idtzTokenCache.remove_idt  sC    ||-.$2E2E2N2NNNN{{4..77BBrD   c                 Z    d|v sJ | j                  | j                  j                  |      S )Nr   )r   r^   r[   )rl   account_items     r'   remove_accountzTokenCache.remove_account  s-    <///{{4..66EErD   rx   r"   )rU   rV   rW   __doc__r^   rc   r   r   r   r   staticmethodr@   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r#   rD   r'   rL   rL   q   s    % % :~ 	$J 	%D 	% 	%3 	%$ 	% 	%5#d 5#nWD W*6vVpK$GFCFrD   rL   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                 <    t        t        | 
  |fi | d| _        y NT)superr   r   has_state_changed)rl   r   rw   	__class__s      r'   r   zSerializableTokenCache.add  s     $d/@@!%rD   c                 >    t         t        |   |||       d| _        y r   )r  r   r   r  )rl   r   r   r   r  s       r'   r   zSerializableTokenCache.modify  s#    $d2Y(;	=!%rD   c                     | j                   5  |rt        j                  |      ni | _        d| _        ddd       y# 1 sw Y   yxY w)zEDeserialize the cache from a state previously obtained by serialize()FN)r{   r   r   r|   r  )rl   states     r'   deserializez"SerializableTokenCache.deserialize   s<     ZZ 	+/4$**U+"DK%*D"	+ 	+ 	+s	   &<Ac                     | j                   5  d| _        t        j                  | j                  d      cddd       S # 1 sw Y   yxY w)z0Serialize the current cache state into a string.Fr   )r   N)r{   r  r   r   r|   r~   s    r'   	serializez SerializableTokenCache.serialize'  s:     ZZ 	5%*D"::dkk!4	5 	5 	5s	   (?Ar"   )
rU   rV   rW   r   r  r   r   r  r	  __classcell__)r  s   @r'   r   r     s%    @ &&
+5rD   r   )r5   r1   r   ry   r   loggingr   	authorityr   oauth2cli.oidcr   r   oauth2cli.oauth2r   	getLoggerrU   r   r   	frozensetr,   r>   rC   rJ   objectrL   r   r#   rD   r'   <module>r     s|           # 8 $ 
		8	$ < "+ , " >U:%$
@F @FF85Z 85rD   