Skip to content

Commit f7f4596

Browse files
author
amazon-meaisiah
committed
Merge 9c17ae1 into meaisiah-account
2 parents db6e324 + 9c17ae1 commit f7f4596

File tree

39 files changed

+2022
-544
lines changed

39 files changed

+2022
-544
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ aws cloudformation describe-stacks --query \
6666
You can override any of the parameters in the template using the `--parameter-overrides key="value"` format. This will be necessary if you intend to deploy several instances of the developer portal or customize some of the features. You can see a full list of overridable parameters in `cloudformation/template.yaml` under the `Parameters` section.
6767

6868
## Registering Users
69-
Users can self-register by clicking the 'Register' button in the developer portal. Cognito calls the `CognitoUserPoolsConfirmationStrategyFunction` to determine if the user is allowed to register themselves. By default, this function always accepts the user into the user pool, but you can customize the body of the function either in a local repository (followed by packaging and deploying) or in the lambda console. If you intend for the developer portal to be 'private' to some group of users (and not globally / freely accessible), you will need to write a lambda function that enforces your business logic for user registration. Documentation on this lambda function's use can be found [here](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html).
69+
Users can self-register by clicking the 'Register' button in the developer portal. Cognito calls the `CognitoPreSignupTriggerFn` lambda to determine if the user is allowed to register themselves. By default, this function always accepts the user into the user pool, but you can customize the body of the function either in a local repository (followed by packaging and deploying) or in the lambda console. If you intend for the developer portal to be 'private' to some group of users (and not globally / freely accessible), you will need to write a lambda function that enforces your business logic for user registration. Documentation on this lambda function's use can be found [here](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html).
7070

7171
### Promoting a User to an Admin
7272
Admin users can manage what APIs are visible to normal users and whether or not SDK generation is enabled (per api) for normal users. To promote a user to an admin, go to the Cognito console in the account the developer portal is in, select User Pools, then select the correct User Pool for the dev portal. From there, choose Users and groups, click on the users' name, choose Add to group, and select the group named `STACK-NAMEAdminsGroup`. This user is now an admin; if they're currently logged in, they will have to log out and back in to receive admin credentials.

cloudformation/template.yaml

+258-9
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ Parameters:
5656
Description: The name of the DynamoDB Customers table.
5757
Default: 'DevPortalCustomers'
5858

59+
DevPortalPreLoginAccountsTableName:
60+
Type: String
61+
Description: The name of the DynamoDB PreLoginAccounts table.
62+
Default: 'DevPortalPreLoginAccounts'
63+
5964
DevPortalAdminEmail:
6065
Type: String
6166
Description: The email address where user submitted feedback notifications get sent.
@@ -638,6 +643,20 @@ Resources:
638643
ReadCapacityUnits: 5
639644
WriteCapacityUnits: 5
640645

646+
PreLoginAccountsTable:
647+
Type: AWS::DynamoDB::Table
648+
Properties:
649+
TableName: !Ref DevPortalPreLoginAccountsTableName
650+
AttributeDefinitions:
651+
- AttributeName: UserId
652+
AttributeType: S
653+
KeySchema:
654+
- AttributeName: UserId
655+
KeyType: HASH
656+
ProvisionedThroughput:
657+
ReadCapacityUnits: 5
658+
WriteCapacityUnits: 5
659+
641660
FeedbackTable:
642661
Type: AWS::DynamoDB::Table
643662
Condition: EnableFeedbackSubmission
@@ -737,6 +756,15 @@ Resources:
737756
- !Ref 'AWS::AccountId'
738757
- :table/
739758
- !Ref CustomersTable
759+
- Effect: Allow
760+
Action:
761+
- dynamodb:GetItem
762+
- dynamodb:Query
763+
- dynamodb:Scan
764+
- dynamodb:PutItem
765+
- dynamodb:UpdateItem
766+
- dynamodb:DeleteItem
767+
Resource: !GetAtt PreLoginAccountsTable.Arn
740768
- Effect: Allow
741769
Action:
742770
- dynamodb:Query
@@ -777,8 +805,18 @@ Resources:
777805
- sns:Publish
778806
Resource: !Ref FeedbackSubmittedSNSTopic
779807
- !Ref 'AWS::NoValue'
808+
- Effect: Allow
809+
Action:
810+
- cognito-idp:ListUsers
811+
- cognito-idp:ListUsersInGroup
812+
- cognito-idp:AdminAddUserToGroup
813+
- cognito-idp:AdminCreateUser
814+
- cognito-idp:AdminDeleteUser
815+
- cognito-idp:AdminGetUser
816+
- cognito-idp:AdminListGroupsForUser
817+
Resource: !GetAtt CognitoUserPool.Arn
780818

781-
CognitoStrategyLambdaExecutionRole:
819+
CognitoPreSignupTriggerExecutionRole:
782820
Type: AWS::IAM::Role
783821
Properties:
784822
AssumeRolePolicyDocument:
@@ -801,6 +839,74 @@ Resources:
801839
- logs:PutLogEvents
802840
Resource: arn:aws:logs:*:*:*
803841

842+
CognitoPostConfirmationTriggerExecutionRole:
843+
Type: AWS::IAM::Role
844+
Properties:
845+
AssumeRolePolicyDocument:
846+
Version: '2012-10-17'
847+
Statement:
848+
Effect: Allow
849+
Principal:
850+
Service: lambda.amazonaws.com
851+
Action: sts:AssumeRole
852+
Path: '/'
853+
Policies:
854+
- PolicyName: root
855+
PolicyDocument:
856+
Version: '2012-10-17'
857+
Statement:
858+
- Effect: Allow
859+
Action:
860+
- logs:CreateLogGroup
861+
- logs:CreateLogStream
862+
- logs:PutLogEvents
863+
Resource: arn:aws:logs:*:*:*
864+
- Effect: Allow
865+
Action:
866+
- dynamodb:PutItem
867+
Resource: !GetAtt PreLoginAccountsTable.Arn
868+
- Effect: Allow
869+
Action:
870+
- cognito-idp:AdminAddUserToGroup
871+
Resource: !GetAtt CognitoUserPool.Arn
872+
873+
CognitoPostAuthenticationTriggerExecutionRole:
874+
Type: AWS::IAM::Role
875+
Properties:
876+
AssumeRolePolicyDocument:
877+
Version: '2012-10-17'
878+
Statement:
879+
Effect: Allow
880+
Principal:
881+
Service: lambda.amazonaws.com
882+
Action: sts:AssumeRole
883+
Path: '/'
884+
Policies:
885+
- PolicyName: root
886+
PolicyDocument:
887+
Version: '2012-10-17'
888+
Statement:
889+
- Effect: Allow
890+
Action:
891+
- logs:CreateLogGroup
892+
- logs:CreateLogStream
893+
- logs:PutLogEvents
894+
Resource: arn:aws:logs:*:*:*
895+
- Effect: Allow
896+
Action:
897+
- dynamodb:Scan
898+
- dynamodb:PutItem
899+
Resource: !GetAtt CustomersTable.Arn
900+
- Effect: Allow
901+
Action:
902+
- dynamodb:GetItem
903+
- dynamodb:PutItem
904+
Resource: !GetAtt PreLoginAccountsTable.Arn
905+
- Effect: Allow
906+
Action:
907+
- cognito-idp:AdminAddUserToGroup
908+
Resource: !GetAtt CognitoUserPool.Arn
909+
804910
CatalogUpdaterLambdaExecutionRole:
805911
Type: AWS::IAM::Role
806912
Properties:
@@ -968,11 +1074,41 @@ Resources:
9681074
- !Ref ApiGatewayApi
9691075
- '/*/*'
9701076

971-
LambdaCognitoUserPoolExecutionPermission:
1077+
CognitoPreSignupTriggerFnExecutionPermission:
9721078
Type: AWS::Lambda::Permission
9731079
Properties:
9741080
Action: lambda:InvokeFunction
975-
FunctionName: !GetAtt CognitoUserPoolsConfirmationStrategyFunction.Arn
1081+
FunctionName: !GetAtt CognitoPreSignupTriggerFn.Arn
1082+
Principal: cognito-idp.amazonaws.com
1083+
SourceArn: !Join
1084+
- ''
1085+
- - 'arn:aws:cognito-idp:'
1086+
- !Ref 'AWS::Region'
1087+
- ':'
1088+
- !Ref 'AWS::AccountId'
1089+
- ':userpool/'
1090+
- !Ref CognitoUserPool
1091+
1092+
CognitoPostConfirmationTriggerFnExecutionPermission:
1093+
Type: AWS::Lambda::Permission
1094+
Properties:
1095+
Action: lambda:InvokeFunction
1096+
FunctionName: !GetAtt CognitoPostConfirmationTriggerFn.Arn
1097+
Principal: cognito-idp.amazonaws.com
1098+
SourceArn: !Join
1099+
- ''
1100+
- - 'arn:aws:cognito-idp:'
1101+
- !Ref 'AWS::Region'
1102+
- ':'
1103+
- !Ref 'AWS::AccountId'
1104+
- ':userpool/'
1105+
- !Ref CognitoUserPool
1106+
1107+
CognitoPostAuthenticationTriggerFnExecutionPermission:
1108+
Type: AWS::Lambda::Permission
1109+
Properties:
1110+
Action: lambda:InvokeFunction
1111+
FunctionName: !GetAtt CognitoPostAuthenticationTriggerFn.Arn
9761112
Principal: cognito-idp.amazonaws.com
9771113
SourceArn: !Join
9781114
- ''
@@ -1030,10 +1166,15 @@ Resources:
10301166
WEBSITE_BUCKET_NAME: !Ref DevPortalSiteS3BucketName
10311167
StaticBucketName: !Ref ArtifactsS3BucketName
10321168
CustomersTableName: !Ref DevPortalCustomersTableName
1169+
PreLoginAccountsTableName: !Ref DevPortalPreLoginAccountsTableName
10331170
CatalogUpdaterFunctionArn: !GetAtt CatalogUpdaterLambdaFunction.Arn
10341171
FeedbackTableName: !Ref DevPortalFeedbackTableName
10351172
FeedbackSnsTopicArn:
10361173
!If [EnableFeedbackSubmission, !Ref FeedbackSubmittedSNSTopic, '']
1174+
UserPoolId: !Ref CognitoUserPool
1175+
AdminsGroupName: !Join ['', [!Ref 'AWS::StackName', 'AdminsGroup']]
1176+
RegisteredGroupName: !Sub '${AWS::StackName}-RegisteredGroup'
1177+
DevelopmentMode: !Ref DevelopmentMode
10371178
# Adds the API as a trigger
10381179
Events:
10391180
ProxyApiRoot:
@@ -1063,24 +1204,86 @@ Resources:
10631204
Layers:
10641205
- !Ref LambdaCommonLayer
10651206

1066-
CognitoUserPoolsConfirmationStrategyFunction:
1207+
CognitoPreSignupTriggerFn:
10671208
Type: AWS::Serverless::Function
10681209
Properties:
1069-
CodeUri: ../lambdas/cognito-user-pools-confirmation-strategy
1210+
FunctionName: !Sub '${AWS::StackName}-CognitoPreSignupTriggerFn'
1211+
CodeUri: ../lambdas/cognito-pre-signup-trigger
10701212
Handler: index.handler
10711213
MemorySize: 128
1072-
Role: !GetAtt CognitoStrategyLambdaExecutionRole.Arn
1073-
Runtime: nodejs12.x
1214+
Role: !GetAtt CognitoPreSignupTriggerExecutionRole.Arn
1215+
Runtime: nodejs10.x
1216+
Timeout: 3
1217+
Environment:
1218+
Variables:
1219+
AccountRegistrationMode: !Ref AccountRegistrationMode
1220+
Layers:
1221+
- !Ref LambdaCommonLayer
1222+
1223+
CognitoPostConfirmationTriggerFn:
1224+
Type: AWS::Serverless::Function
1225+
Properties:
1226+
FunctionName: !Sub '${AWS::StackName}-CognitoPostConfirmationTriggerFn'
1227+
CodeUri: ../lambdas/cognito-post-confirmation-trigger
1228+
Handler: index.handler
1229+
MemorySize: 128
1230+
Role: !GetAtt CognitoPostConfirmationTriggerExecutionRole.Arn
1231+
Runtime: nodejs10.x
1232+
Timeout: 3
1233+
Environment:
1234+
Variables:
1235+
AccountRegistrationMode: !Ref AccountRegistrationMode
1236+
PreLoginAccountsTableName: !Ref DevPortalPreLoginAccountsTableName
1237+
RegisteredGroupName: !Sub '${AWS::StackName}-RegisteredGroup'
1238+
Layers:
1239+
- !Ref LambdaCommonLayer
1240+
1241+
CognitoPostAuthenticationTriggerFn:
1242+
Type: AWS::Serverless::Function
1243+
Properties:
1244+
FunctionName: !Sub '${AWS::StackName}-CognitoPostAuthenticationTriggerFn'
1245+
CodeUri: ../lambdas/cognito-post-authentication-trigger
1246+
Handler: index.handler
1247+
MemorySize: 128
1248+
Role: !GetAtt CognitoPostAuthenticationTriggerExecutionRole.Arn
1249+
Runtime: nodejs10.x
10741250
Timeout: 3
1251+
Environment:
1252+
Variables:
1253+
CustomersTableName: !Ref DevPortalCustomersTableName
1254+
PreLoginAccountsTableName: !Ref DevPortalPreLoginAccountsTableName
1255+
RegisteredGroupName: !Sub '${AWS::StackName}-RegisteredGroup'
10751256
Layers:
10761257
- !Ref LambdaCommonLayer
10771258

10781259
CognitoUserPool:
10791260
Type: AWS::Cognito::UserPool
10801261
Properties:
10811262
UserPoolName: !Ref CognitoIdentityPoolName
1263+
# Lambda trigger caveats:
1264+
#
1265+
# - We can't use the functions' ARNs here, because there would be a
1266+
# circular dependency: some functions reference either the UserPool or
1267+
# UserPoolGroups within it.
1268+
#
1269+
# - You must declare an AWS::Lambda::Permission for each lambda here, or
1270+
# else calls from Cognito will fail with an AccessDeniedException. See
1271+
# `CognitoPreSignupTriggerFnExecutionPermission` as an example. More
1272+
# reading: <https://stackoverflow.com/a/42460847> and
1273+
# <https://forums.aws.amazon.com/thread.jspa?messageID=748566#748566>
10821274
LambdaConfig:
1083-
PreSignUp: !GetAtt CognitoUserPoolsConfirmationStrategyFunction.Arn
1275+
PreSignUp: !Join
1276+
- ''
1277+
- - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:'
1278+
- !Sub '${AWS::StackName}-CognitoPreSignupTriggerFn'
1279+
PostConfirmation: !Join
1280+
- ''
1281+
- - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:'
1282+
- !Sub '${AWS::StackName}-CognitoPostConfirmationTriggerFn'
1283+
PostAuthentication: !Join
1284+
- ''
1285+
- - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:'
1286+
- !Sub '${AWS::StackName}-CognitoPostAuthenticationTriggerFn'
10841287
Policies:
10851288
PasswordPolicy:
10861289
MinimumLength: 12
@@ -1264,6 +1467,7 @@ Resources:
12641467
Roles:
12651468
authenticated: !GetAtt CognitoAuthenticatedRole.Arn
12661469

1470+
# Every logged-in Cognito user is "authenticated".
12671471
CognitoAuthenticatedRole:
12681472
Type: AWS::IAM::Role
12691473
Properties:
@@ -1281,6 +1485,42 @@ Resources:
12811485
'cognito-identity.amazonaws.com:amr': authenticated
12821486
Policies:
12831487
- PolicyName: CognitoAuthenticatedRole
1488+
PolicyDocument:
1489+
Version: '2012-10-17'
1490+
Statement:
1491+
- Effect: Allow
1492+
Action:
1493+
- execute-api:Invoke
1494+
Resource: !Join
1495+
- ''
1496+
- - 'arn:aws:execute-api:'
1497+
- !Ref 'AWS::Region'
1498+
- ':'
1499+
- !Ref 'AWS::AccountId'
1500+
- ':'
1501+
- !Ref ApiGatewayApi
1502+
- /prod/*/signin
1503+
Path: '/'
1504+
1505+
# A logged-in Cognito user, who is not in a "pending" (invite or request)
1506+
# state, is "registered".
1507+
CognitoRegisteredRole:
1508+
Type: AWS::IAM::Role
1509+
Properties:
1510+
AssumeRolePolicyDocument:
1511+
Version: '2012-10-17'
1512+
Statement:
1513+
- Effect: Allow
1514+
Principal:
1515+
Federated: cognito-identity.amazonaws.com
1516+
Action: sts:AssumeRoleWithWebIdentity
1517+
Condition:
1518+
StringEquals:
1519+
'cognito-identity.amazonaws.com:aud': !Ref CognitoIdentityPool
1520+
'ForAnyValue:StringLike':
1521+
'cognito-identity.amazonaws.com:amr': authenticated
1522+
Policies:
1523+
- PolicyName: CognitoRegisteredRole
12841524
PolicyDocument:
12851525
Version: '2012-10-17'
12861526
Statement:
@@ -1326,7 +1566,7 @@ Resources:
13261566
'ForAnyValue:StringLike':
13271567
'cognito-identity.amazonaws.com:amr': authenticated
13281568
Policies:
1329-
- PolicyName: CognitoAuthenticatedRole
1569+
- PolicyName: CognitoAdminRole
13301570
PolicyDocument:
13311571
Version: '2012-10-17'
13321572
Statement:
@@ -1354,6 +1594,15 @@ Resources:
13541594
RoleArn: !GetAtt CognitoAdminRole.Arn
13551595
UserPoolId: !Ref CognitoUserPool
13561596

1597+
CognitoRegisteredGroup:
1598+
Type: AWS::Cognito::UserPoolGroup
1599+
Properties:
1600+
Description: 'Registered users in the developer portal'
1601+
GroupName: !Sub '${AWS::StackName}-RegisteredGroup'
1602+
Precedence: 1
1603+
RoleArn: !GetAtt CognitoRegisteredRole.Arn
1604+
UserPoolId: !Ref CognitoUserPool
1605+
13571606
CatalogUpdaterLambdaFunction:
13581607
Type: AWS::Serverless::Function
13591608
Properties:

0 commit comments

Comments
 (0)