Skip to content

Commit

Permalink
feat(cognito): deletion protection for user pools (#22765)
Browse files Browse the repository at this point in the history
Add the `deletionProtection` property to enable deletion protection on a user pool.


----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored Nov 6, 2022
1 parent dfcfb8d commit 9bde9f3
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 15 deletions.
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw
- [App Clients](#app-clients)
- [Resource Servers](#resource-servers)
- [Domains](#domains)
- [Deletion protection](#deletion-protection)

## User Pools

Expand Down Expand Up @@ -869,3 +870,16 @@ Existing domains can be imported into CDK apps using `UserPoolDomain.fromDomainN
```ts
const myUserPoolDomain = cognito.UserPoolDomain.fromDomainName(this, 'my-user-pool-domain', 'domain-name');
```

### Deletion protection

Deletion protection can be enabled on a user pool to prevent accidental deletion:

```ts
const userpool = new cognito.UserPool(this, 'UserPool', {
// ...
deletionProtection: true,
});
```

By default deletion protection is disabled.
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,13 @@ export interface UserPoolProps {
*/
readonly removalPolicy?: RemovalPolicy;

/**
* Indicates whether the user pool should have deletion protection enabled.
*
* @default false
*/
readonly deletionProtection?: boolean;

/**
* Device tracking settings
* @default - see defaults on each property of DeviceTracking.
Expand Down Expand Up @@ -938,6 +945,7 @@ export class UserPool extends UserPoolBase {
accountRecoverySetting: this.accountRecovery(props),
deviceConfiguration: props.deviceTracking,
userAttributeUpdateSettings: this.configureUserAttributeChanges(props),
deletionProtection: defaultDeletionProtection(props.deletionProtection),
});
userPool.applyRemovalPolicy(props.removalPolicy);

Expand Down Expand Up @@ -1279,3 +1287,15 @@ function undefinedIfNoKeys(struct: object): object | undefined {
function encodePuny(input: string | undefined): string | undefined {
return input !== undefined ? punycodeEncode(input) : input;
}

function defaultDeletionProtection(deletionProtection?: boolean): 'ACTIVE' | 'INACTIVE' | undefined {
if (deletionProtection === true) {
return 'ACTIVE';
}

if (deletionProtection === false) {
return 'INACTIVE';
}

return undefined;
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"20.0.0"}
{"version":"21.0.0"}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "20.0.0",
"version": "21.0.0",
"files": {
"74ea2c843421df9c10c1481ddd7217c95f27e17517f1937cdcf1377dfd6c25c1": {
"c804fbf067be5d847ab7df1eb55d6fa733f513f3908b0162773c8912e08695b1": {
"source": {
"path": "integ-user-pool.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "74ea2c843421df9c10c1481ddd7217c95f27e17517f1937cdcf1377dfd6c25c1.json",
"objectKey": "c804fbf067be5d847ab7df1eb55d6fa733f513f3908b0162773c8912e08695b1.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"AdminCreateUserConfig": {
"AllowAdminCreateUserOnly": true
},
"DeletionProtection": "INACTIVE",
"EmailVerificationMessage": "The verification code to your new account is {####}",
"EmailVerificationSubject": "Verify your new account",
"SmsVerificationMessage": "The verification code to your new account is {####}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "20.0.0",
"version": "21.0.0",
"testCases": {
"integ.user-pool": {
"stacks": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "20.0.0",
"version": "21.0.0",
"artifacts": {
"Tree": {
"type": "cdk:tree",
Expand All @@ -23,7 +23,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/74ea2c843421df9c10c1481ddd7217c95f27e17517f1937cdcf1377dfd6c25c1.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c804fbf067be5d847ab7df1eb55d6fa733f513f3908b0162773c8912e08695b1.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.85"
"version": "10.1.140"
}
},
"integ-user-pool": {
Expand Down Expand Up @@ -41,6 +41,7 @@
"adminCreateUserConfig": {
"allowAdminCreateUserOnly": true
},
"deletionProtection": "INACTIVE",
"emailVerificationMessage": "The verification code to your new account is {####}",
"emailVerificationSubject": "Verify your new account",
"smsVerificationMessage": "The verification code to your new account is {####}",
Expand Down Expand Up @@ -68,20 +69,20 @@
"id": "user-pool-id",
"path": "integ-user-pool/user-pool-id",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.85"
"fqn": "@aws-cdk/core.CfnOutput",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.85"
"fqn": "@aws-cdk/core.Stack",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.85"
"fqn": "@aws-cdk/core.App",
"version": "0.0.0"
}
}
}
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-cognito/test/integ.user-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const stack = new Stack(app, 'integ-user-pool');
const userpool = new UserPool(stack, 'myuserpool', {
userPoolName: 'MyUserPool',
removalPolicy: RemovalPolicy.DESTROY,
deletionProtection: false,
});

new CfnOutput(stack, 'user-pool-id', {
value: userpool.userPoolId,
});
});
15 changes: 15 additions & 0 deletions packages/@aws-cdk/aws-cognito/test/user-pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,21 @@ test('grant', () => {

});

test('deletion protection', () => {
// GIVEN
const stack = new Stack();

// WHEN
new UserPool(stack, 'Pool', {
deletionProtection: true,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', {
DeletionProtection: 'ACTIVE',
});
});

function fooFunction(scope: Construct, name: string): lambda.IFunction {
return new lambda.Function(scope, name, {
functionName: name,
Expand Down

0 comments on commit 9bde9f3

Please sign in to comment.