o
    i,R                     @   s   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eZdZdd Zd	d
 ZG dd deZG dd deZdS )    N   )canonicalize)decode_partdecode_id_token)ClientZbrokerc                 C   s   t |fi | |kS N)dict)Zsmallbig r
   G/home/app/Keep/.python/lib/python3.10/site-packages/msal/token_cache.pyis_subdict_of      r   c                 C   s   |  d|  dS )NZpreferred_usernameZupn)get)id_token_claimsr
   r
   r   _get_username   s   r   c                
   @   s   e Zd ZdZG dd dZG dd dZdd Z	d,d	d
Zd,ddZd,ddZ	e
d,dedededefddZd-ddddZd-ddddZd,ddZdd Zd,ddZd,d d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*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                   @   s    e Zd ZdZdZdZdZdZdS )zTokenCache.CredentialTypeZAccessTokenZRefreshTokenZAccountZIdTokenZAppMetadataN)__name__
__module____qualname__ACCESS_TOKENREFRESH_TOKENACCOUNTID_TOKENAPP_METADATAr
   r
   r
   r   CredentialType   s    r   c                   @   s   e Zd ZdZdZdS )zTokenCache.AuthorityTypeADFSMSSTSN)r   r   r   r   r   r
   r
   r
   r   AuthorityType&   s    r   c                    sx   t   _i  _ jj	 	 d fdd	 jj	 	 d fdd	 jj	 	 d fdd	 jjd	dd jj	d
ddi _
d S )Nc                    s.   d | pd|pd jj|pdd|pdg S N- )joinr   r   lower)home_account_idenvironment	client_idtarget!ignored_payload_from_a_real_tokenselfr
   r   <lambda>1   s   z%TokenCache.__init__.<locals>.<lambda>c                    s2   d | pd|pd jj|pd|pd|pdg S r   )r!   r   r   r"   )r#   r$   r%   realmr&   r'   r(   r
   r   r*   <   s   c                    s.   d | pd|pd jj|pd|pddg S r   )r!   r   r   r"   )r#   r$   r%   r+   r'   r(   r
   r   r*   K   s   c                 [   s    d | pd|pd|pdg S r   )r!   r"   )r#   r$   r+   Z!ignored_payload_from_a_real_entryr
   r
   r   r*   V   s   c                 [   s   d | pd|pdS )Nzappmetadata-{}-{}r    )format)r$   r%   kwargsr
   r
   r   r*   ^   r   )NNNN)NNNNN)NNNNN)	threadingRLock_lock_cacher   r   r   r   r   r   
key_makersr(   r
   r(   r   __init__*   s&   



zTokenCache.__init__Nc              
   C   s2   | j | jj| jtjj ||||d|d|dS )N )r#   r$   r%   r+   r&   default)_getr   r   r3   r   r!   )r)   r#   r$   r%   r+   r&   r7   r
   r
   r   _get_access_tokenb   s   zTokenCache._get_access_tokenc                 C   s&   | j | jj| jtjj ||d|dS )N)r$   r%   r6   )r8   r   r   r3   r   )r)   r$   r%   r7   r
   r
   r   _get_app_metadatar   s   zTokenCache._get_app_metadatac                 C   s@   | j  | j|i ||W  d    S 1 sw   Y  d S r   )r1   r2   r   )r)   credential_typekeyr7   r
   r
   r   r8   {   s   $zTokenCache._getentryquery
target_setreturnc                 C   sD   |rdd |  D ni }t|| o!|r |t| dd kS dS )Nc                 S   s0   i | ]\}}||d krt |tr| n|qS )r$   )
isinstancestrr"   .0kvr
   r
   r   
<dictcomp>   s    z+TokenCache._is_matching.<locals>.<dictcomp>r&   r    T)itemsr   setr   split)r=   r>   r?   Z query_with_lowercase_environmentr
   r
   r   _is_matching   s   
zTokenCache._is_matchingnowc          
      c   sX   t |pg }t|tsJ dd}|| jjkrKt|trKd|v rKd|v rKd|v rKd|v rK|rK| |d |d |d |d |}|rK| ||rK|V  t|}| j	P t
|du r\t n|}g }| j|i  D ]%}|| jjkrt
|d |k r|| qj||kr| j|||dr|V  qj|D ]}	| |	 qW d   dS 1 sw   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 typeNr#   r$   r%   r+   
expires_on)r?   )sortedrA   listr   r   r   r9   rK   rI   r1   inttimer2   r   valuesappend	remove_at)
r)   r;   r&   r>   rM   Zpreferred_resultr?   Zexpired_access_tokensr=   atr
   r
   r   search   sF   
"zTokenCache.searchc                C   s"   t dt t| j||||dS )z Equivalent to list(search(...)).z7Use list(search(...)) instead to explicitly get a list.)r&   r>   rM   )warningswarnDeprecationWarningrP   rW   )r)   r;   r&   r>   rM   r
   r
   r   find   s
   zTokenCache.findc              	   C   sZ   dd }t |||di d||di dd}tdtj|d	d
td | j||dS )z:Handle a token obtaining event, and add tokens into cache.c                    s    fdd|   D S )Nc                    s"   i | ]\}}|| v rd n|qS )z********r
   rC   sensitive_fieldsr
   r   rG      s    z;TokenCache.add.<locals>.make_clean_copy.<locals>.<dictcomp>)rH   )
dictionaryr]   r
   r\   r   make_clean_copy   s   
z'TokenCache.add.<locals>.make_clean_copydata)passwordZclient_secretrefresh_tokenZ	assertionresponse)r   access_tokenrb   id_tokenusername)r`   rc   zevent=%s   T)indent	sort_keysr7   rL   )r   r   loggerdebugjsondumpsrB   _TokenCache__add)r)   eventrM   r_   Zclean_eventr
   r
   r   add   s   

zTokenCache.addc                 C   s^   d|v rt 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uidZutidz{uid}.{utid}subNr
   )rl   loadsr   r,   )r)   rc   r   rq   rs   r
   r
   r   Z__parse_account   s   zTokenCache.__parse_accountc                    s<  d  }}d|v rt |d \}}}d|v r|d }|di }|di  |d}|d}|d}	|dpD|	rCt|	|d	 d
ni }
| ||
\}}dt|dpVg }| j6 t|d u rgt n|}|r|drzt|d| nd}t|d|}t|d|}| j	j
||||d	|||ddt|t|| t|| d}| fdd D  d|v r|d }t|| |d< | | j	j
|| |r,|ds,||||d|
d|
dt|
p dp|dpd|d|dkr| jjn| jjd }td!d"tjd# f}|d$|v r#|d$ |d%< | | j	j|| |	rF| j	j|	||||d	d&}| | j	j|| |rn| j	j||||d	|t|d'}d(|v re|d( |d)< | | j	j|| |d	|d*}d(|v r|d(|d)< | | j	j|| W d    d S 1 sw   Y  d S )+NZtoken_endpointr$   rc   r`   rd   rb   re   r   r%   )r%   r5   scoperN   iX  
expires_inext_expires_in
token_typeZBearer)r;   secretr#   r$   r%   r&   r+   rx   Z	cached_atrN   Zextended_expires_onc                    s   i | ]}|d v r| | qS )>   Zkey_idr
   )rD   rE   r`   r
   r   rG     s    z$TokenCache.__add.<locals>.<dictcomp>
refresh_inZ
refresh_onZskip_account_creationZ_account_idoidrs   rf   r    authority_typeZadfs)r#   r$   r+   Zlocal_account_idrf   r}   Zauthorization_codera   Z
GRANT_TYPEZ
grant_typeZaccount_source)r;   ry   r#   r$   r+   r%   )r;   ry   r#   r$   r%   r&   last_modification_timeZfociZ	family_id)r%   r$   )r   r   r   _TokenCache__parse_accountr!   rO   r1   rQ   rR   r   r   rB   updatemodifyr   r   r   r   _GRANT_TYPE_BROKERr   ZDEVICE_FLOWr   r   r   r   )r)   ro   rM   r$   r+   _rc   rd   rb   re   r   rq   r#   r&   Zdefault_expires_inrv   rw   rV   r{   accountZ%grant_types_that_establish_an_accountZidtrtZapp_metadatar
   rz   r   Z__add   s   









	
	
$zTokenCache.__addc                 C   s   | j | di |}| j0 |r"| j|i }t|fi |||< n| j|i |d  W d    d S W d    d S 1 s@w   Y  d S )Nr
   )r3   r1   r2   
setdefaultr   pop)r)   r;   	old_entrynew_key_value_pairsr<   entriesr
   r
   r   r   Z  s   "zTokenCache.modifyc                 C   &   | d| jjksJ | | jj|S Nr;   )r   r   r   r   )r)   rt_itemr
   r
   r   	remove_rtl     zTokenCache.remove_rtc              	   C   s:   | d| jjksJ | | jj||ttt dS )Nr;   )ry   r~   )r   r   r   r   rB   rQ   rR   )r)   r   Znew_rtr
   r
   r   	update_rtp  s
   zTokenCache.update_rtc                 C   r   r   )r   r   r   r   )r)   Zat_itemr
   r
   r   rU   w  r   zTokenCache.remove_atc                 C   r   r   )r   r   r   r   )r)   Zidt_itemr
   r
   r   
remove_idt{  r   zTokenCache.remove_idtc                 C   s   d|v sJ |  | jj|S )Nr}   )r   r   r   )r)   Zaccount_itemr
   r
   r   remove_account  s   zTokenCache.remove_accountr   r.   )r   r   r   __doc__r   r   r4   r9   r:   r8   staticmethodr   rI   boolrK   rW   r[   rp   r   rn   r   r   r   rU   r   r   r
   r
   r
   r   r      s,    ;


	/


rr   c                       sB   e Zd ZdZdZ fddZd fdd	Zdd	 Zd
d Z  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                    s"   t t| j|fi | d| _d S NT)superr   rp   has_state_changed)r)   ro   r-   	__class__r
   r   rp     s   
zSerializableTokenCache.addNc                    s   t t| ||| d| _d S r   )r   r   r   r   )r)   r;   r   r   r   r
   r   r     s   

zSerializableTokenCache.modifyc                 C   sF   | j  |rt|ni | _d| _W d   dS 1 sw   Y  dS )zEDeserialize the cache from a state previously obtained by serialize()FN)r1   rl   rt   r2   r   )r)   stater
   r
   r   deserialize  s   "z"SerializableTokenCache.deserializec                 C   s@   | j  d| _tj| jddW  d   S 1 sw   Y  dS )z0Serialize the current cache state into a string.Frg   )rh   N)r1   r   rl   rm   r2   r(   r
   r
   r   	serialize  s   $z SerializableTokenCache.serializer   )
r   r   r   r   r   rp   r   r   r   __classcell__r
   r
   r   r   r     s     r   )rl   r/   rR   loggingrX   	authorityr   Zoauth2cli.oidcr   r   Zoauth2cli.oauth2r   	getLoggerr   rj   r   r   r   objectr   r   r
   r
   r
   r   <module>   s     
  o