
    @G                        d Z ddlmZ ddlm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 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  eg d      Z eg d      Z  e       j2                  eeg ZddddddddZdddddddZej:                  j<                  ej>                  ej:                  j@                  ejB                  iZ"ej:                  j<                  ejF                  ej:                  j@                  ejH                  iZ% ejL                  d       Z'd! Z(d" Z)d# Z*d$ Z+d% Z,	 d3d&Z-d' Z.d( Z/d) Z0d* Z1d+ Z2d, Z3	 	 d4d-Z4d. Z5d/ Z6d0 Z7	 	 d4d1Z8	 	 d4d2Z9y)5z,Tools for making the most of S3Api metadata.    )absolute_import)division)unicode_literalsN)metadata_util)xml_metadata_field_converters)errors)storage_url)user_request_args_factory)gcs_resource_reference)resource_reference)s3_resource_reference)log)CacheControlContentDispositionContentEncodingContentLanguageContentTypeMetadata)ACLAccessControlPolicyStorageClasscache_controlcontent_dispositioncontent_encodingcontent_languagecontent_typemd5_hashstorage_class)r   r   r   r   r   
ContentMD5r   zauthenticated-readzbucket-owner-full-controlzbucket-owner-readprivatezpublic-readzpublic-read-write)authenticatedReadbucketOwnerFullControlbucketOwnerReadr    
publicReadpublicReadWritez^[a-fA-F0-9]{32}$c                    t        j                  |       }|j                  dd       |j                  s|S |j                  j                  }|rD|D ]?  }t        j                  |      }|j                  d      }|d   j                  ||d       A |j                  j                  }|rt        |      }g }	|j                  dg       D ]r  }
|
j                  di       }t        |j                  d      |j                  d      |j                  d	      f      }|j                  |      rb|	j                  |
       t |	|d<   |S )
aW  Returns full ACL policy object with requested changes.

  Args:
    acl_dict (dict): Contains S3-format ACL policy dict for bucket or object.
      Usually of the form: "{"Grants": [...], "Owner": {...}}". See:
      https://boto3.amazonaws.com/v1/documentation/api/latest/reference
      /services/s3.html#S3.Client.get_bucket_acl
    request_config (request_config_factory._RequestConfig): Contains desired
      changes for the ACL policy.

  Returns:
    dict: Deep copy of acl_dict with added and removed grants and
      removed "ResponseMetadata" field to allow for reuse in PUT API calls.
  ResponseMetadataN
PermissionGrants)r(   Granteer*   EmailAddressIDURI)
copydeepcopypopresource_argsacl_grants_to_addappendacl_grants_to_removesetgetintersection)acl_dictrequest_configacl_dict_copyr2   	new_grantnew_grant_copy
permissionr4   entity_identifiers_to_removefiltered_grantsexisting_grantexisting_granteeexisting_grantee_identifierss                7lib/googlecloudsdk/api_lib/storage/xml_metadata_util.py,get_acl_policy_with_added_and_removed_grantsrD   U   sL     --)-&-		%	%$22DD&	}}Y/n!%%l3jH$$"#& 	 ' (55JJ#&';#< O'++Hb9'++Ir:%(/1A1E1Ed1K&(&)" *66
&(~. : .M(	    c                 >    |si }| s|S |D ]  }|| v s| |   ||<    |S )zECopy fields(provided in arguments) from one metadata dict to another. )source_metadata_dictdestination_metadata_dictfieldsfields       rC   _copy_metadatarL      s?    	" "	$$e$$)=e)D&  
#"rE   c                 $    t        | |t              S )z:Copies common S3 fields from one metadata dict to another.)rL   _COMMON_S3_METADATA_FIELDSrH   rI   s     rC   copy_object_metadatarP      s    	 
 rE   c                 $    t        | |t              S )z>Copies user_metadata fields from one metadata dict to another.)rL   _USER_METADATA_FIELDSrO   s     rC   copy_user_metadata_fieldsrS      s    	
 rE   c                 l    | t         vr$t        j                  dj                  |             t         |    S )a  Translates Apitools predefined ACL enum key (as string) to S3 equivalent.

  Args:
    predefined_acl_string (str): Value representing user permissions.

  Returns:
    Translated ACL string.

  Raises:
    Error: Predefined ACL translation could not be found.
  zACould not translate predefined_acl_string {} to AWS-accepted ACL.)*_GCS_TO_S3_PREDEFINED_ACL_TRANSLATION_DICTr   Errorformat)predefined_acl_strings    rC   %translate_predefined_acl_string_to_s3rY      s<     "LL
,,	#V$9:  
44I	JJrE   c                 R    t        j                  | |||j                  d            S )aj  Creates storage_url.CloudUrl from S3 API response.

  Args:
    scheme (storage_url.ProviderPrefix): Prefix used for provider URLs.
    object_dict (dict): Dictionary representing S3 API response.
    bucket_name (str): Bucket to include in URL.
    object_name (str | None): Object to include in URL.

  Returns:
    storage_url.CloudUrl populated with data.
  	VersionId)schemebucket_nameresource_name
generation)r	   CloudUrlr6   )r\   object_dictr]   object_names       rC   !_get_object_url_from_xml_responserc      s,     
		-	
/ /rE   c                     d| v r| j                  d      }nd| v r| d   j                  d      }nd}|r3|j                  d      r"|j                  d      r|j                  d      S |S )z.Returns the cleaned-up etag value, if present.ETagCopyObjectResultN")r6   
startswithendswithstrip)ra   etags     rC   	_get_etagrl      si    {??6"D[()*..v6DD 
dooc"t}}S'9::c?	+rE   c                     | rOt         j                  |       r:t        j                  t	        j
                  |             }|j                  d      S t        j                  d| |       y)z6Returns base64 encoded MD5 hash, if etag is valid MD5.zutf-8)encodingzSNon-MD5 etag ("%s") present for object: %s. Data integrity checks are not possible.N)		MD5_REGEXmatchbase64	b64encodebinascii	unhexlifydecoder   debug)rk   
object_urlencoded_bytess      rC   _get_md5_hash_from_etagry      s[    	iood#$$X%7%7%=>M11II	348*F 
rE   c                     | j                  di       }|j                  di       }|j                  dd      j                         }t        j                  d|      }|r|j	                  d      S y)z@Returns base64 encoded CRC32C hash from object response headers.r'   HTTPHeaderszx-goog-hash zcrc32c\=([^,]+)   N)r6   rj   researchgroup)ra   response_metadataheadershash_headerresults        rC   !_get_crc32c_hash_from_object_dictr      sf    !oo&8"=!!-4'M2.446+99'5&<<? rE   c                 t    t        | t              r'd| v r#| j                         }|j                  d       |S | S )z?Returns the error string if value is error or the value itself.r'   )
isinstancedictr.   r0   )value
value_copys     rC   _get_error_or_valuer      s7    t!3u!<JNN%&	,rE   c                 R   t        |j                  d            }|dk(  rd}n|dk(  rd}t        |j                  d            }t        |t              r|j                  d      dk(  rd}nd	}t	        |    t        j                  | |      t        |j                  d
            t        |j                  d            t        |j                  d            t        |j                  d            |t        |j                  d            ||t        |j                  d            
      S )aV  Creates resource_reference.S3BucketResource from S3 API response.

  Args:
    scheme (storage_url.ProviderPrefix): Prefix used for provider URLs.
    bucket_dict (dict): Dictionary representing S3 API response.
    bucket_name (str): Bucket response is relevant to.

  Returns:
    resource_reference.S3BucketResource populated with data.
  Payer	RequesterTBucketOwnerF
VersioningStatusEnabledNr   	CORSRulesLifecycleConfigurationLoggingEnabledLocationConstraintWebsite)	aclcors_configlifecycle_configlogging_configrequester_payslocationmetadataversioning_enabledwebsite_config)r   r6   r   r   _SCHEME_TO_BUCKET_RESOURCE_DICTr	   r`   )r\   bucket_dictr]   r   r   s        rC   %get_bucket_resource_from_xml_responser     s    '{w'?@.{"N&N*;??<+HI"D)h'94	(	06;/
kooe4
5%kook&BC*
//2
35(9I)JK#";??3G#HI+()CD
F FrE   c                 d    | j                  dd      }|sy|D ci c]  }|d   |d    c}S c c}w )zHParse object tags from object response in format of GCS object contexts.TagSetNKeyValue)r6   )ra   obj_tagstags      rC   _parse_object_tags_if_anyr   '  sJ     __Xt,(	 +3
*23c%j#g,(
  
s   -c           	         t        | |||xs |d         }d|v r|j                  d      }n|j                  d      }|j                  d|j                  d            }t        |      }|r|}	n|j                  d      }	|	r|	|d<   t        |	      }
t	        |    |fi d|
d|j                  d	      d
|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|d|d|j                  d      dt        ||      d|d|d|j                  d       d!|j                  d      }| t        j                  j                  k(  rt        |      |_
        | t        j                  j                  k(  rt        |      |_        |S )"a  Creates resource_reference.S3ObjectResource from S3 API response.

  Args:
    scheme (storage_url.ProviderPrefix): Prefix used for provider URLs.
    object_dict (dict): Dictionary representing S3 API response.
    bucket_name (str): Bucket response is relevant to.
    object_name (str|None): Object if relevant to query.
    acl_dict (dict|None): Response from S3 get_object_acl API call.

  Returns:
    resource_reference.S3ObjectResource populated with data.
  r   SizeContentLengthServerSideEncryptionSSECustomerAlgorithmr   r   r   r   component_count
PartsCountr   r   r   r   r   r   r   r   creation_timeLastModifiedcustom_fieldsr   encryption_algorithmrk   kms_keySSEKMSKeyIdr   r   sizer   r   update_time)rc   r6   rl   r   _SCHEME_TO_OBJECT_RESOURCE_DICTry   r	   ProviderPrefixGCSr   crc32c_hashS3r   tags)r\   ra   r]   rb   r8   rw   r   r   rk   raw_acl_datar   object_resources               rC   %get_object_resource_from_xml_responser   5  s   " 1k;(I{57IK* {??6"D???+D$koo.DEG	;	$L ??5)L%KL)#3F;
  OON3 "ool3	
 &//*>? #'89 #'89 ??=1  OON3  OOJ/ 0  oom, 'tZ8   !"  OON3#$ //.1%/* {))---"CK"PO{)),,,4[AO	rE   c                 f    |d   }t        j                  t        j                  | ||      |      S )aB  Creates resource_reference.PrefixResource from S3 API response.

  Args:
    scheme (storage_url.ProviderPrefix): Prefix used for provider URLs.
    prefix_dict (dict): The S3 API response representing a prefix.
    bucket_name (str): Bucket for the prefix.

  Returns:
    A resource_reference.PrefixResource instance.
  Prefix)r\   r]   r^   )prefix)r   PrefixResourcer	   r`   )r\   prefix_dictr]   r   s       rC   %get_prefix_resource_from_xml_responser   y  s=     x &		*	*!  
 rE   c                 D   i }| j                   }|r|j                  .|j                  t        j                  |j                               |j
                  .|j                  t        j                  |j
                               |j                  .|j                  t        j                  |j                               |j                  |j                  |d<   |j                  .|j                  t        j                  |j                               |j                  .|j                  t        j                  |j                               |j                  |j                  9|j                  t        j                   |j                  |j                               |S )z>Returns S3 bucket metadata dict fields based on RequestConfig.r   )r1   cors_file_pathupdater   process_corslabels_file_pathprocess_labelslifecycle_file_pathprocess_lifecycler   r   process_requester_pays
versioningprocess_versioningweb_error_pageweb_main_page_suffixprocess_website)r9   r   r1   s      rC   ,get_bucket_metadata_dict_from_request_configr     ss   ( ..-##/oo
'
4
4**,- %%1oo
'
6
6,,./ ((4oo
'
9
9//12 )'4'='=h#$##/oo
'
>
>**,- +oo
'
:
:&&() 	$$0**6oo
'
7
7**M,N,NPQ 
/rE   c                 F    |t         j                  k(  rd| |<   y||| |<   yy)z)Sets appropriate metadata based on value.N)r
   CLEAR)r   keyr   s      rC   _process_value_or_clear_flagr     s.    
'---HSMHSM rE   c                     | j                   }|y| j                  yt        j                         D ]  }t	        ||d      s y t        j                  || j                  | j                  ||      S )z>Checks the presence of user_metadata fields in request_config.NFTattributes_resourceknown_posix)	r1   rX   _S3_TO_GENERIC_FIELD_NAMES_valuesgetattrr   has_updated_custom_fieldspreserve_posixpreserve_symlinks)r9   r   r   r1   r   s        rC   0is_user_metadata_field_present_in_request_configr     sy     !..-))5*113e}eT* 4 
	0	0##&&-
 rE   c           
      6   |j                   t        |j                         | d<   |j                  }| j                  di       }t	        j
                  ||||      }||| d<   |r5t        j                         D ]  \  }}t        | |t        ||d              yy)a  Returns S3 object metadata dict fields based on RequestConfig.

  Args:
    object_metadata (dict): Existing object metadata.
    request_config (request_config): May contain data to add to object_metadata.
    attributes_resource (Resource|None): If present, used for parsing POSIX and
      symlink data from a resource for the --preserve-posix and/or
      --preserve_symlink flags. This value is ignored unless it is an instance
      of FileObjectResource.
    posix_to_set (PosixAttributes|None): Set as custom metadata on target.

  Nr   r   r   )
rX   rY   r1   r6   r   get_updated_custom_fieldsr   itemsr   r   )	object_metadatar9   r   posix_to_setr1   existing_metadatacustom_fields_dictrK   r   s	            rC   /update_object_metadata_dict_from_request_configr     s    $ ))5B,,.OE !..-%))*b9$>>-	 #"4OJ399;u"


 < rE   )N)NN):__doc__
__future__r   r   r   rq   rs   r.   r~   googlecloudsdk.api_lib.storager   r   "googlecloudsdk.command_lib.storager   r	   r
   ,googlecloudsdk.command_lib.storage.resourcesr   r   r   googlecloudsdk.corer   	frozensetrR   _NON_USER_METADATA_FIELDSunionrN   r   rU   r   r   GcsBucketResourcer   S3BucketResourcer   GcsObjectResourceS3ObjectResourcer   compilero   rD   rL   rP   rS   rY   rc   rl   ry   r   r   r   r   r   r   r   r   r   r   rG   rE   rC   <module>r      s   3 &  '    	 8 H 5 : H O K N #! #   & '   /Y[..67 
 $/))!#  .9**. * ""$:$L$L!!#8#I#I# 
 ""$:$L$L!!#8#I#I# 
 BJJ+,	2j	#K. 37/, 	#FL" 7;37	AH("J : 	-rE   