Skip to content

Commit f213cc2

Browse files
committed
issues/151: Added ExpectedBucketOwner parameter when making S3 requests
1 parent 58d5dd6 commit f213cc2

3 files changed

Lines changed: 28 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
### Removed
1313
### Fixed
1414
### Security
15+
- [issues/151](https://github.com/podaac/bignbit/issues/151): Added ExpectedBucketOwner parameter when making S3 requests.
1516

1617
## [0.7.2]
1718
### Added

bignbit/utils.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,27 @@
1515
ED_USER = ED_PASS = None
1616
EDL_USER_TOKEN: dict[str, str] = {}
1717
HARMONY_CLIENT: Client | None = None
18+
AWS_ACCOUNT_ID: str | None = None
1819

1920
HARMONY_SHOULD_VALIDATE_AUTH = os.environ.get('HARMONY_SHOULD_VALIDATE_AUTH', default='False').upper() == 'TRUE'
2021

2122

23+
def get_aws_account_id() -> str:
24+
"""
25+
Get and cache the current AWS account ID via STS.
26+
27+
Returns
28+
-------
29+
str
30+
The AWS account ID for the current caller identity
31+
"""
32+
global AWS_ACCOUNT_ID # pylint: disable=W0603
33+
if not AWS_ACCOUNT_ID:
34+
sts_client = boto3.client('sts')
35+
AWS_ACCOUNT_ID = sts_client.get_caller_identity()['Account']
36+
return AWS_ACCOUNT_ID
37+
38+
2239
def get_edl_creds() -> tuple[str, str]:
2340
"""
2441
Get EDL username and password from SSM.
@@ -215,7 +232,8 @@ def upload_string_as_object(bucket_name: str, key_name: str, object_content: str
215232
s3_client.put_object(
216233
Body=object_content.encode(),
217234
Bucket=bucket_name,
218-
Key=key_name
235+
Key=key_name,
236+
ExpectedBucketOwner=get_aws_account_id()
219237
)
220238
return f's3://{bucket_name}/{key_name}'
221239

@@ -235,6 +253,7 @@ def upload_object(
235253
Key=key,
236254
Body=body_content,
237255
ContentType=content_type,
256+
ExpectedBucketOwner=get_aws_account_id()
238257
)
239258
return f's3://{bucket}/{key}'
240259

@@ -258,7 +277,8 @@ def upload_to_s3(filepath: pathlib.Path, bucket_name: str, object_key: str):
258277
s3 uri of new object
259278
"""
260279
s3_client = boto3.client('s3')
261-
s3_client.upload_file(str(filepath), bucket_name, object_key)
280+
s3_client.upload_file(str(filepath), bucket_name, object_key,
281+
ExtraArgs={'ExpectedBucketOwner': get_aws_account_id()})
262282

263283
return f's3://{bucket_name}/{object_key}'
264284

tests/test_handle_big_result.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import xml.etree.ElementTree as ET
55
import boto3
66
import pytest
7-
from moto import mock_s3
7+
from moto import mock_s3, mock_sts
88

99
import bignbit.utils
1010
from bignbit.handle_big_result import (
@@ -73,9 +73,11 @@ def test_process_harmony_results_no_data():
7373
file_dicts = process_harmony_results(harmony_job, cmr_environment)
7474
assert file_dicts == []
7575

76+
@mock_sts
7677
@mock_s3
7778
def test_generate_metadata():
7879
"""Test generating image metadata xml end-to-end for a single image set."""
80+
bignbit.utils.AWS_ACCOUNT_ID = None
7981
# image metadata xml will be uploaded within the function, so the bucket needs to be mocked
8082
s3_client = boto3.client('s3', region_name='us-west-2')
8183
bucket_name = 'svc-bignbit-podaac-sit-svc-staging'
@@ -234,9 +236,11 @@ def test_get_mdxml_cnm_file_meta():
234236
assert result['size'] == len(image_metadata_xml)
235237

236238

239+
@mock_sts
237240
@mock_s3
238241
def test_write_cnm_message():
239242
"""Test writing CNM message to S3"""
243+
bignbit.utils.AWS_ACCOUNT_ID = None
240244
# Create mock S3 bucket
241245
s3_client = boto3.client('s3', region_name='us-west-2')
242246
bucket_name = 'test-audit-bucket'

0 commit comments

Comments
 (0)