o
    iH                     @   sz  d dl Z d dlZd dl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 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 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 ddlmZ ddlmZ ddlmZ ddlm Z  G dd de!Z"G dd de#Z$G dd de"Z%G dd de"Z&G dd de"Z'dd  Z(d!d" Z)d#d$ Z*G d%d& d&ee+Z,dS )'    N)input)buildwraps)ServiceAccountCredentials)FlowExchangeError)AccessTokenRefreshError)OAuth2WebServerFlow)OOB_CALLBACK_URN)Storage)ClientRedirectHandler)ClientRedirectServer)scopes_to_string   )ApiAttribute)ApiAttributeMixin)LoadSettingsFile)ValidateSettings)SettingsError)InvalidConfigErrorc                   @      e Zd ZdZdS )	AuthErrorz3Base error for authentication/authorization errors.N__name__
__module____qualname____doc__ r   r   G/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/pydrive/auth.pyr          r   c                   @   r   )InvalidCredentialsErrorz&Error trying to read credentials file.Nr   r   r   r   r   r       r   r    c                   @   r   )AuthenticationRejectedzUser rejected authentication.Nr   r   r   r   r   r!   "   r   r!   c                   @   r   )AuthenticationErrorzGeneral authentication error.Nr   r   r   r   r   r"   &   r   r"   c                   @   r   )RefreshErrorzAccess token refresh error.Nr   r   r   r   r   r#   *   r   r#   c                       t   fdd}|S )z>Decorator to check if the auth is valid and loads auth if not.c                    s   | j d u r	t | _ | j jr t| dddkr| j   n| j   | j jd u r+| j   |d urTd|v rT|d d urTd|d v rT|d d d urT|d d | _|d d= n| j 	 | _ | g|R i |S )Nauth_methodFserviceparamhttp)
auth
GoogleAuthaccess_token_expiredgetattrServiceAuthLocalWebserverAuthr&   	Authorizer(   Get_Http_Object)selfargskwargs	decorateer   r   
_decorated/   s"   


zLoadAuth.<locals>._decoratedr   r5   r6   r   r4   r   LoadAuth-   s   r8   c                    r$   )z'Decorator to authorize service account.c                    s   d| _ d}| jd}| jd u r|r|   | jd u r- | g|R i | |   d}n| jrL| jjd ur;|   n | g|R i | |   d}|rV|rX| 	  d S d S d S )Nr&   Fsave_credentialsT)
r%   settingsgetcredentialsLoadCredentialsr/   r+   refresh_tokenRefreshSaveCredentials)r1   r2   r3   dirtyr9   r4   r   r   r6   P   s$   

z$CheckServiceAuth.<locals>._decoratedr   r7   r   r4   r   CheckServiceAuthN   s   rB   c                    r$   )z6Decorator to check if it requires OAuth2 flow request.c                    s   d}d }| j d}| jd u r|r|   | jd u r|   | jd u r1 | g|R i |}d}n| jrL| jjd ur?|   n | g|R i |}d}|d urU| 	| |r_|ra| 
  d S d S d S )NFr9   T)r:   r;   r<   r=   flowGetFlowr+   r>   r?   Authr@   )r1   r2   r3   rA   coder9   r4   r   r   r6   i   s(   



zCheckAuth.<locals>._decoratedr   r7   r   r4   r   	CheckAuthg   s   rG   c                   @   s,  e Zd ZdZddddgdZg dZg dZed	Zed
Z	edZ
edZedZedZedZd;ddZedd Ze		d<ddZedd Zedd Zd=ddZd=dd Zd=d!d"Zd=d#d$Zd=d%d&Zd=d'd(Zd)d* Zd+d, Zd-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#d7d8 Z$d9d: Z%dS )>r*   zWrapper class for oauth2client library in google-api-python-client.

  Loads all settings and credentials from one 'settings.yaml' file
  and performs common OAuth2.0 related functionality such as authentication
  and authorization.
  filezclient_secrets.jsonFz%https://www.googleapis.com/auth/drive)client_config_backendclient_config_filer9   oauth_scope)	client_idclient_secretauth_uri	token_uri
revoke_uriredirect_uri)client_service_emailclient_user_emailclient_pkcs12_file_pathr:   client_configrC   r<   r(   r&   r%   settings.yamlNc                 C   sf   || _ t|  i | _zt|| _W n ty    | j| _Y dS w | jdu r,| j| _dS t| j dS )zCreate an instance of GoogleAuth.

    This constructor just sets the path of settings file.
    It does not actually read the file.

    :param settings_file: path of settings file. 'settings.yaml' by default.
    :type settings_file: str.
    N)	http_timeoutr   __init__rU   r   r:   r   DEFAULT_SETTINGSr   )r1   settings_filerW   r   r   r   rX      s   	

zGoogleAuth.__init__c                 C   s   | j du rdS | j jS )zChecks if access token doesn't exist or is expired.

    :returns: bool -- True if access token doesn't exist or is expired.
    NT)r<   r+   r1   r   r   r   r+      s   
zGoogleAuth.access_token_expired	localhostc           
      C   s"  |du rddg}d}d}|D ]#}|}z	t ||ft}W n tjy. } zW Y d}~qd}~ww d} |r;d||f }ntd td	 td
 t || j_|  }	t	j
|	ddd td t  td|	  t  |  d|jv r{td tdd|jv r|jd S td td td)a  Authenticate and authorize from user by creating local web server and
    retrieving authentication code.

    This function is not for web server application. It creates local web server
    for user from standalone application.

    :param host_name: host name of the local web server.
    :type host_name: str.
    :param port_numbers: list of port numbers to be tried to used.
    :type port_numbers: list.
    :returns: str -- code returned from local web server
    :raises: AuthenticationRejected, AuthenticationError
    Ni  i  Fr   Tzhttp://%s:%s/z>Failed to start a local web server. Please check your firewallz=settings and locally running programs that may be blocking orz8using configured ports. Default ports are 8080 and 8090.r   )new	autoraisez&Your browser has been opened to visit:    errorz#Authentication request was rejectedzUser rejected authenticationrF   z>Failed to find "code" in the query parameters of the redirect.zTry command-line authenticationzNo code found in redirect)r   r   socketr`   printr"   rC   rQ   
GetAuthUrl
webbrowseropenhandle_requestquery_paramsr!   )
r1   	host_nameport_numberssuccessport_numberporthttpdeoauth_callbackauthorize_urlr   r   r   r.      sH   


zGoogleAuth.LocalWebserverAuthc                 C   s<   t | j_|  }td t  td|  t  td S )zAuthenticate and authorize from user by printing authentication url
    retrieving authentication code from command-line.

    :returns: str -- code returned from commandline.
    z)Go to the following link in your browser:r_   zEnter verification code: )r
   rC   rQ   rc   rb   r   strip)r1   rp   r   r   r   CommandLineAuth   s   zGoogleAuth.CommandLineAuthc                 C   sx   t | jt | j r|   t| jd }| jd}| jd }| jd }tj|||d| _	|r:| j	j
|d| _	dS dS )zAuthenticate and authorize using P12 private key, client id
    and client email for a Service account.
    :raises: AuthError, InvalidConfigError
    rK   rS   rR   rT   )service_account_emailfilenamescopes)subN)setSERVICE_CONFIGS_LISTrU   LoadServiceConfigSettingsr   r:   r;   r   from_p12_keyfiler<   create_delegated)r1   ru   
user_emailservice_email	file_pathr   r   r   r-     s   

zGoogleAuth.ServiceAuthc                 C   @   |du r| j d}|du rtd|dkr|   dS td)zLoads credentials or create empty credentials if it doesn't exist.

    :param backend: target backend to save credential to.
    :type backend: str.
    :raises: InvalidConfigError
    Nsave_credentials_backend!Please specify credential backendrH    Unknown save_credentials_backend)r:   r;   r   LoadCredentialsFiler1   backendr   r   r   r=     s   zGoogleAuth.LoadCredentialsc                 C   sT   |du r| j d}|du rtdzt|}| | _W dS  ty)   tdw )a%  Loads credentials or create empty credentials if it doesn't exist.

    Loads credentials file from path in settings if not specified.

    :param credentials_file: path of credentials file to read.
    :type credentials_file: str.
    :raises: InvalidConfigError, InvalidCredentialsError
    Nsave_credentials_file'Please specify credentials file to read(Credentials file cannot be symbolic link)r:   r;   r   r   r<   IOErrorr    r1   credentials_filestorager   r   r   r   %  s   	zGoogleAuth.LoadCredentialsFilec                 C   r   )a$  Saves credentials according to specified backend.

    If you have any specific credentials backend in mind, don't use this
    function and use the corresponding function you want.

    :param backend: backend to save credentials.
    :type backend: str.
    :raises: InvalidConfigError
    Nr   r   rH   r   )r:   r;   r   SaveCredentialsFiler   r   r   r   r@   8  s   
zGoogleAuth.SaveCredentialsc                 C   st   | j du r	td|du r| jd}|du rtdzt|}|| j  | j | W dS  ty9   tdw )zSaves credentials to the file in JSON format.

    :param credentials_file: destination to save file to.
    :type credentials_file: str.
    :raises: InvalidConfigError, InvalidCredentialsError
    NzNo credentials to saver   r   r   )	r<   r    r:   r;   r   r   put	set_storer   r   r   r   r   r   K  s   
zGoogleAuth.SaveCredentialsFilec                 C   sh   |du r| j d}|du rtd|dkr|   dS |dkr&|   dS |dkr0|   dS td)aQ  Loads client configuration according to specified backend.

    If you have any specific backend to load client configuration from in mind,
    don't use this function and use the corresponding function you want.

    :param backend: backend to load client configuration from.
    :type backend: str.
    :raises: InvalidConfigError
    NrI   z$Please specify client config backendrH   r:   r&   zUnknown client_config_backend)r:   r;   r   LoadClientConfigFileLoadClientConfigSettingsry   r   r   r   r   LoadClientConfig_  s   
zGoogleAuth.LoadClientConfigc              
   C   s   |du r	| j d }z	t|\}}W n tjy% } ztd| d}~ww |tjtjfvr2tdz#g d}|D ]	}|| | j|< q9|d| jd< |d d | jd	< W n t	y`   td
w dg}z|D ]	}|| | j|< qgW dS  t	y}   Y dS w )a  Loads client configuration file downloaded from APIs console.

    Loads client config file from path in settings if not specified.

    :param client_config_file: path of client config file to read.
    :type client_config_file: str.
    :raises: InvalidConfigError
    NrJ   zInvalid client secrets file %sz)Unknown client_type of client config file)rL   rM   rN   rO   rP   redirect_urisr   rQ   z"Insufficient client config in fileclient_email)
r:   clientsecretsloadfileInvalidClientSecretsErrorr   TYPE_WEBTYPE_INSTALLEDrU   r;   KeyError)r1   rJ   client_typeclient_infor`   config_indexconfigservice_auth_configr   r   r   r   v  s:   	
zGoogleAuth.LoadClientConfigFilec              	   C   sP   | j D ]"}z| jd | | j|< W q ty%   d}|d|7 }t|w dS )zSLoads client configuration from settings file.
    :raises: InvalidConfigError
    service_configz'Insufficient service config in settingsz

Missing: {} key.N)rx   r:   rU   r   formatr   )r1   r   errr   r   r   ry     s   
z$GoogleAuth.LoadServiceConfigSettingsc              	   C   s>   | j D ]}z| jd | | j|< W q ty   tdw dS )zTLoads client configuration from settings file.

    :raises: InvalidConfigError
    rU   z&Insufficient client config in settingsN)CLIENT_CONFIGS_LISTr:   rU   r   r   )r1   r   r   r   r   r     s   
z#GoogleAuth.LoadClientConfigSettingsc                    s   t  fdd jD s    jd  jd  jd d} jd dur- jd |d< t jd	  jd
 t jd fi | _ jdrU jj	
ddd dS dS )zQGets Flow object from client configuration.

    :raises: InvalidConfigError
    c                 3   s    | ]}| j v V  qd S N)rU   ).0r   r[   r   r   	<genexpr>  s    z%GoogleAuth.GetFlow.<locals>.<genexpr>rQ   rN   rO   )rQ   rN   rO   rP   NrL   rM   rK   get_refresh_tokenofflineforce)access_typeapproval_prompt)allr   r   rU   r	   r   r:   rC   r;   paramsupdate)r1   constructor_kwargsr   r[   r   rD     s.   zGoogleAuth.GetFlowc              
   C   sz   | j du r	td| j jdu rtd| jdu r tj| jd| _z
| j | j W dS  ty< } ztd| d}~ww )z;Refreshes the access_token.

    :raises: RefreshError
    NzNo credential to refresh.zBNo refresh_token found.Please set access_type of OAuth to offline.timeoutzAccess token refresh failed: %s)	r<   r#   r>   r(   httplib2HttprW   refreshr   )r1   r`   r   r   r   r?     s   

zGoogleAuth.Refreshc                 C   s   | j du r	|   | j  S )zlCreates authentication url where user visits to grant access.

    :returns: str -- Authentication url.
    N)rC   rD   step1_get_authorize_urlr[   r   r   r   rc     s   

zGoogleAuth.GetAuthUrlc                 C   s   |  | |   dS )zAuthenticate, authorize, and build service.

    :param code: Code for authentication.
    :type code: str.
    :raises: AuthenticationError
    N)Authenticater/   )r1   rF   r   r   r   rE     s   
zGoogleAuth.Authc              
   C   sV   | j du r	|   z	| j || _W n ty$ } ztd| d}~ww td dS )zAuthenticates given authentication code back from user.

    :param code: Code for authentication.
    :type code: str.
    :raises: AuthenticationError
    NzOAuth2 code exchange failed: %szAuthentication successful.)rC   rD   step2_exchanger<   r   r"   rb   )r1   rF   rn   r   r   r   r     s   
zGoogleAuth.Authenticatec                 C   sN   | j du rtj| jd| _ | jrtd| j| j | _ tdd| j d| _	dS )zEAuthorizes and builds service.

    :raises: AuthenticationError
    Nr   z*No valid credentials provided to authorizedrivev2)r(   )
r(   r   r   rW   r+   r"   r<   	authorizer   r&   r[   r   r   r   r/     s   
zGoogleAuth.Authorizec                 C   s   t j| jd}| j|}|S )zCreate and authorize an httplib2.Http object. Necessary for
    thread-safety.
    :return: The http object to be used in each call.
    :rtype: httplib2.Http
    r   )r   r   rW   r<   r   )r1   r(   r   r   r   r0     s   zGoogleAuth.Get_Http_Object)rV   N)r\   Nr   )&r   r   r   r   rY   r   rx   r   r:   rU   rC   r<   r(   r&   r%   rX   propertyr+   rG   r.   rr   rB   r-   r=   r   r@   r   r   r   ry   r   rD   r?   rc   rE   r   r/   r0   r   r   r   r   r*      sT    

	6







&	
r*   )-ra   rd   r   oauth2client.clientsecretsr   	six.movesr   apiclient.discoveryr   	functoolsr   oauth2client.service_accountr   oauth2client.clientr   r   r	   r
   oauth2client.filer   oauth2client.toolsr   r   oauth2client._helpersr   apiattrr   r   r:   r   r   r   r   	Exceptionr   r   r    r!   r"   r#   r8   rB   rG   objectr*   r   r   r   r   <module>   s>    !