o
    i8                     @   s  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mZmZm	Z	m
Z
 ddlmZ ddlmZmZmZ ddlmZ ddlmZ d	d
lmZ d	dlmZ d	dlmZmZ d	dlmZ ejZee Z!dej" ddej# ddej$ diZ%de&fddZ'dd Z(G dd deeZ)dS )zIBase class for credentials using MSAL for interactive user authentication    N)AnyOptionalIterableDict)urlparse)AccessTokenAccessTokenInfoTokenRequestOptions)ClientAuthenticationError   )MsalCredential   )AuthenticationRecord)KnownAuthorities)AuthenticationRequiredErrorCredentialUnavailableError)wrap_exceptionszhttps://)z2https://management.core.chinacloudapi.cn//.default)z3https://management.core.usgovcloudapi.net//.default)z-https://management.core.windows.net//.defaultreturnc                 C   s.   | dt |  d  7 } t| } t| dS )zDecode client info. Taken from msal.oauth2cli.oidc.

    :param str raw: base64-encoded client info
    :return: decoded client info
    :rtype: str
    =   zutf-8)lenstrbase64urlsafe_b64decodedecode)raw r   [/home/app/Keep/.python/lib/python3.10/site-packages/azure/identity/_internal/interactive.py_decode_client_info#   s   r   c           	   
   C   s   zE| d }d| v rt t| d }djdi |}n|d }t|d }|dp/|jd}|dp8|d	 }t|j	|d
 |||dW S  t
tfy[ } ztdd}||d}~ww )a~  Build an AuthenticationRecord from the result of an MSAL ClientApplication token request.

    :param response: The result of a token request
    :type response: dict[str, typing.Any]
    :return: An AuthenticationRecord
    :rtype: ~azure.identity.AuthenticationRecord
    :raises ~azure.core.exceptions.ClientAuthenticationError: If the response doesn't contain expected data
    Zid_token_claimsclient_infoz{uid}.{utid}subZisstid/Zpreferred_usernameZupnZaud)	authority	client_idhome_account_id	tenant_idusernamezCFailed to build AuthenticationRecord from unexpected identity tokenmessageNr   )jsonloadsr   formatr   getpathstripr   netlocKeyError
ValueErrorr
   )	responseZid_tokenr   r%   Zissuerr&   r'   exZ
auth_errorr   r   r   _build_auth_record0   s.   
r5   c                       s$  e Zd Zddddee dededdf fdd	Zdddd
dedee dee dedede	fddZ
dddedee defddZddddedee dededef
ddZddddddeee  dee dee dededefddZedededefddZejdefdd Z  ZS )!InteractiveCredentialNF)authentication_record disable_automatic_authenticationr7   r8   kwargsr   c                   sv   || _ || _| jr.|dd  |dd p| jj}tt| jd| jj| jj|d| d S tt| jdi | d S )Nr$   r&   )r$   r#   r&   r   )	!_disable_automatic_authentication_auth_recordpopr&   superr6   __init__r$   r#   )selfr7   r8   r9   r&   	__class__r   r   r>   \   s   
zInteractiveCredential.__init__claimsr&   
enable_caescopesrC   r&   rD   c                O   sH   i }|r||d< |r||d< ||d< | j ||dd|}t|j|jS )a  Request an access token for `scopes`.

        This method is called automatically by Azure SDK clients.

        :param str scopes: desired scopes for the access token. This method requires at least one scope.
            For more information about scopes, see
            https://learn.microsoft.com/entra/identity-platform/scopes-oidc.
        :keyword str claims: additional claims required in the token, such as those returned in a resource provider's
            claims challenge following an authorization failure
        :keyword str tenant_id: optional tenant to include in the token request.
        :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested
            token. Defaults to False.
        :return: An access token with the desired scopes.
        :rtype: ~azure.core.credentials.AccessToken
        :raises CredentialUnavailableError: the credential is unable to attempt authentication because it lacks
            required data, state, or platform support
        :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message``
            attribute gives a reason.
        :raises AuthenticationRequiredError: user interaction is necessary to acquire a token, and the credential is
            configured not to begin this automatically. Call :func:`authenticate` to begin interactive authentication.
        rC   r&   rD   	get_tokenoptionsbase_method_name)_get_token_baser   tokenZ
expires_on)r?   rC   r&   rD   rE   r9   rH   Z
token_infor   r   r   rF   q   s   zInteractiveCredential.get_token)rH   rH   c                G   s   | j ||ddS )a&  Request an access token for `scopes`.

        This is an alternative to `get_token` to enable certain scenarios that require additional properties
        on the token. This method is called automatically by Azure SDK clients.

        :param str scopes: desired scopes for the access token. This method requires at least one scope.
            For more information about scopes, see https://learn.microsoft.com/entra/identity-platform/scopes-oidc.
        :keyword options: A dictionary of options for the token request. Unknown options will be ignored. Optional.
        :paramtype options: ~azure.core.credentials.TokenRequestOptions

        :rtype: AccessTokenInfo
        :return: An AccessTokenInfo instance containing information about the token.

        :raises CredentialUnavailableError: the credential is unable to attempt authentication because it lacks
            required data, state, or platform support
        :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message``
            attribute gives a reason.
        :raises AuthenticationRequiredError: user interaction is necessary to acquire a token, and the credential is
            configured not to begin this automatically. Call :func:`authenticate` to begin interactive authentication.
        get_token_inforG   )rJ   )r?   rH   rE   r   r   r   rL      s   z$InteractiveCredential.get_token_inforL   rG   rI   c                O   s  |sd| d}t d| jj|| t||d| j }|p!i }|d}|d}|dd}	|D ]}
|
tj	vrC|
|
||
  q4z| j||||	d	|}t d
| jj| |W S  ty } zt|trk|s|t jd| jj||t tjd  W Y d }~nd }~ww tt }z0| j||||	d	|}d|vrd|dp|d}| j|}t||dt|| _W n ty } zt jd| jj||t tjd  d }~ww t d
| jj| d|v rt|d nd }t|d |t|d  |dd|dS )N'z' requires at least one scopez%s.%s failed: %s_allow_promptrC   r&   rD   FrB   z%s.%s succeeded)exc_infoaccess_tokenzAuthentication failed: {}Zerror_descriptionerror)r)   r3   
refresh_on
expires_in
token_typeBearerrT   rR   )_LOGGERwarningrA   __name__r2   r<   r:   r-   r	   __annotations__
setdefault_acquire_token_silentinfo	Exception
isinstancer   isEnabledForloggingDEBUGinttime_request_tokenr,   _clientget_error_responser
   r5   r;   r   )r?   rH   rI   rE   r9   r)   Zallow_promptrC   r&   rD   keyrK   r4   nowresultr3   rR   r   r   r   rJ      sz   






z%InteractiveCredential._get_token_base)rE   rC   r&   rD   c                K   sB   |s| j tvrtddt| j  }| j|d|||d|}| jS )ai  Interactively authenticate a user. This method will always generate a challenge to the user.

        :keyword Iterable[str] scopes: scopes to request during authentication, such as those provided by
          :func:`AuthenticationRequiredError.scopes`. If provided, successful authentication will cache an access token
          for these scopes.
        :keyword str claims: additional claims required in the token, such as those provided by
          :func:`AuthenticationRequiredError.claims`
        :keyword str tenant_id: optional tenant to include in the token request.
        :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested
            token. Access tokens retrieved with CAE enabled will be cached separately from other tokens.
            Defaults to False.
        :return: An AuthenticationRecord containing the authenticated user's information.
        :rtype: ~azure.identity.AuthenticationRecord
        :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message``
          attribute gives a reason.
        zVAuthenticating in this environment requires a value for the 'scopes' keyword argument.r(   T)rN   rC   r&   rD   )Z
_authority_DEFAULT_AUTHENTICATE_SCOPESr   rF   r;   )r?   rE   rC   r&   rD   r9   _r   r   r   authenticate   s   


z"InteractiveCredential.authenticatec           
      O   s   d }| d}| jrc| jdi |}|j| jjdD ]H}| d| jjkr&qtt }|jt	|||d}|rbd|v rbd|v rbd|v rJt|d nd }t
|d |t|d  | dd	|d
  S q|rr| j|}	t|||	dt||d)NrC   )r'   r%   )accountZclaims_challengerP   rS   rR   rT   rU   rV   )rC   r3   )rC   r   )r-   r;   Z_get_appZget_accountsr'   r%   rc   rd   Zacquire_token_silent_with_errorlistr   rf   rg   r   )
r?   rE   r9   rj   rC   apprn   ri   rR   r3   r   r   r   r\     s,   


z+InteractiveCredential._acquire_token_silentc                 O   s   d S )Nr   )r?   rE   r9   r   r   r   re   9  s   z$InteractiveCredential._request_token)rY   
__module____qualname__r   r   boolr   r>   r   r   rF   r	   r   rL   rJ   r   rm   r   r\   abcabstractmethodr   re   __classcell__r   r   r@   r   r6   [   s~    
 '
J

(r6   )*__doc__rt   r   r*   ra   rd   typingr   r   r   r   urllib.parser   Zazure.core.credentialsr   r   r	   Zazure.core.exceptionsr
   Zmsal_credentialsr   r;   r   
_constantsr   _exceptionsr   r   	_internalr   ABC	getLoggerrY   rW   ZAZURE_CHINAZAZURE_GOVERNMENTZAZURE_PUBLIC_CLOUDrk   r   r   r5   r6   r   r   r   r   <module>   s0   



+