U
    4Je3                     @   s  d Z ddlZddlZddl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 z8dd	lmZ dd
lmZmZ ddlmZ ddlmZ W n  ek
r   eddY nX zddlmZmZ W n  ek
r   eddY nX ddlmZ dZdZdZdZ dZ!G dd deZ"dS )zOCI Authentication Plugin.    N)	b64encode)Path)AnyDictOptional   )errors)logger)UnsupportedAlgorithm)hashesserialization)padding)PRIVATE_KEY_TYPESz'Package 'cryptography' is not installed)config
exceptionszGPackage 'oci' (Oracle Cloud Infrastructure Python SDK) is not installed   )BaseAuthPluginMySQLOCIAuthPlugini (  z0Ephemeral security token is too large (10KB max)zGEphemeral security token file ('security_token_file') could not be readzKOCI configuration file does not contain a 'fingerprint' or 'key_file' entryc                   @   s   e Zd ZU dZdZeed< dZeed< dZ	e
ed< dZeed	< ejZeed
< eeeee
f edddZeeedddZeee
f dddZdee edddZdS )r   z2Implement the MySQL OCI IAM authentication plugin.Zauthentication_oci_clientplugin_nameFrequires_sslNcontextDEFAULToci_config_profileoci_config_file)	signature
oci_configreturnc              
   C   s   t | }|d | d}|drz8t|d }| jtkrJtt	|j
dd|d< W n2 ttfk
r } ztt|W 5 d}~X Y nX tj|dd	S )
a=  Prepare client's authentication response

        Prepares client's authentication response in JSON format
        Args:
            signature (bytes):  server's nonce to be signed by client.
            oci_config (dict): OCI configuration object.

        Returns:
            str: JSON string with the following format:
                 {"fingerprint": str, "signature": str, "token": base64.base64.base64}

        Raises:
            ProgrammingError: If the ephemeral security token file can't be open or the
                              token is too large.
        fingerprint)r   r   security_token_filezutf-8)encodingtokenN),:)
separators)r   decodegetr   statst_sizeOCI_SECURITY_TOKEN_MAX_SIZEr   ProgrammingErrorOCI_SECURITY_TOKEN_TOO_LARGE	read_textOSErrorUnicodeError%OCI_SECURITY_TOKEN_FILE_NOT_AVAILABLEjsondumps)r   r   Zsignature_64auth_responser   err r3   U/tmp/pip-unpacked-wheel-7_167w8m/mysql/connector/plugins/authentication_oci_client.py_prepare_auth_responseP   s"    	

z)MySQLOCIAuthPlugin._prepare_auth_response)key_pathr   c                 C   sz   z4t tj| d}tj| dd}W 5 Q R X W n@ ttt	t
fk
rt } ztd|  d| W 5 d}~X Y nX |S )z+Get the private_key form the given locationrbN)passwordz2An error occurred while reading the API_KEY from "z": )openospath
expanduserr   Zload_pem_private_keyread	TypeErrorr,   
ValueErrorr
   r   r)   )r6   key_fileprivate_keyr2   r3   r3   r4   _get_private_keyx   s    z#MySQLOCIAuthPlugin._get_private_key)r   c                 C   s   g }dd dd d}i }zt | jp*t j| jp2d}| D ]X\}}z*|| rn||| sn|d| d W q> tk
r   |d|  Y q>X q>W nD tj	tj
tjtjtjfk
r } z|t| W 5 d	}~X Y nX |rtd
| j d| |S )z=Get a valid OCI config from the given configuration file pathc                 S   s   t | dkS )N    )lenxr3   r3   r4   <lambda>       z:MySQLOCIAuthPlugin._get_valid_oci_config.<locals>.<lambda>c                 S   s   t jt j| S )N)r:   r;   existsr<   rE   r3   r3   r4   rG      rH   )r   r@   r   zParameter "z" is invalidzDoes not contain parameter NzInvalid oci-config-file: z. Errors found: )r   	from_filer   DEFAULT_LOCATIONr   itemsappendKeyErrorr   ZConfigFileNotFoundZInvalidConfigZInvalidKeyFilePathZInvalidPrivateKeyZProfileNotFoundstrr   r)   )selfZ
error_listZreq_keysr   Zreq_keyZ	req_valuer2   r3   r3   r4   _get_valid_oci_config   s:    
 z(MySQLOCIAuthPlugin._get_valid_oci_config)	auth_datar   c                 C   sd   t d| jt| j |  }| |d }|| jt t	
 }| ||}t d| | S )z-Prepare authentication string for the server.zserver nonce: %s, len %dr@   zauthentication response: %s)r	   debugZ
_auth_datarD   rQ   rB   signr   ZPKCS1v15r   SHA256r5   encode)rP   rR   r   rA   r   r1   r3   r3   r4   r1      s      z MySQLOCIAuthPlugin.auth_response)N)__name__
__module____qualname____doc__r   rO   __annotations__r   boolr   r   r   r   rK   r   staticmethodbytesr   r5   r   rB   rQ   r   r1   r3   r3   r3   r4   r   G   s   
'()#rZ   r/   r:   base64r   pathlibr   typingr   r   r    r   r	   Zcryptography.exceptionsr
   Zcryptography.hazmat.primitivesr   r   Z)cryptography.hazmat.primitives.asymmetricr   Z/cryptography.hazmat.primitives.asymmetric.typesr   ImportErrorr)   Zocir   r   r   ZAUTHENTICATION_PLUGIN_CLASSr(   r*   r.   ZOCI_PROFILE_MISSING_PROPERTIESr   r3   r3   r3   r4   <module>   s>   