Skip to content

Commit ba41996

Browse files
authored
fix(s3): revert incorrect account used for S3 event source mapping (#29405)
Reverts #29365 as it causes test failure.
1 parent 3fb0254 commit ba41996

File tree

3 files changed

+8
-96
lines changed

3 files changed

+8
-96
lines changed

Diff for: packages/aws-cdk-lib/aws-lambda-event-sources/test/s3.test.ts

-82
Original file line numberDiff line numberDiff line change
@@ -228,86 +228,4 @@ describe('S3EventSource', () => {
228228
},
229229
});
230230
});
231-
test('Cross account buckect access', () => {
232-
// GIVEN
233-
const app = new cdk.App();
234-
const stack = new cdk.Stack(app, 'stack');
235-
const fn = new TestFunction(stack, 'Fn');
236-
237-
let accountB = '1234567';
238-
//WHEN
239-
const foreignBucket =
240-
s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', {
241-
bucketArn: 'arn:aws:s3:::some-bucket-not-in-this-account',
242-
// The account the bucket really lives in
243-
account: accountB,
244-
});
245-
246-
// This will generate the IAM bindings
247-
fn.addEventSource(new sources.S3EventSource(foreignBucket as s3.Bucket,
248-
{ events: [s3.EventType.OBJECT_CREATED] }));
249-
250-
// THEN
251-
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
252-
'Principal': 's3.amazonaws.com',
253-
'SourceAccount': '1234567',
254-
'SourceArn': 'arn:aws:s3:::some-bucket-not-in-this-account',
255-
});
256-
});
257-
258-
test('Test bucket account is referenced intrinsicly', () => {
259-
// GIVEN
260-
const stack = new cdk.Stack();
261-
const fn = new TestFunction(stack, 'Fn');
262-
const bucket = new s3.Bucket(stack, 'B');
263-
264-
// WHEN
265-
fn.addEventSource(new sources.S3EventSource(bucket, {
266-
events: [s3.EventType.OBJECT_CREATED, s3.EventType.OBJECT_REMOVED],
267-
filters: [
268-
{ prefix: 'prefix/' },
269-
{ suffix: '.png' },
270-
],
271-
}));
272-
273-
// THEN
274-
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
275-
'Principal': 's3.amazonaws.com',
276-
'SourceAccount': {
277-
'Ref': 'AWS::AccountId',
278-
},
279-
'SourceArn': {
280-
'Fn::GetAtt': ['B08E7C7AF', 'Arn'],
281-
},
282-
});
283-
});
284-
285-
test('Default to stack account if bucket account doesnt exist', () => {
286-
// GIVEN
287-
const app = new cdk.App();
288-
const stack = new cdk.Stack(app, 'stack');
289-
const fn = new TestFunction(stack, 'Fn');
290-
291-
let accountB = '';
292-
//WHEN
293-
const foreignBucket =
294-
s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', {
295-
bucketArn: 'arn:aws:s3:::some-bucket-not-in-this-account',
296-
// The account the bucket really lives in
297-
account: accountB,
298-
});
299-
300-
// This will generate the IAM bindings
301-
fn.addEventSource(new sources.S3EventSource(foreignBucket as s3.Bucket,
302-
{ events: [s3.EventType.OBJECT_CREATED] }));
303-
304-
// THEN
305-
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
306-
'Principal': 's3.amazonaws.com',
307-
'SourceAccount': {
308-
'Ref': 'AWS::AccountId',
309-
},
310-
'SourceArn': 'arn:aws:s3:::some-bucket-not-in-this-account',
311-
});
312-
});
313231
});

Diff for: packages/aws-cdk-lib/aws-s3-notifications/lib/lambda.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class LambdaDestination implements s3.IBucketNotificationDestination {
2121

2222
if (bucket.node.tryFindChild(permissionId) === undefined) {
2323
this.fn.addPermission(permissionId, {
24-
sourceAccount: bucket.account || Stack.of(bucket).account,
24+
sourceAccount: Stack.of(bucket).account,
2525
principal: new iam.ServicePrincipal('s3.amazonaws.com'),
2626
sourceArn: bucket.bucketArn,
2727
// Placing the permissions node in the same scope as the s3 bucket.

Diff for: packages/aws-cdk-lib/aws-s3/lib/bucket.ts

+7-13
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,6 @@ export interface IBucket extends IResource {
9595
*/
9696
policy?: BucketPolicy;
9797

98-
/**
99-
* The account bucket belongs to.
100-
*/
101-
readonly account?: string;
102-
10398
/**
10499
* Adds a statement to the resource policy for a principal (i.e.
105100
* account/role/service) to perform actions on this bucket and/or its
@@ -1759,7 +1754,6 @@ export class Bucket extends BucketBase {
17591754
public readonly bucketWebsiteNewUrlFormat = attrs.bucketWebsiteNewUrlFormat ?? false;
17601755
public readonly encryptionKey = attrs.encryptionKey;
17611756
public readonly isWebsite = attrs.isWebsite ?? false;
1762-
public readonly account = attrs.account;
17631757
public policy?: BucketPolicy = undefined;
17641758
protected autoCreatePolicy = false;
17651759
protected disallowPublicAccess = false;
@@ -1973,11 +1967,11 @@ export class Bucket extends BucketBase {
19731967

19741968
if (props.serverAccessLogsBucket instanceof Bucket) {
19751969
props.serverAccessLogsBucket.allowLogDelivery(this, props.serverAccessLogsPrefix);
1976-
// It is possible that `serverAccessLogsBucket` was specified but is some other `IBucket`
1977-
// that cannot have the ACLs or bucket policy applied. In that scenario, we should only
1978-
// setup log delivery permissions to `this` if a bucket was not specified at all, as documented.
1979-
// For example, we should not allow log delivery to `this` if given an imported bucket or
1980-
// another situation that causes `instanceof` to fail
1970+
// It is possible that `serverAccessLogsBucket` was specified but is some other `IBucket`
1971+
// that cannot have the ACLs or bucket policy applied. In that scenario, we should only
1972+
// setup log delivery permissions to `this` if a bucket was not specified at all, as documented.
1973+
// For example, we should not allow log delivery to `this` if given an imported bucket or
1974+
// another situation that causes `instanceof` to fail
19811975
} else if (!props.serverAccessLogsBucket && props.serverAccessLogsPrefix) {
19821976
this.allowLogDelivery(this, props.serverAccessLogsPrefix);
19831977
} else if (props.serverAccessLogsBucket) {
@@ -2231,7 +2225,7 @@ export class Bucket extends BucketBase {
22312225
function parseLifecycleRule(rule: LifecycleRule): CfnBucket.RuleProperty {
22322226
const enabled = rule.enabled ?? true;
22332227
if ((rule.expiredObjectDeleteMarker)
2234-
&& (rule.expiration || rule.expirationDate || self.parseTagFilters(rule.tagFilters))) {
2228+
&& (rule.expiration || rule.expirationDate || self.parseTagFilters(rule.tagFilters))) {
22352229
// ExpiredObjectDeleteMarker cannot be specified with ExpirationInDays, ExpirationDate, or TagFilters.
22362230
throw new Error('ExpiredObjectDeleteMarker cannot be specified with expiration, ExpirationDate, or TagFilters.');
22372231
}
@@ -2356,7 +2350,7 @@ export class Bucket extends BucketBase {
23562350
}
23572351

23582352
if (accessControlRequiresObjectOwnership && this.objectOwnership === ObjectOwnership.BUCKET_OWNER_ENFORCED) {
2359-
throw new Error(`objectOwnership must be set to "${ObjectOwnership.OBJECT_WRITER}" when accessControl is "${this.accessControl}"`);
2353+
throw new Error (`objectOwnership must be set to "${ObjectOwnership.OBJECT_WRITER}" when accessControl is "${this.accessControl}"`);
23602354
}
23612355

23622356
return {

0 commit comments

Comments
 (0)