Skip to content

Commit b37e145

Browse files
committed
apply bucket-owner-full-control on boto synapse upload
1 parent 87530e3 commit b37e145

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

synapseclient/core/remote_file_storage_wrappers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ def upload_file(bucket, endpoint_url, remote_file_key, upload_file_path,
132132
upload_file_path,
133133
remote_file_key,
134134
Callback=progress_callback,
135-
Config=transfer_config
135+
Config=transfer_config,
136+
ExtraArgs={'ACL': 'bucket-owner-full-control'},
136137
)
137138
return upload_file_path
138139

tests/integration/synapseclient/core/test_external_storage.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import pytest
1010
import unittest
11+
from unittest import mock
1112

1213
try:
1314
boto3 = importlib.import_module('boto3')
@@ -181,3 +182,37 @@ def test_sts_external_storage_location(self):
181182
retrieved_file_entity = self.syn.get(file_entity['id'])
182183
with open(retrieved_file_entity.path, 'r') as f:
183184
assert file_contents == f.read()
185+
186+
def test_boto_upload__acl(self):
187+
"""Verify when we store a Synapse object using boto we apply a bucket-owner-full-control ACL to the object"""
188+
bucket_name, _ = get_aws_env()
189+
_, folder, storage_location_id = self._configure_storage_location(sts_enabled=True)
190+
191+
file_contents = str(uuid.uuid4())
192+
upload_file = self._make_temp_file(contents=file_contents)
193+
194+
# mock the sts setting so that we upload this file using boto regardless of test configuration
195+
with mock.patch.object(self.syn, 'use_boto_sts_transfers', new_callable=mock.PropertyMock(return_value=True)):
196+
file = self.syn.store(File(path=upload_file.name, parent=folder))
197+
198+
s3_read_client = boto3.client('s3', **get_aws_env()[1])
199+
bucket_acl = s3_read_client.get_bucket_acl(Bucket=bucket_name)
200+
bucket_grantee = bucket_acl['Grants'][0]['Grantee']
201+
assert bucket_grantee['Type'] == 'CanonicalUser'
202+
bucket_owner_id = bucket_grantee['ID']
203+
204+
# with_retry to avoid acidity issues of an S3 put
205+
object_acl = with_retry(
206+
lambda: s3_read_client.get_object_acl(
207+
Bucket=bucket_name,
208+
Key=file['_file_handle']['key']
209+
),
210+
retry_exceptions=[s3_read_client.exceptions.NoSuchKey]
211+
)
212+
grants = object_acl['Grants']
213+
assert len(grants) == 1
214+
grant = grants[0]
215+
grantee = grant['Grantee']
216+
assert grantee['Type'] == 'CanonicalUser'
217+
assert grantee['ID'] == bucket_owner_id
218+
assert grant['Permission'] == 'FULL_CONTROL'

tests/unit/synapseclient/core/unit_test_remote_storage_file_wrappers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ def _upload_test(**kwargs):
197197
upload_file_path,
198198
remote_file_key,
199199
Callback=progress_callback,
200-
Config=transfer_config
200+
Config=transfer_config,
201+
ExtraArgs={'ACL': 'bucket-owner-full-control'},
201202
)
202203

203204
# why do we return something we passed...?

0 commit comments

Comments
 (0)