Skip to content

Commit

Permalink
Allow Bucket.load() to work on cross-account buckets (boto#1064)
Browse files Browse the repository at this point in the history
* Make s3.Bucket.load() more accepting of failure

This will cause it to no longer fail if creation_date
can't be found via ListBuckets (boto#1063)

* Only swallow ListBuckets AccessDenied errors
  • Loading branch information
kmosher authored and dstufft committed Apr 28, 2017
1 parent 18f2969 commit 60681e8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
22 changes: 13 additions & 9 deletions boto3/s3/inject.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,19 @@ def bucket_load(self, *args, **kwargs):

# We can't actually get the bucket's attributes from a HeadBucket,
# so we need to use a ListBuckets and search for our bucket.
response = self.meta.client.list_buckets()
for bucket_data in response['Buckets']:
if bucket_data['Name'] == self.name:
self.meta.data = bucket_data
break
else:
raise ClientError({'Error': {'Code': '404', 'Message': 'NotFound'}},
'ListBuckets')

# However, we may fail if we lack permissions to ListBuckets
# or the bucket is in another account. In which case, creation_date
# will be None.
self.meta.data = {}
try:
response = self.meta.client.list_buckets()
for bucket_data in response['Buckets']:
if bucket_data['Name'] == self.name:
self.meta.data = bucket_data
break
except ClientError as e:
if not e.response.get('Error', {}).get('Code') == 'AccessDenied':
raise

def object_summary_load(self, *args, **kwargs):
"""
Expand Down
21 changes: 19 additions & 2 deletions tests/unit/s3/test_inject.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,35 @@ def test_bucket_load_finds_bucket(self):
self.resource.meta.data,
{'Name': self.resource.name, 'CreationDate': 2})

def test_bucket_load_raise_error(self):
def test_bucket_load_doesnt_find_bucket(self):
self.resource.name = 'MyBucket'
self.client.list_buckets.return_value = {
'Buckets': [
{'Name': 'NotMyBucket', 'CreationDate': 1},
{'Name': 'NotMine2', 'CreationDate': 2},
],
}
inject.bucket_load(self.resource)
self.assertEqual(self.resource.meta.data, {})

def test_bucket_load_encounters_access_exception(self):
self.client.list_buckets.side_effect = ClientError(
{'Error':
{'Code': 'AccessDenied',
'Message': 'Access Denied'}},
'ListBuckets')
inject.bucket_load(self.resource)
self.assertEqual(self.resource.meta.data, {})

def test_bucket_load_encounters_other_exception(self):
self.client.list_buckets.side_effect = ClientError(
{'Error':
{'Code': 'ExpiredToken',
'Message': 'The provided token has expired.'}},
'ListBuckets')
with self.assertRaises(ClientError):
inject.bucket_load(self.resource)


class TestBucketTransferMethods(unittest.TestCase):

def setUp(self):
Expand Down

0 comments on commit 60681e8

Please sign in to comment.