Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,7 @@ export class Bucket extends BucketBase {
if (!bucketName) {
throw new Error('Bucket name is required');
}
Bucket.validateBucketName(bucketName);
Bucket.validateBucketName(bucketName, true);

const newUrlFormat = attrs.bucketWebsiteNewUrlFormat === undefined
? false
Expand Down Expand Up @@ -1585,7 +1585,7 @@ export class Bucket extends BucketBase {
*
* @param physicalName name of the bucket.
*/
public static validateBucketName(physicalName: string): void {
public static validateBucketName(physicalName: string, allowWildcard: boolean = false): void {
const bucketName = physicalName;
if (!bucketName || Token.isUnresolved(bucketName)) {
// the name is a late-bound value, not a defined string,
Expand All @@ -1596,19 +1596,20 @@ export class Bucket extends BucketBase {
const errors: string[] = [];

// Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
if (bucketName.length < 3 || bucketName.length > 63) {
if ((!allowWildcard || bucketName.indexOf('*') === -1) && (bucketName.length < 3 || bucketName.length > 63)) {
errors.push('Bucket name must be at least 3 and no more than 63 characters');
}
const charsetMatch = bucketName.match(/[^a-z0-9.-]/);
const charsetMatch = bucketName.match(/[^*a-z0-9.-]/);
if (charsetMatch) {
errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) '
+ `(offset: ${charsetMatch.index})`);
}
if (!/[a-z0-9]/.test(bucketName.charAt(0))) {
const allowedCharsStartEnd = allowWildcard ? /[*a-z0-9]/ : /[a-z0-9]/;
if (!allowedCharsStartEnd.test(bucketName.charAt(0))) {
errors.push('Bucket name must start and end with a lowercase character or number '
+ '(offset: 0)');
}
if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) {
if (!allowedCharsStartEnd.test(bucketName.charAt(bucketName.length - 1))) {
errors.push('Bucket name must start and end with a lowercase character or number '
+ `(offset: ${bucketName.length - 1})`);
}
Expand Down
28 changes: 28 additions & 0 deletions packages/@aws-cdk/aws-s3/test/bucket.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,34 @@ describe('bucket', () => {
});
});

test('import allows short bucket name with wild card', () => {
const stack = new cdk.Stack(undefined, undefined, {
env: { region: 'us-east-1' },
});

const bucket = s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', {
bucketName: 'm*',
});

expect(stack.resolve(bucket.bucketArn)).toEqual({
'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':s3:::m*']],
});
});

test('import allows bucket name with wild card', () => {
const stack = new cdk.Stack(undefined, undefined, {
env: { region: 'us-east-1' },
});

const bucket = s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', {
bucketName: 'my-bucket*',
});

expect(stack.resolve(bucket.bucketArn)).toEqual({
'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':s3:::my-bucket*']],
});
});

test('grantRead', () => {
const stack = new cdk.Stack();
const reader = new iam.User(stack, 'Reader');
Expand Down