Skip to content

Commit 880ca16

Browse files
yosefkriYossi Kricheli
andauthored
Bug Fix: Update Cognito Authentication Flow (#672)
Co-authored-by: Yossi Kricheli <[email protected]>
1 parent 3062b5a commit 880ca16

File tree

2 files changed

+97
-11
lines changed

2 files changed

+97
-11
lines changed

lib/authentication/index.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,18 +308,34 @@ export class Authentication extends Construct {
308308
role: lambdaRoleAddUserToGroup,
309309
logRetention: config.logRetention ?? logs.RetentionDays.ONE_WEEK,
310310
loggingFormat: lambda.LoggingFormat.JSON,
311+
environment: {
312+
DEFAULT_USER_GROUP: getConstructId("user", config),
313+
},
314+
}
315+
);
316+
317+
addFederatedUserToUserGroupLambda.addPermission(
318+
"CognitoPreSignUpTrigger",
319+
{
320+
principal: new iam.ServicePrincipal("cognito-idp.amazonaws.com"),
321+
sourceArn: userPool.userPoolArn,
311322
}
312323
);
324+
userPool.addTrigger(
325+
cognito.UserPoolOperation.PRE_SIGN_UP,
326+
addFederatedUserToUserGroupLambda
327+
);
313328

329+
// Add a second trigger for POST_CONFIRMATION to handle group assignment
314330
addFederatedUserToUserGroupLambda.addPermission(
315-
"CognitoPostAuthTrigger",
331+
"CognitoPostConfirmationTrigger",
316332
{
317333
principal: new iam.ServicePrincipal("cognito-idp.amazonaws.com"),
318334
sourceArn: userPool.userPoolArn,
319335
}
320336
);
321337
userPool.addTrigger(
322-
cognito.UserPoolOperation.POST_AUTHENTICATION,
338+
cognito.UserPoolOperation.POST_CONFIRMATION,
323339
addFederatedUserToUserGroupLambda
324340
);
325341

lib/authentication/lambda/addFederatedUserToUserGroup/index.py

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import boto3
22
from botocore.exceptions import ClientError
3+
import os
34

45

56
def get_user_groups(cognito, username, user_pool_id):
@@ -70,31 +71,100 @@ def add_user_to_group(cognito, username, group_name, user_pool_id):
7071

7172

7273
def handler(event, context):
73-
user_attributes = event["request"]["userAttributes"]
74-
print(f"User attributes {user_attributes}")
75-
# For federated users, the username will be the "sub" from the IdP
76-
username = event["request"]["userAttributes"]["sub"]
77-
new_group = event["request"]["userAttributes"].get("custom:chatbot_role")
78-
user_pool_id = event["userPoolId"]
79-
80-
# if federated user
81-
if new_group:
74+
print(f"Event received: {event}")
75+
76+
# Handle different trigger types with different event structures
77+
if "request" in event and "userAttributes" in event["request"]:
78+
# POST_AUTHENTICATION trigger
79+
user_attributes = event["request"]["userAttributes"]
80+
username = user_attributes.get("sub") or user_attributes.get("username")
81+
new_group = user_attributes.get("custom:chatbot_role")
82+
user_pool_id = event["userPoolId"]
83+
trigger_type = "POST_AUTHENTICATION"
84+
elif "userAttributes" in event:
85+
# PRE_AUTHENTICATION trigger
86+
user_attributes = event["userAttributes"]
87+
username = user_attributes.get("sub")
88+
new_group = user_attributes.get("custom:chatbot_role")
89+
user_pool_id = event["userPoolId"]
90+
trigger_type = "PRE_AUTHENTICATION"
91+
elif "request" in event and "userAttributes" in event["request"] and "validationData" in event["request"]:
92+
# POST_CONFIRMATION trigger
93+
user_attributes = event["request"]["userAttributes"]
94+
username = user_attributes.get("sub") or user_attributes.get("username")
95+
new_group = user_attributes.get("custom:chatbot_role")
96+
user_pool_id = event["userPoolId"]
97+
trigger_type = "POST_CONFIRMATION"
98+
elif "request" in event and "userAttributes" in event["request"] and "validationData" not in event["request"]:
99+
# PRE_SIGN_UP trigger
100+
user_attributes = event["request"]["userAttributes"]
101+
# For Pre sign-up, username might be in different fields
102+
username = user_attributes.get("sub") or user_attributes.get("username") or user_attributes.get("email")
103+
new_group = user_attributes.get("custom:chatbot_role")
104+
user_pool_id = event["userPoolId"]
105+
trigger_type = "PRE_SIGN_UP"
106+
else:
107+
print("No user attributes found in event")
108+
return event
109+
110+
print(f"Trigger type: {trigger_type}")
111+
print(f"User attributes: {user_attributes}")
112+
print(f"Username: {username}")
113+
print(f"New group: {new_group}")
114+
print(f"User pool ID: {user_pool_id}")
115+
116+
# Get default group from environment variable or use 'user' as fallback
117+
default_group = os.environ.get("DEFAULT_USER_GROUP", "user")
118+
119+
# If no custom:chatbot_role is provided, use default group
120+
if not new_group:
121+
new_group = default_group
122+
print(f"No custom:chatbot_role found, using default group: {default_group}")
123+
124+
# For Pre sign-up, we cannot assign groups because the user doesn't exist yet
125+
if trigger_type == "PRE_SIGN_UP":
126+
print("Pre sign-up trigger - user will be created after this trigger completes")
127+
print(f"Will assign user to group: {new_group}")
128+
print("Note: Group assignment will happen in a separate trigger (POST_CONFIRMATION)")
129+
130+
# For Pre sign-up, we can only validate or modify the sign-up request
131+
# We cannot assign groups yet as the user doesn't exist
132+
# The group assignment will need to happen in POST_CONFIRMATION or PRE_AUTHENTICATION
133+
134+
# You might want to add the group information to the user attributes
135+
# so it can be used later in POST_CONFIRMATION
136+
if "custom:chatbot_role" not in user_attributes:
137+
user_attributes["custom:chatbot_role"] = new_group
138+
print(f"Added custom:chatbot_role attribute: {new_group}")
139+
140+
return event
141+
142+
# For other triggers (PRE_AUTHENTICATION, POST_AUTHENTICATION, POST_CONFIRMATION)
143+
if username:
82144
cognito = boto3.client("cognito-idp")
83145

84146
current_groups = get_user_groups(
85147
cognito=cognito, username=username, user_pool_id=user_pool_id
86148
)
87149

150+
print(f"Current groups for user {username}: {current_groups}")
151+
152+
# Remove user from all groups except the new one
88153
for group in current_groups:
89154
if group != new_group:
90155
remove_user_from_group(cognito, username, group, user_pool_id)
91156

157+
# Add user to the new group if not already in it
92158
if new_group not in current_groups:
93159
add_user_to_group(
94160
cognito=cognito,
95161
username=username,
96162
group_name=new_group,
97163
user_pool_id=user_pool_id,
98164
)
165+
else:
166+
print(f"User {username} is already in group {new_group}")
167+
else:
168+
print("No username found in user attributes, skipping group assignment")
99169

100170
return event

0 commit comments

Comments
 (0)