o
    >cnA                     @   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ZddlZddlZddl	m
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 e ZdZdZdZdZd	Zg d
ZG dd deZ	ddejj j!fddZ"G dd dZ#G dd dej$Z%dd Z&dS )z8Provides authentication support for TensorBoardUploader.    N)util)
tb_logging)Zopenidz.https://www.googleapis.com/auth/userinfo.emaila	  
    {
        "installed":{
            "client_id":"373649185512-8v619h5kft38l4456nm2dj4ubeqsrvh6.apps.googleusercontent.com",
            "project_id":"hosted-tensorboard-prod",
            "auth_uri":"https://accounts.google.com/o/oauth2/auth",
            "token_uri":"https://oauth2.googleapis.com/token",
            "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
            "client_secret":"pOyAuU2yq2arsM98Bw5hwYtr",
            "redirect_uris":["http://localhost"]
        }
    }
z)https://oauth2.googleapis.com/device/codez,urn:ietf:params:oauth:grant-type:device_codea  
    {
        "installed":{
            "client_id":"373649185512-26ojik4u7dt0rdtfdmfnhpajqqh579qd.apps.googleusercontent.com",
            "project_id":"hosted-tensorboard-prod",
            "auth_uri":"https://accounts.google.com/o/oauth2/auth",
            "token_uri":"https://oauth2.googleapis.com/token",
            "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
            "client_secret":"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"
        }
    }
)Ztensorboardcredentialszuploader-creds.jsonc                   @   s:   e Zd ZdZe ZefddZdd Zdd Zdd	 Z	d
S )CredentialsStorezAPrivate file store for a `google.oauth2.credentials.Credentials`.c                 C   sP   |t ju rt }|du rtd |du rd| _dS tjj	|gt
R  | _dS )aw  Creates a CredentialsStore.

        Args:
          user_config_directory: Optional absolute path to the root directory for
            storing user configs, under which to store the credentials file. If not
            set, defaults to a platform-specific location. If set to None, the
            store is disabled (reads return None; write and clear are no-ops).
        Nz@Credentials caching disabled - no private config directory found)r   _DEFAULT_CONFIG_DIRECTORYr   Zget_user_config_directoryloggerZwarning_credentials_filepathospathjoin&TENSORBOARD_CREDENTIALS_FILEPATH_PARTS)selfZuser_config_directory r   9lib/python3.10/site-packages/tensorboard/uploader/auth.py__init__   s   
	
zCredentialsStore.__init__c                 C   s2   | j du rdS tj| j rtjjj| j S dS )zMReturns the current `google.oauth2.credentials.Credentials`, or
        None.N)	r   r	   r
   existsgoogleoauth2r   CredentialsZfrom_authorized_user_file)r   r   r   r   read_credentials   s   

z!CredentialsStore.read_credentialsc                 C   s   t |tjjjstdt| | jdu rdS tj	dk}t
j| j|d |j|j|j|j|jdd}t| jd}t|| W d   dS 1 sJw   Y  dS )z>Writes a `google.oauth2.credentials.Credentials` to the store.z#Cannot write credentials of type %sNnt)privateZauthorized_user)refresh_token	token_uri	client_idclient_secretscopestypew)
isinstancer   r   r   r   	TypeErrorr   r   r	   namer   Zmake_file_with_directoriesr   r   r   r   r   openjsondump)r   r   r   datafr   r   r   write_credentials   s(   


"z"CredentialsStore.write_credentialsc              
   C   sV   | j du rdS z	t| j  W dS  ty* } z|jtjkr W Y d}~dS d}~ww )z:Clears the store of any persisted credentials information.N)r   r	   removeOSErrorerrnoENOENT)r   er   r   r   clear   s   
zCredentialsStore.clearN)
__name__
__module____qualname____doc__objectr   r   r   r'   r-   r   r   r   r   r   |   s    r   Freturnc                 C   sz   t }| s.tdr.ztt}tjj||d}|j	ddW S  t
jy-   tjd Y nw tt}t||d}| S )a+  Makes the user authenticate to retrieve auth credentials.

    The default behavior is to use the [installed app flow](
    http://developers.google.com/identity/protocols/oauth2/native-app), in which
    a browser is started for the user to authenticate, along with a local web
    server. The authentication in the browser would produce a redirect response
    to `localhost` with an authorization code that would then be received by the
    local web server started here.

    The two most notable cases where the default flow is not well supported are:
    - When the uploader is run from a colab notebook.
    - Then the uploader is run via a remote terminal (SSH).

    If any of the following is true, a different auth flow will be used:
    - the flag `--auth_force_console` is set to true, or
    - a browser is not available, or
    - a local web server cannot be started

    In this case, a [limited-input device flow](
    http://developers.google.com/identity/protocols/oauth2/limited-input-device)
    will be used, in which the user is presented with a URL and a short code
    that they'd need to use to authenticate and authorize access in a separate
    browser or device. The uploader will poll for access until the access is
    granted or rejected, or the initiated authorization request expires.
    ZDISPLAY)r   r   )portz.Falling back to remote authentication flow...
)OPENID_CONNECT_SCOPESr	   getenvr#   loads"_INSTALLED_APP_OAUTH_CLIENT_CONFIG
auth_flowsZInstalledAppFlowZfrom_client_configZrun_local_server
webbrowserErrorsysstderrwrite)_LIMITED_INPUT_DEVICE_OAUTH_CLIENT_CONFIG_LimitedInputDeviceAuthFlowrun)Zforce_consoler   client_configflowr   r   r   authenticate_user   s   

rD   c                   @   s^   e Zd ZdZdd ZdejjjfddZ	dd Z
d	ed
edefddZdejjjfddZdS )r@   zOAuth flow to authenticate using the limited-input device flow.

    See:
    http://developers.google.com/identity/protocols/oauth2/limited-input-device
    c                 C   s   |d | _ || _d S )NZ	installed)_client_config_scopes)r   rB   r   r   r   r   r      s   

z$_LimitedInputDeviceAuthFlow.__init__r3   c                 C   sL   |   }dj|d |d d}t| | j|d |d |d d}| |S )	NzTo sign in with the TensorBoard uploader:

1. On your computer or phone, visit:

   {url}

2. Sign in with your Google account, then enter:

   {code}
Zverification_urlZ	user_code)urlcodedevice_codeinterval
expires_in)rI   polling_intervalexpiration_seconds)_send_device_auth_requestformatprint_poll_for_auth_token_build_credentials)r   Zdevice_responseZprompt_messageauth_responser   r   r   rA     s   
z_LimitedInputDeviceAuthFlow.runc                 C   s>   | j d d| jd}tjt|d }d|vrtd|S )Nr    )r   Zscoper%   rI   zZThere was an error while contacting Google's authorization server. Please try again later.)rE   r   rF   requestspost_DEVICE_AUTH_CODE_URIr#   RuntimeError)r   paramsrr   r   r   rN     s   
z5_LimitedInputDeviceAuthFlow._send_device_auth_requestrI   rL   rM   c           	      C   s   | j d }| j d | j d |td}t | }t |k rvtj||d}| }d|v r/|S d|v r?|d dkr?t| n1d|v rU|d d	krUt|d
 }t| nd|v rc|d dkrctd|j	dv rlt
dtdt |k std)Nr   r   r   )r   r   rI   Z
grant_typerU   access_tokenerrorZauthorization_pendingZ	slow_downg      ?Zaccess_deniedzAccess was denied by user.>   i  i  z&There must be an error in the request.z=An unexpected error occurred while waiting for authorization.z$Timed out waiting for authorization.)rE   %_LIMITED_INPUT_DEVICE_AUTH_GRANT_TYPEtimerV   rW   r#   sleepintPermissionErrorZstatus_code
ValueErrorrY   TimeoutError)	r   rI   rL   rM   r   rZ   Zexpiration_timeZrespr[   r   r   r   rQ   *  s4   

z0_LimitedInputDeviceAuthFlow._poll_for_auth_tokenc              
   C   sZ   t j tt |d  }tjjj|d |d |d | jd | jd | jd | j	|dS )	NrK   r\   r   id_tokenr   r   r   )r   re   r   r   r   r   Zexpiry)
datetimeZutcfromtimestampra   r_   r   r   r   r   rE   rF   )r   rS   Zexpiration_datetimer   r   r   rR   R  s   z._LimitedInputDeviceAuthFlow._build_credentialsN)r.   r/   r0   r1   r   r   r   r   r   rA   rN   strra   rQ   rR   r   r   r   r   r@      s    
(r@   c                       s(   e Zd ZdZ fddZdd Z  ZS )IdTokenAuthMetadataPluginas  A `gRPC AuthMetadataPlugin` that uses ID tokens.

    This works like the existing `google.auth.transport.grpc.AuthMetadataPlugin`
    except that instead of always using access tokens, it preferentially uses the
    `Credentials.id_token` property if available (and logs an error otherwise).

    See http://www.grpc.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin
    c                    s>   t t|   t|tjjjstdt	| || _
|| _dS )a3  Constructs an IdTokenAuthMetadataPlugin.

        Args:
          credentials (google.auth.credentials.Credentials): The credentials to
            add to requests.
          request (google.auth.transport.Request): A HTTP transport request object
            used to refresh credentials as needed.
        z-Cannot get ID tokens from credentials type %sN)superrh   r   r   r   r   r   r   r    r   _credentials_request)r   r   request	__class__r   r   r   o  s   	
z"IdTokenAuthMetadataPlugin.__init__c                 C   s`   i }| j | j|j|j| t| j dd}|r | j j||d ntd |t	|
 d dS )a  Passes authorization metadata into the given callback.

        Args:
          context (grpc.AuthMetadataContext): The RPC context.
          callback (grpc.AuthMetadataPluginCallback): The callback that will
            be invoked to pass in the authorization metadata.
        re   N)tokenz#Failed to find ID token credentials)rj   Zbefore_requestrk   method_nameZservice_urlgetattrZapplyr   r]   listitems)r   contextcallbackZheadersre   r   r   r   __call__  s   
z"IdTokenAuthMetadataPlugin.__call__)r.   r/   r0   r1   r   rv   __classcell__r   r   rm   r   rh   e  s    	rh   c                 C   s   t jjj }tt| |S )zConstructs `grpc.CallCredentials` using
    `google.auth.Credentials.id_token`.

    Args:
      credentials (google.auth.credentials.Credentials): The credentials to use.

    Returns:
      grpc.CallCredentials: The call credentials.
    )r   ZauthZ	transportrV   ZRequestgrpcZmetadata_call_credentialsrh   )r   rl   r   r   r   id_token_call_credentials  s   
ry   )F)'r1   rf   r*   r#   r	   rV   r<   r_   r:   Zgoogle_auth_oauthlib.flowrC   r9   rx   Zgoogle.authr   Zgoogle.auth.transport.requestsZgoogle.oauth2.credentialsZtensorboard.uploaderr   Ztensorboard.utilr   Z
get_loggerr   r5   r8   rX   r^   r?   r   r2   r   r   r   r   rD   r@   ZAuthMetadataPluginrh   ry   r   r   r   r   <module>   s@   N
-o1