Fix/azure copy object (#382)

* fix: Added destination bucket acl check and metadata comparision for CopyObject action in azure backend

---------

Co-authored-by: Ben McClelland <ben.mcclelland@versity.com>
This commit is contained in:
Jon Austin
2024-01-22 13:01:16 -05:00
committed by GitHub
parent d956ecacd7
commit cf92b6fd80

View File

@@ -399,16 +399,40 @@ func (az *Azure) DeleteObjects(ctx context.Context, input *s3.DeleteObjectsInput
}
func (az *Azure) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3.CopyObjectOutput, error) {
client, err := az.getBlobClient(*input.Bucket, *input.Key)
containerClient, err := az.getContainerClient(*input.Bucket)
if err != nil {
return nil, err
}
res, err := containerClient.GetProperties(ctx, &container.GetPropertiesOptions{})
if err != nil {
return nil, azureErrToS3Err(err)
}
dstContainerAcl, err := getAclFromMetadata(res.Metadata, aclKeyCapital)
if err != nil {
return nil, err
}
err = auth.VerifyACL(*dstContainerAcl, *input.ExpectedBucketOwner, types.PermissionWrite, false)
if err != nil {
return nil, err
}
if strings.Join([]string{*input.Bucket, *input.Key}, "/") == *input.CopySource && isMetaSame(res.Metadata, input.Metadata) {
return nil, s3err.GetAPIError(s3err.ErrInvalidCopyDest)
}
tags, err := parseTags(input.Tagging)
if err != nil {
return nil, err
}
client, err := az.getBlobClient(*input.Bucket, *input.Key)
if err != nil {
return nil, err
}
resp, err := client.CopyFromURL(ctx, az.serviceURL+"/"+*input.CopySource, &blob.CopyFromURLOptions{
BlobTags: tags,
Metadata: parseMetadata(input.Metadata),
@@ -942,3 +966,21 @@ func getAclFromMetadata(meta map[string]*string, key aclKey) (*auth.ACL, error)
return &acl, nil
}
func isMetaSame(azMeta map[string]*string, awsMeta map[string]string) bool {
if len(azMeta) != len(awsMeta)+1 {
return false
}
for key, val := range azMeta {
if key == string(aclKeyCapital) || key == string(aclKeyLower) {
continue
}
awsVal, ok := awsMeta[key]
if !ok || awsVal != *val {
return false
}
}
return true
}