fix copy in place for bucket with encryption (#6303)
This commit is contained in:
parent
52846c9555
commit
9d8d166571
@ -242,7 +242,7 @@ class FakeKey(BaseModel, ManagedState):
|
|||||||
res["x-amz-server-side-encryption"] = self.encryption
|
res["x-amz-server-side-encryption"] = self.encryption
|
||||||
if self.encryption == "aws:kms" and self.kms_key_id is not None:
|
if self.encryption == "aws:kms" and self.kms_key_id is not None:
|
||||||
res["x-amz-server-side-encryption-aws-kms-key-id"] = self.kms_key_id
|
res["x-amz-server-side-encryption-aws-kms-key-id"] = self.kms_key_id
|
||||||
if self.bucket_key_enabled is not None:
|
if self.encryption == "aws:kms" and self.bucket_key_enabled is not None:
|
||||||
res[
|
res[
|
||||||
"x-amz-server-side-encryption-bucket-key-enabled"
|
"x-amz-server-side-encryption-bucket-key-enabled"
|
||||||
] = self.bucket_key_enabled
|
] = self.bucket_key_enabled
|
||||||
@ -2373,6 +2373,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
|||||||
lock_legal_status: Optional[str] = None,
|
lock_legal_status: Optional[str] = None,
|
||||||
lock_until: Optional[str] = None,
|
lock_until: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
bucket = self.get_bucket(dest_bucket_name)
|
||||||
if src_key.name == dest_key_name and src_key.bucket_name == dest_bucket_name:
|
if src_key.name == dest_key_name and src_key.bucket_name == dest_bucket_name:
|
||||||
if src_key.encryption and src_key.encryption != "AES256" and not encryption:
|
if src_key.encryption and src_key.encryption != "AES256" and not encryption:
|
||||||
# this a special case, as now S3 default to AES256 when not provided
|
# this a special case, as now S3 default to AES256 when not provided
|
||||||
@ -2386,6 +2387,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
|||||||
encryption,
|
encryption,
|
||||||
mdirective == "REPLACE",
|
mdirective == "REPLACE",
|
||||||
website_redirect_location,
|
website_redirect_location,
|
||||||
|
bucket.encryption, # S3 will allow copy in place if the bucket has encryption configured
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
raise CopyObjectMustChangeSomething
|
raise CopyObjectMustChangeSomething
|
||||||
@ -2417,7 +2419,6 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
|
|||||||
new_key.set_expiry(None)
|
new_key.set_expiry(None)
|
||||||
|
|
||||||
# Send notifications that an object was copied
|
# Send notifications that an object was copied
|
||||||
bucket = self.get_bucket(dest_bucket_name)
|
|
||||||
notifications.send_event(
|
notifications.send_event(
|
||||||
self.account_id, notifications.S3_OBJECT_CREATE_COPY, bucket, new_key
|
self.account_id, notifications.S3_OBJECT_CREATE_COPY, bucket, new_key
|
||||||
)
|
)
|
||||||
|
@ -682,3 +682,39 @@ def test_copy_object_in_place_website_redirect_location():
|
|||||||
|
|
||||||
head_object = client.head_object(Bucket=bucket_name, Key=key)
|
head_object = client.head_object(Bucket=bucket_name, Key=key)
|
||||||
assert head_object["WebsiteRedirectLocation"] == "/test/direct"
|
assert head_object["WebsiteRedirectLocation"] == "/test/direct"
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_copy_object_in_place_with_bucket_encryption():
|
||||||
|
# If a bucket has encryption configured, it will allow copy in place per default
|
||||||
|
client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||||
|
bucket_name = "test-bucket"
|
||||||
|
client.create_bucket(Bucket=bucket_name)
|
||||||
|
key = "source-key"
|
||||||
|
|
||||||
|
response = client.put_bucket_encryption(
|
||||||
|
Bucket=bucket_name,
|
||||||
|
ServerSideEncryptionConfiguration={
|
||||||
|
"Rules": [
|
||||||
|
{
|
||||||
|
"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"},
|
||||||
|
"BucketKeyEnabled": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
|
||||||
|
|
||||||
|
response = client.put_object(
|
||||||
|
Body=b"",
|
||||||
|
Bucket=bucket_name,
|
||||||
|
Key=key,
|
||||||
|
)
|
||||||
|
assert response["ServerSideEncryption"] == "AES256"
|
||||||
|
|
||||||
|
response = client.copy_object(
|
||||||
|
Bucket=bucket_name,
|
||||||
|
CopySource={"Bucket": bucket_name, "Key": key},
|
||||||
|
Key=key,
|
||||||
|
)
|
||||||
|
assert response["ServerSideEncryption"] == "AES256"
|
||||||
|
@ -127,3 +127,24 @@ def test_encryption_status_on_copied_objects():
|
|||||||
# verify encryption status on object2 does have encryption
|
# verify encryption status on object2 does have encryption
|
||||||
res = s3.get_object(Bucket=bucket_name, Key="file2.txt")
|
res = s3.get_object(Bucket=bucket_name, Key="file2.txt")
|
||||||
res.should.have.key("ServerSideEncryption").equals("AES256")
|
res.should.have.key("ServerSideEncryption").equals("AES256")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_encryption_bucket_key_for_aes_not_returned():
|
||||||
|
bucket_name = str(uuid4())
|
||||||
|
s3 = boto3.client("s3", region_name="us-east-1")
|
||||||
|
s3.create_bucket(Bucket=bucket_name)
|
||||||
|
# enable encryption
|
||||||
|
sse_config = {
|
||||||
|
"Rules": [
|
||||||
|
{
|
||||||
|
"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"},
|
||||||
|
"BucketKeyEnabled": False,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
s3.put_bucket_encryption(
|
||||||
|
Bucket=bucket_name, ServerSideEncryptionConfiguration=sse_config
|
||||||
|
)
|
||||||
|
res = s3.put_object(Bucket=bucket_name, Body=b"test", Key="file.txt")
|
||||||
|
res.shouldnt.have.key("BucketKeyEnabled")
|
||||||
|
Loading…
Reference in New Issue
Block a user