
    2i1f                         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passwordusername	assertion	client_id
grant_type
token_typedevice_coderedirect_uriclient_secretcode_verifierrefresh_tokenclient_assertionrequested_token_useclient_assertion_typec                    | 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     F/var/www/html/qr/venv/lib/python3.12/site-packages/msal/token_cache.py	<genexpr>z)_compute_ext_cache_key.<locals>.<genexpr>]   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;   G   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_ofr@   d   s    u$$    c                 D    | j                  d| j                  d            S )Npreferred_usernameupn)get)id_token_claimss    r$   _get_usernamerG   g   s&    E"$ $rA   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    rA   r$   CredentialTyperK   t   s!    $ '&$rA   r[   c                       e Zd ZdZdZy)TokenCache.AuthorityTypeADFSMSSTSN)rR   rS   rT   r^   r_   r    rA   r$   AuthorityTyper]   |   s    rA   r`   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[   rW   r6   )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 rA   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 )Nrd   r   rM   rL   r+   r6   )re   rf   r   realmrg   ext_cache_keyrh   s          r$   rj   z%TokenCache.__init__.<locals>.<lambda>   sb     HH'-2#)r $1m!R"
 1>m_2
G   %'# rA   c                     dj                  | xs d|xs dj                  j                  |xs d|xs ddg      j                         S rc   )r+   r[   rY   r6   )re   rf   r   rm   rh   ri   s        r$   rj   z%TokenCache.__init__.<locals>.<lambda>   sR    HH'-2#)r++44!R  !57 rA   c                 ^    dj                  | xs d|xs d|xs dg      j                         S rc   rl   )re   rf   rm   !ignored_payload_from_a_real_entrys       r$   rj   z%TokenCache.__init__.<locals>.<lambda>   s8    HH'-2#)r  !57 rA   c                 6    dj                  | xs d|xs d      S )Nzappmetadata-{}-{}r   )format)rf   r   kwargss      r$   rj   z%TokenCache.__init__.<locals>.<lambda>   s     '..{/@b)/rR rA   )NNNN)NNNNNN)NNNNN)	threadingRLock_lock_cacher[   rW   rU   rY   rX   rZ   
key_makersri   s   `r$   __init__zTokenCache.__init__   s    __&
 --IM#	# ,,IM+/&*"$ ((IM"	# ''# ,,Sk7rA   Nc                     | j                  | j                  j                   | j                  t        j                  j                     ||||dj                  |      |      |      S )N )re   rf   r   rm   rg   rn   default)_getr[   rU   rz   rI   r+   )ri   re   rf   r   rm   rg   rn   r   s           r$   _get_access_tokenzTokenCache._get_access_token   sh     yy,,CDOOJ55BBC /'#xx'+   
 
	rA   c                     | j                  | j                  j                   | j                  t        j                  j                     ||      |      S )N)rf   r   r   )r   r[   rZ   rz   rI   )ri   rf   r   r   s       r$   _get_app_metadatazTokenCache._get_app_metadata   sQ    yy,,CDOOJ55BBC'#    	rA   c                     | j                   5  | j                  j                  |i       j                  ||      cd d d        S # 1 sw Y   y xY wr   )rx   ry   rE   )ri   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 )Nrf   rg   r   T)r(   
isinstancer*   r6   r@   setrE   split)r   r   r   r"   r8    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 typeNre   rf   r   rm   rn   )rn   
expires_on)r   )r,   r   listr[   rU   r=   r   rE   r   r   rx   inttimery   valuesappend	remove_at)
ri   r   rg   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.)rg   r   r   )warningswarnDeprecationWarningr   r   )ri   r   rg   r   r   s        r$   findzTokenCache.find  s3    E	  DKKeQTKUVVrA   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"   r8   s       r$   make_clean_copyz'TokenCache.add.<locals>.make_clean_copy'  s@     ',,.Aq &6!6:A=  s   +r7   )r   r   r   r   response)rF   access_tokenr   id_tokenr   )r7   r   zevent=%s   T)indent	sort_keysr   r   )r=   rE   loggerdebugjsondumpsr*   _TokenCache__add)ri   eventr   r   clean_events        r$   addzTokenCache.add%  s    	
  62!6 9  %UYYz2%> A 	
 	Z "
 	 zz%Sz))rA   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_idclient_infouidutidz{uid}.{utid}subNr    )r   loadsr   rs   )ri   r   rF   r   r   s        r$   __parse_accountzTokenCache.__parse_account?  sr    H$**[-1H%IJK#+(="$9N$9$9$HK$HHH!%(C3<$$4xrA   c                 B	   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#   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_endpointrf   r   r7   r   r   r   rF   r   )r   r~   r
   r   iX  
expires_inext_expires_inr   Bearer)r   secretre   rf   r   rg   rm   r   	cached_atr   extended_expires_on>   r   rn   
refresh_in
refresh_onskip_account_creation_account_idoidr   r   r   authority_typeadfs)re   rf   rm   local_account_idr   r   authorization_coder   
GRANT_TYPEr   account_source)r   r   re   rf   rm   r   )r   r   re   rf   r   rg   last_modification_timefoci	family_id)r   rf   )r   rE   r   _TokenCache__parse_accountr+   r,   rx   r   r   r[   rU   r*   updater;   modifyrG   r`   r^   r_   _GRANT_TYPE_BROKERr   DEVICE_FLOWrX   rY   rW   rZ   )ri   r   r   rf   rm   _r   r7   r   r   r   rF   r   re   rg   default_expires_inr   r   r   r"   rn   r   account%grant_types_that_establish_an_accountidtrtapp_metadatas                              r$   __addzTokenCache.__addL  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&&|496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    )rz   rx   ry   
setdefaultr=   pop)ri   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   )rE   r[   rW   r   )ri   rt_items     r$   	remove_rtzTokenCache.remove_rt  sC    {{,-1D1D1R1RRRR{{4..<<gFFrA   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  ||t	        t        t        j                                     d      S )Nr   )r   r   )rE   r[   rW   r   r*   r   r   )ri   r   new_rts      r$   	update_rtzTokenCache.update_rt  sc    {{,-1D1D1R1RRRR{{4..<<g&)#diik*:&;H  	rA   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  |      S r   )rE   r[   rU   r   )ri   at_items     r$   r   zTokenCache.remove_at  sC    {{,-1D1D1Q1QQQQ{{4..;;WEErA   c                     |j                  d      | j                  j                  k(  sJ | j                  | j                  j                  |      S r   )rE   r[   rY   r   )ri   idt_items     r$   
remove_idtzTokenCache.remove_idt  sC    ||-.$2E2E2N2NNNN{{4..77BBrA   c                 Z    d|v sJ | j                  | j                  j                  |      S )Nr   )r   r[   rX   )ri   account_items     r$   remove_accountzTokenCache.remove_account  s-    <///{{4..66EErA   ru   r   )rR   rS   rT   __doc__r[   r`   r|   r   r   r   staticmethodr=   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r    rA   r$   rI   rI   l   s    % % :~ 	$J 	%D 	% 	%3 	%$ 	% 	%5#d 5#nWD W*4vVpK$GFCFrA   rI   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)ri   r   rt   	__class__s      r$   r   zSerializableTokenCache.add  s     $d/@@!%rA   c                 >    t         t        |   |||       d| _        y r   )r   r   r   r   )ri   r   r   r   r   s       r$   r   zSerializableTokenCache.modify  s#    $d2Y(;	=!%rA   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)rx   r   r   ry   r   )ri   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)rx   r   r   r   ry   r{   s    r$   	serializez SerializableTokenCache.serialize!  s:     ZZ 	5%*D"::dkk!4	5 	5 	5s	   (?Ar   )
rR   rS   rT   r   r   r   r   r  r  __classcell__)r   s   @r$   r   r     s%    @ &&
+5rA   r   )r2   r.   r   rv   r   loggingr   	authorityr   oauth2cli.oidcr   r   oauth2cli.oauth2r   	getLoggerrR   r   r   	frozensetr)   r;   r@   rG   objectrI   r   r    rA   r$   <module>r     s|           # 8 $ 
		8	$ < "+ , " 4U:%$
F FD85Z 85rA   