o
    䯪gSV                     @   s  d dl Z d dlmZ d dlZzd dlmZ d dlm  m	Z
 W n ey,   dZdZ
Y n	w d dlmZmZ dZdZdZdZdZe jje jjgZe jd	d
dd Ze jd	d
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z dd Z!dd  Z"d!d" Z#d#d$ Z$d%d& Z%d'd( Z&d)d* Z'd+d, Z(d-d. Z)d/d0 Z*e jj+d1d2d3d4 Z,e jj+d5d2d6d7 Z-d8d9 Z.d:d; Z/d<d= Z0dS )>    N)	timedelta)InMemoryKmsClientverify_file_encryptedzencrypted_table.in_mem.parquets   0123456789112345
footer_keys   1234567890123450col_keymodule)scopec                  C   s6   t jt g dt g dt g dd} | S )N)         )abc)xyz)paTablefrom_pydictarray)
data_table r   a/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/pyarrow/tests/parquet/test_encryption.pyr   0   s   r   c                  C   s   t jttddgid} | S )Nr   r   )r   column_keys)peEncryptionConfigurationFOOTER_KEY_NAMECOL_KEY_NAME)basic_encryption_configr   r   r   r   :   s   r   c                 C   s&   t j| d}dd }t |}||fS )z
    Sets up and returns the KMS connection configuration and crypto factory
    based on provided KMS configuration parameters.
    custom_kms_confc                 S      t | S Nr   kms_connection_configurationr   r   r   kms_factoryK      z1setup_encryption_environment.<locals>.kms_factory)r   KmsConnectionConfigCryptoFactory)r    kms_connection_configr&   crypto_factoryr   r   r   setup_encryption_environmentD   s   
r,   c           
      C   s<   || d|| di}t|\}}	t| ||||	 ||	fS )zL
    Writes an encrypted parquet file based on the provided parameters.
    UTF-8)decoder,   write_encrypted_parquet)
pathr   footer_key_namecol_key_namer   r   encryption_configr    r*   r+   r   r   r   write_encrypted_fileT   s   

r4   c                 C   s|   | t  }tjttddgidtdddd}t||tttt|\}}t	| tj
tddd}t||||}||s<J d	S )
zDWrite an encrypted parquet, verify it's encrypted, and then read it.r   r   
AES_GCM_V1      @minutes   r   r   encryption_algorithmcache_lifetimedata_key_length_bitsr<   N)PARQUET_NAMEr   r   r   r   r   r4   
FOOTER_KEYCOL_KEYr   DecryptionConfigurationread_encrypted_parquetequals)tempdirr   r0   r3   r*   r+   decryption_configresult_tabler   r   r   !test_encrypted_parquet_write_readj   s*   	rH   c                 C   sZ   | ||}|d usJ tj| |j|d}|| W d    d S 1 s&w   Y  d S )N)encryption_properties)file_encryption_propertiespqParquetWriterschemawrite_table)r0   tabler3   r*   r+   rJ   writerr   r   r   r/      s   "r/   c                 C   sn   | ||}|d usJ tj| |d}|jdksJ tj| |d}t|jdks*J tj| |d}|jddS )Ndecryption_propertiesr   Tuse_threads)	file_decryption_propertiesrK   read_metadatanum_columnsread_schemalennamesParquetFileread)r0   rF   r*   r+   rU   metarM   resultr   r   r   rC      s    rC   c                 C   s   | t  }tjttddgidtdddd}t||tttt| t	| t
ttdttdi\}}tjtddd	}tjtd
d t|||| W d   dS 1 sVw   Y  dS )zYWrite an encrypted parquet, verify it's encrypted,
    and then read it using wrong keys.r   r   r5   r6   r7   r9   r:   r-   r>   zIncorrect master key usedmatchN)r?   r   r   r   r   r   r4   r@   rA   r   r,   r.   rB   pytestraises
ValueErrorrC   )rE   r   r0   r3   wrong_kms_connection_configwrong_crypto_factoryrF   r   r   r   +test_encrypted_parquet_write_read_wrong_key   s4   
	


"rf   c                 C   sP   t | | tjtdd t| t   W d   dS 1 s!w   Y  dS )zmWrite an encrypted parquet, verify it's encrypted,
    but then try to read it without decryption properties.no decryptionr_   N)rH   ra   rb   IOErrorrK   r[   r?   r\   rE   r   r   r   r   0test_encrypted_parquet_read_no_decryption_config   s   
"rj   c                 C   L   t | | tjtdd t| t  W d   dS 1 sw   Y  dS )zwWrite an encrypted parquet, verify it's encrypted,
    but then try to read its metadata without decryption properties.rg   r_   N)rH   ra   rb   rh   rK   rV   r?   ri   r   r   r   9test_encrypted_parquet_read_metadata_no_decryption_config   s   
"rl   c                 C   rk   )zuWrite an encrypted parquet, verify it's encrypted,
    but then try to read its schema without decryption properties.rg   r_   N)rH   ra   rb   rh   rK   rX   r?   ri   r   r   r   7test_encrypted_parquet_read_schema_no_decryption_config   s   
"rm   c              	   C   s\   | d }t jtd}tjtdd t||tttd| W d   dS 1 s'w   Y  dS )zMWrite an encrypted parquet, but give only footer key,
    without column key.z)encrypted_table_no_col_key.in_mem.parquetr   z4Either column_keys or uniform_encryption must be setr_       N)	r   r   r   ra   rb   OSErrorr4   r   r@   )rE   r   r0   r3   r   r   r   'test_encrypted_parquet_write_no_col_key   s   
"rq   c                 C   j   | d }|}t  }dd }t |}tjtdd t||||| W d   dS 1 s.w   Y  dS )<Write an encrypted parquet, but raise KeyError in KmsClient.(encrypted_table_kms_error.in_mem.parquetc                 S   r!   r"   r#   r$   r   r   r   r&      s   z;test_encrypted_parquet_write_kms_error.<locals>.kms_factoryr   r_   N)r   r(   r)   ra   rb   KeyErrorr/   rE   r   r   r0   r3   r*   r&   r+   r   r   r   &test_encrypted_parquet_write_kms_error   s   
"rw   c                    s   | d }|}t  }G dd dt j  fdd}t |}tjtdd t||||| W d   dS 1 s9w   Y  dS )	rs   rt   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	zJtest_encrypted_parquet_write_kms_specific_error.<locals>.ThrowingKmsClientzVA KmsClient implementation that throws exception in
        wrap/unwrap calls
        c                 S   s   t j|  || _dS )z%Create an InMemoryKmsClient instance.N)r   	KmsClient__init__configselfr{   r   r   r   rz     s   
zStest_encrypted_parquet_write_kms_specific_error.<locals>.ThrowingKmsClient.__init__c                 S      t d)NCannot Wrap Keyrc   r}   	key_bytesmaster_key_identifierr   r   r   wrap_key  r'   zStest_encrypted_parquet_write_kms_specific_error.<locals>.ThrowingKmsClient.wrap_keyc                 S   r~   )NzCannot Unwrap Keyr   r}   wrapped_keyr   r   r   r   
unwrap_key  r'   zUtest_encrypted_parquet_write_kms_specific_error.<locals>.ThrowingKmsClient.unwrap_keyN__name__
__module____qualname____doc__rz   r   r   r   r   r   r   ThrowingKmsClient  s
    r   c                        | S r"   r   r$   r   r   r   r&   "  s   zDtest_encrypted_parquet_write_kms_specific_error.<locals>.kms_factoryr   r_   N)r   r(   ry   r)   ra   rb   rc   r/   rv   r   r   r   /test_encrypted_parquet_write_kms_specific_error	  s   
"r   c                 C   rr   )z@Write an encrypted parquet, but raise ValueError in kms_factory.0encrypted_table_kms_factory_error.in_mem.parquetc                 S   r~   )NCannot create KmsClientr   r$   r   r   r   r&   6  r'   zCtest_encrypted_parquet_write_kms_factory_error.<locals>.kms_factoryr   r_   N)r   r(   r)   ra   rb   rc   r/   rv   r   r   r   .test_encrypted_parquet_write_kms_factory_error-  s   
"r   c                    sx   | d }|}t  }G dd d  fdd}t |}tt t||||| W d   dS 1 s5w   Y  dS )z_Write an encrypted parquet, but use wrong KMS client type
    that doesn't implement KmsClient.r   c                   @   rx   )	zOtest_encrypted_parquet_write_kms_factory_type_error.<locals>.WrongTypeKmsClientz4This is not an implementation of KmsClient.
        c                 S   s   |j | _d S r"   )r    master_keys_mapr|   r   r   r   rz   O  s   zXtest_encrypted_parquet_write_kms_factory_type_error.<locals>.WrongTypeKmsClient.__init__c                 S      d S r"   r   r   r   r   r   r   R     zXtest_encrypted_parquet_write_kms_factory_type_error.<locals>.WrongTypeKmsClient.wrap_keyc                 S   r   r"   r   r   r   r   r   r   U  r   zZtest_encrypted_parquet_write_kms_factory_type_error.<locals>.WrongTypeKmsClient.unwrap_keyNr   r   r   r   r   WrongTypeKmsClientK  s
    r   c                    r   r"   r   r$   r   r   r   r&   X  r'   zHtest_encrypted_parquet_write_kms_factory_type_error.<locals>.kms_factoryN)r   r(   r)   ra   rb   	TypeErrorr/   rv   r   r   r   3test_encrypted_parquet_write_kms_factory_type_errorA  s   
"r   c               
   C   s   dd } t jttddgidddtdd	dd
d}| | t jtd}tddgi|_d|_d|_d|_tdd	|_	d|_
d
|_| | d S )Nc                 S   sv   t | jksJ ddg| jt ksJ d| jksJ | jsJ | jr#J tdd| jks-J | j	r2J d| j
ks9J d S )Nr   r   AES_GCM_CTR_V1      $@r7      )r   r   r   r   r;   plaintext_footerdouble_wrappingr   r<   internal_key_materialr=   )r3   r   r   r   !validate_encryption_configurationc  s   


zZtest_encrypted_parquet_encryption_configuration.<locals>.validate_encryption_configurationr   r   r   TFr   r7   r   )r   r   r;   r   r   r<   r   r=   rn   )r   r   r   r   r   r   r;   r   r   r<   r   r=   )r   r3   encryption_config_1r   r   r   /test_encrypted_parquet_encryption_configurationb  s.   


r   c                  C   sR   t jtddd} tdd| jksJ t  }tdd|_tdd|jks'J d S )Nr   r7   r>   )r   rB   r   r<   )rF   decryption_config_1r   r   r   /test_encrypted_parquet_decryption_configuration  s   r   c                  C   sZ   dd } t jddddddd	}| | t  }d|_d|_d|_ddd|_| | d S )
Nc                 S   sB   d| j ksJ d| jksJ d| jksJ ddd| jksJ d S )N	Instance1URL1MyTokenkey_material_1key_material_2key1key2kms_instance_idkms_instance_urlkey_access_tokenr    )r*   r   r   r   validate_kms_connection_config  s   zPtest_encrypted_parquet_kms_configuration.<locals>.validate_kms_connection_configr   r   r   r   r   r   r   )r   r(   r   r   r   r    )r   r*   kms_connection_config_1r   r   r   (test_encrypted_parquet_kms_configuration  s$   r   zNPlaintext footer - reading plaintext column subset reads encrypted columns too)reasonc                 C   sh   | t  }tjttddgiddd}tjttdttdid}dd	 }t	|}t
||||| d
S )zWrite an encrypted parquet, with plaintext footer
    and with single wrapping,
    verify it's encrypted, and then read plaintext columns.r   r   TF)r   r   r   r   r-   r   c                 S   r!   r"   r#   r$   r   r   r   r&     r'   zStest_encrypted_parquet_write_read_plain_footer_single_wrapping.<locals>.kms_factoryN)r?   r   r   r   r   r(   r@   r.   rA   r)   r/   rE   r   r0   r3   r*   r&   r+   r   r   r   >test_encrypted_parquet_write_read_plain_footer_single_wrapping  s$   


r   z'External key material not supported yetc                 C   sT   | t  }tjti dd}tjttdid}dd }t|}t||||| dS )zWrite an encrypted parquet, with external key
    material.
    Currently it's not implemented, so should throw
    an exceptionF)r   r   r   r-   r   c                 S   r!   r"   r#   r$   r   r   r   r&     r'   z:test_encrypted_parquet_write_external.<locals>.kms_factoryN)	r?   r   r   r   r(   r@   r.   r)   r/   r   r   r   r   %test_encrypted_parquet_write_external  s   
r   c                 C   s   | t  }t||tttt|\}}t| tjt	ddd}t
dD ]"}|||}|dus/J tj||d}	|	jdd}
||
sCJ q!dS )	z`Write an encrypted parquet, verify it's encrypted,
    and then read it multithreaded in a loop.r6   r7   r>   2   NrQ   TrS   )r?   r4   r   r   r@   rA   r   r   rB   r   rangerU   rK   r[   r\   rD   )rE   r   r   r0   r*   r+   rF   irU   r^   rG   r   r   r   test_encrypted_parquet_loop  s(   r   c           
      C   st   | t  }t||tttt|\}}t| tjt	ddd}|
||}~tj||d}|jdd}	||	s8J dS )z^
    Test that decryption properties can be used if the crypto factory is no longer alive
    r6   r7   r>   rQ   TrS   N)r?   r4   r   r   r@   rA   r   r   rB   r   rU   rK   r[   r\   rD   )
rE   r   r   r0   r*   r+   rF   rU   r^   rG   r   r   r   %test_read_with_deleted_crypto_factory  s$   r   c           	      C   sz   | t  }t||tttt|\}}tjtddd}|	||}t
j||d}||s-J t
j| |d}||s;J dS )z>Write an encrypted parquet then read it back using read_table.r6   r7   r>   rQ   N)r?   r4   r   r   r@   rA   r   rB   r   rU   rK   
read_tablerD   )	rE   r   r   r0   r*   r+   rF   rU   rG   r   r   r   !test_encrypted_parquet_read_table%  s"   r   )1ra   datetimer   pyarrowr   pyarrow.parquetparquetrK   pyarrow.parquet.encryption
encryptionr   ImportError pyarrow.tests.parquet.encryptionr   r   r?   r@   r   rA   r   markparquet_encryption
pytestmarkfixturer   r   r,   r4   rH   r/   rC   rf   rj   rl   rm   rq   rw   r   r   r   r   r   r   xfailr   r   r   r   r   r   r   r   r   <module>   s^   


	
	#	
	$!#

'
