diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json index e83e633d67676..1d90ae0c15d4b 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-iam.expected.json @@ -1,42 +1,5 @@ { "Resources": { - "PoolsmsRoleC3352CE6": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "awsappsyncintegPool5D14B05B" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "PoolD3F588B8": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -57,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "awsappsyncintegPool5D14B05B", - "SnsCallerArn": { - "Fn::GetAtt": [ - "PoolsmsRoleC3352CE6", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "UserPoolName": "myPool", "VerificationMessageTemplate": { diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json index dc19df3e4c395..80d03e19f7767 100644 --- a/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql.expected.json @@ -1,42 +1,5 @@ { "Resources": { - "PoolsmsRoleC3352CE6": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "awsappsyncintegPool5D14B05B" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "PoolD3F588B8": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -57,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "awsappsyncintegPool5D14B05B", - "SnsCallerArn": { - "Fn::GetAtt": [ - "PoolsmsRoleC3352CE6", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "UserPoolName": "myPool", "VerificationMessageTemplate": { diff --git a/packages/@aws-cdk/aws-cognito/README.md b/packages/@aws-cdk/aws-cognito/README.md index 4674fb7570ef8..b4f5a86dc5c26 100644 --- a/packages/@aws-cdk/aws-cognito/README.md +++ b/packages/@aws-cdk/aws-cognito/README.md @@ -201,8 +201,13 @@ The default value is `false`. Cognito sends various messages to its users via SMS, for different actions, ranging from account verification to marketing. In order to send SMS messages, Cognito needs an IAM role that it can assume, with permissions that allow it -to send SMS messages. By default, CDK will create this IAM role but can also be explicily specified to an existing IAM -role using the `smsRole` property. +to send SMS messages. + +By default, the CDK looks at all of the specified properties (and their defaults when not explicitly specified) and +automatically creates an SMS role, when needed. For example, if MFA second factor by SMS is enabled, the CDK will +create a new role. The `smsRole` property can be used to specify the user supplied role that should be used instead. +Additionally, the property `enableSmsRole` can be used to override the CDK's default behaviour to either enable or +suppress automatic role creation. ```ts import { Role } from '@aws-cdk/aws-iam'; diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index 9a09a6500bb04..ddbc7da3992d3 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -471,6 +471,13 @@ export interface UserPoolProps { */ readonly smsRoleExternalId?: string; + /** + * Setting this would explicitly enable or disable SMS role creation. + * When left unspecified, CDK will determine based on other properties if a role is needed or not. + * @default - CDK will determine based on other properties of the user pool if an SMS role should be created or not. + */ + readonly enableSmsRole?: boolean; + /** * Methods in which a user registers or signs in to a user pool. * Allows either username with aliases OR sign in with email, phone, or both. @@ -835,41 +842,56 @@ export class UserPool extends UserPoolBase { return { usernameAttrs, aliasAttrs, autoVerifyAttrs }; } - private smsConfiguration(props: UserPoolProps): CfnUserPool.SmsConfigurationProperty { + private smsConfiguration(props: UserPoolProps): CfnUserPool.SmsConfigurationProperty | undefined { + if (props.enableSmsRole === false && props.smsRole) { + throw new Error('enableSmsRole cannot be disabled when smsRole is specified'); + } + if (props.smsRole) { return { snsCallerArn: props.smsRole.roleArn, externalId: props.smsRoleExternalId, }; - } else { - const smsRoleExternalId = this.construct.uniqueId.substr(0, 1223); // sts:ExternalId max length of 1224 - const smsRole = props.smsRole ?? new Role(this, 'smsRole', { - assumedBy: new ServicePrincipal('cognito-idp.amazonaws.com', { - conditions: { - StringEquals: { 'sts:ExternalId': smsRoleExternalId }, - }, - }), - inlinePolicies: { - /* - * The UserPool is very particular that it must contain an 'sns:Publish' action as an inline policy. - * Ideally, a conditional that restricts this action to 'sms' protocol needs to be attached, but the UserPool deployment fails validation. - * Seems like a case of being excessively strict. - */ - 'sns-publish': new PolicyDocument({ - statements: [ - new PolicyStatement({ - actions: [ 'sns:Publish' ], - resources: [ '*' ], - }), - ], - }), - }, - }); - return { - externalId: smsRoleExternalId, - snsCallerArn: smsRole.roleArn, - }; } + + if (props.enableSmsRole === false) { + return undefined; + } + + const mfaConfiguration = this.mfaConfiguration(props); + const phoneVerification = props.signInAliases?.phone === true || props.autoVerify?.phone === true; + const roleRequired = mfaConfiguration?.includes('SMS_MFA') || phoneVerification; + if (!roleRequired && props.enableSmsRole === undefined) { + return undefined; + } + + const smsRoleExternalId = this.construct.uniqueId.substr(0, 1223); // sts:ExternalId max length of 1224 + const smsRole = props.smsRole ?? new Role(this, 'smsRole', { + assumedBy: new ServicePrincipal('cognito-idp.amazonaws.com', { + conditions: { + StringEquals: { 'sts:ExternalId': smsRoleExternalId }, + }, + }), + inlinePolicies: { + /* + * The UserPool is very particular that it must contain an 'sns:Publish' action as an inline policy. + * Ideally, a conditional that restricts this action to 'sms' protocol needs to be attached, but the UserPool deployment fails validation. + * Seems like a case of being excessively strict. + */ + 'sns-publish': new PolicyDocument({ + statements: [ + new PolicyStatement({ + actions: [ 'sns:Publish' ], + resources: [ '*' ], + }), + ], + }), + }, + }); + return { + externalId: smsRoleExternalId, + snsCallerArn: smsRole.roleArn, + }; } private mfaConfiguration(props: UserPoolProps): string[] | undefined { diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json index 8b5246dfedf58..be2e268a29eac 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json @@ -1,49 +1,18 @@ { "Resources": { - "myuserpoolsmsRole0E16FDD9": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integuserpoolclientexplicitpropsmyuserpoolFC6541FF" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "myuserpool01998219": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { @@ -51,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integuserpoolclientexplicitpropsmyuserpoolFC6541FF", - "SnsCallerArn": { - "Fn::GetAtt": [ - "myuserpoolsmsRole0E16FDD9", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "VerificationMessageTemplate": { "DefaultEmailOption": "CONFIRM_WITH_CODE", diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json index 511d200ed5d90..368a5945b361b 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json @@ -1,49 +1,18 @@ { "Resources": { - "UserPoolsmsRole4EA729DD": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integuserpooldomaincfdistUserPool17475E8A" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "UserPool6BA7E5F2": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { @@ -51,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integuserpooldomaincfdistUserPool17475E8A", - "SnsCallerArn": { - "Fn::GetAtt": [ - "UserPoolsmsRole4EA729DD", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "VerificationMessageTemplate": { "DefaultEmailOption": "CONFIRM_WITH_CODE", @@ -176,7 +136,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4S3BucketC6CBC09E" + "Ref": "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061S3Bucket67234880" }, "S3Key": { "Fn::Join": [ @@ -189,7 +149,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4S3VersionKeyB194AB23" + "Ref": "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061S3VersionKey9802AE96" } ] } @@ -202,7 +162,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4S3VersionKeyB194AB23" + "Ref": "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061S3VersionKey9802AE96" } ] } @@ -244,17 +204,17 @@ } }, "Parameters": { - "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4S3BucketC6CBC09E": { + "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061S3Bucket67234880": { "Type": "String", - "Description": "S3 bucket for asset \"a75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4\"" + "Description": "S3 bucket for asset \"8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061\"" }, - "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4S3VersionKeyB194AB23": { + "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061S3VersionKey9802AE96": { "Type": "String", - "Description": "S3 key for asset version \"a75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4\"" + "Description": "S3 key for asset version \"8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061\"" }, - "AssetParametersa75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4ArtifactHashBE5BD63C": { + "AssetParameters8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061ArtifactHash9212BF97": { "Type": "String", - "Description": "Artifact hash for asset \"a75563f489fb6bc4064bc85b91ef607f671326e647bcd9d9bcab0731de62edd4\"" + "Description": "Artifact hash for asset \"8ae75ec4aaae0510b0918d3a69fac5c978d780ae0d60bb94c65c7f5b4c498061\"" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-signinurl.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-signinurl.expected.json index 6bb3d7edab140..694cf43b5f5ea 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-signinurl.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-signinurl.expected.json @@ -1,49 +1,18 @@ { "Resources": { - "UserPoolsmsRole4EA729DD": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integuserpooldomainsigninurlUserPool1325E89F" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "UserPool6BA7E5F2": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { @@ -51,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integuserpooldomainsigninurlUserPool1325E89F", - "SnsCallerArn": { - "Fn::GetAtt": [ - "UserPoolsmsRole4EA729DD", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "VerificationMessageTemplate": { "DefaultEmailOption": "CONFIRM_WITH_CODE", diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.expected.json index 3fa00974541cf..e68a262eb7ee3 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.expected.json @@ -1,49 +1,18 @@ { "Resources": { - "poolsmsRole04048F13": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integuserpoolidppoolAE0BD80C" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "pool056F3F7E": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { @@ -51,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integuserpoolidppoolAE0BD80C", - "SnsCallerArn": { - "Fn::GetAtt": [ - "poolsmsRole04048F13", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "VerificationMessageTemplate": { "DefaultEmailOption": "CONFIRM_WITH_CODE", diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-code.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-code.expected.json index 90d858978f043..5cc13052434f2 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-code.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-code.expected.json @@ -40,10 +40,16 @@ "myuserpool01998219": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-link.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-link.expected.json index 45661be1e0766..53c9f89ed8031 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-link.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-signup-link.expected.json @@ -40,10 +40,16 @@ "myuserpool01998219": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool.expected.json index f2beef72d6eb4..85214615c050d 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool.expected.json @@ -1,49 +1,18 @@ { "Resources": { - "myuserpoolsmsRole0E16FDD9": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integuserpoolmyuserpoolDA38443C" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "myuserpool01998219": { "Type": "AWS::Cognito::UserPool", "Properties": { - "AccountRecoverySetting": { + "AccountRecoverySetting": { "RecoveryMechanisms": [ - { "Name": "verified_phone_number", "Priority": 1 }, - { "Name": "verified_email", "Priority": 2 } + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } ] }, "AdminCreateUserConfig": { @@ -51,15 +20,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integuserpoolmyuserpoolDA38443C", - "SnsCallerArn": { - "Fn::GetAtt": [ - "myuserpoolsmsRole0E16FDD9", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "UserPoolName": "MyUserPool", "VerificationMessageTemplate": { diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index cf24bed751e34..1be015f803baa 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -1,6 +1,6 @@ import '@aws-cdk/assert/jest'; import { ABSENT } from '@aws-cdk/assert/lib/assertions/have-resource'; -import { Role } from '@aws-cdk/aws-iam'; +import { Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { CfnParameter, Construct, Duration, Stack, Tag } from '@aws-cdk/core'; import { AccountRecovery, Mfa, NumberAttribute, StringAttribute, UserPool, UserPoolIdentityProvider, UserPoolOperation, VerificationEmailStyle } from '../lib'; @@ -28,49 +28,9 @@ describe('User Pool', () => { EmailSubject: 'Verify your new account', SmsMessage: 'The verification code to your new account is {####}', }, - SmsConfiguration: { - SnsCallerArn: { - 'Fn::GetAtt': [ 'PoolsmsRoleC3352CE6', 'Arn' ], - }, - ExternalId: 'Pool', - }, + SmsConfiguration: ABSENT, lambdaTriggers: ABSENT, }); - - expect(stack).toHaveResource('AWS::IAM::Role', { - AssumeRolePolicyDocument: { - Statement: [ - { - Action: 'sts:AssumeRole', - Condition: { - StringEquals: { - 'sts:ExternalId': 'Pool', - }, - }, - Effect: 'Allow', - Principal: { - Service: 'cognito-idp.amazonaws.com', - }, - }, - ], - Version: '2012-10-17', - }, - Policies: [ - { - PolicyDocument: { - Statement: [ - { - Action: 'sns:Publish', - Effect: 'Allow', - Resource: '*', - }, - ], - Version: '2012-10-17', - }, - PolicyName: 'sns-publish', - }, - ], - }); }); test('self sign up option is correctly configured', () => { @@ -1085,6 +1045,231 @@ describe('User Pool', () => { }); }); }); + + describe('sms roles', () => { + test('default', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool'); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: ABSENT, + }); + }); + + test('smsRole and smsExternalId is set', () => { + // GIVEN + const stack = new Stack(); + const smsRole = new Role(stack, 'smsRole', { + assumedBy: new ServicePrincipal('service.amazonaws.com'), + }); + + // WHEN + new UserPool(stack, 'pool', { + smsRole, + smsRoleExternalId: 'role-external-id', + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: { + ExternalId: 'role-external-id', + SnsCallerArn: { 'Fn::GetAtt': [ 'smsRoleA4587CE8', 'Arn' ] }, + }, + }); + }); + + test('setting enableSmsRole creates an sms role', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + enableSmsRole: true, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: { + ExternalId: 'pool', + SnsCallerArn: { 'Fn::GetAtt': [ 'poolsmsRole04048F13', 'Arn' ] }, + }, + }); + expect(stack).toHaveResource('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Condition: { + StringEquals: { + 'sts:ExternalId': 'pool', + }, + }, + Effect: 'Allow', + Principal: { + Service: 'cognito-idp.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + Policies: [ + { + PolicyDocument: { + Statement: [ + { + Action: 'sns:Publish', + Effect: 'Allow', + Resource: '*', + }, + ], + Version: '2012-10-17', + }, + PolicyName: 'sns-publish', + }, + ], + }); + }); + + test('auto sms role is not created when MFA and phoneVerification is off', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.OFF, + signInAliases: { + phone: false, + }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: ABSENT, + }); + }); + + test('auto sms role is not created when OTP-based MFA is enabled and phoneVerification is off', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.REQUIRED, + mfaSecondFactor: { + otp: true, + sms: false, + }, + signInAliases: { + phone: false, + }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: ABSENT, + }); + }); + + test('auto sms role is created when phone verification is turned on', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.OFF, + signInAliases: { phone: true }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: { + ExternalId: 'pool', + SnsCallerArn: { 'Fn::GetAtt': [ 'poolsmsRole04048F13', 'Arn' ] }, + }, + }); + }); + + test('auto sms role is created when phone auto-verification is set', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.OFF, + signInAliases: { phone: false }, + autoVerify: { phone: true }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: { + ExternalId: 'pool', + SnsCallerArn: { 'Fn::GetAtt': [ 'poolsmsRole04048F13', 'Arn' ] }, + }, + }); + }); + + test('auto sms role is created when MFA is turned on', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.REQUIRED, + mfaSecondFactor: { + sms: true, + otp: false, + }, + signInAliases: { + phone: false, + }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: { + ExternalId: 'pool', + SnsCallerArn: { 'Fn::GetAtt': [ 'poolsmsRole04048F13', 'Arn' ] }, + }, + }); + }); + + test('auto sms role is not created when enableSmsRole is unset, even when MFA is configured', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new UserPool(stack, 'pool', { + mfa: Mfa.REQUIRED, + mfaSecondFactor: { + sms: true, + otp: false, + }, + enableSmsRole: false, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPool', { + SmsConfiguration: ABSENT, + }); + }); + + test('throws an error when smsRole is specified but enableSmsRole is unset', () => { + const stack = new Stack(); + const smsRole = new Role(stack, 'smsRole', { + assumedBy: new ServicePrincipal('service.amazonaws.com'), + }); + + expect(() => new UserPool(stack, 'pool', { + smsRole, + enableSmsRole: false, + })).toThrow(/enableSmsRole cannot be disabled/); + }); + }); }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/test/integ.cognito.lit.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/test/integ.cognito.lit.expected.json index e35271c92c173..be3c5a7fe88d8 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/test/integ.cognito.lit.expected.json +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/test/integ.cognito.lit.expected.json @@ -453,43 +453,6 @@ ] } }, - "UserPoolsmsRole4EA729DD": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Condition": { - "StringEquals": { - "sts:ExternalId": "integcognitoUserPool7BB79D76" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cognito-idp.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "sns-publish" - } - ] - } - }, "UserPool6BA7E5F2": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -504,15 +467,6 @@ }, "EmailVerificationMessage": "The verification code to your new account is {####}", "EmailVerificationSubject": "Verify your new account", - "SmsConfiguration": { - "ExternalId": "integcognitoUserPool7BB79D76", - "SnsCallerArn": { - "Fn::GetAtt": [ - "UserPoolsmsRole4EA729DD", - "Arn" - ] - } - }, "SmsVerificationMessage": "The verification code to your new account is {####}", "VerificationMessageTemplate": { "DefaultEmailOption": "CONFIRM_WITH_CODE",