diff --git a/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py b/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py index 9364839eb93..93e609f258f 100644 --- a/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py +++ b/aws_lambda_powertools/utilities/data_classes/cognito_user_pool_event.py @@ -68,7 +68,7 @@ def validation_data(self) -> Optional[Dict[str, str]]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the pre sign-up data_classes.""" + that you specify for the pre sign-up trigger.""" return self["request"].get("clientMetadata") @@ -135,7 +135,7 @@ def user_attributes(self) -> Dict[str, str]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the post confirmation data_classes.""" + that you specify for the post confirmation trigger.""" return self["request"].get("clientMetadata") @@ -172,7 +172,7 @@ def validation_data(self) -> Optional[Dict[str, str]]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the pre sign-up data_classes.""" + that you specify for the pre sign-up trigger.""" return self["request"].get("clientMetadata") @@ -283,7 +283,7 @@ def user_attributes(self) -> Dict[str, str]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the pre sign-up data_classes.""" + that you specify for the pre sign-up trigger.""" return self["request"].get("clientMetadata") @@ -329,9 +329,9 @@ class CustomMessageTriggerEvent(BaseTriggerEvent): - `CustomMessage_AdminCreateUser` To send the temporary password to a new user. - `CustomMessage_ResendCode` To resend the confirmation code to an existing user. - `CustomMessage_ForgotPassword` To send the confirmation code for Forgot Password request. - - `CustomMessage_UpdateUserAttribute` When a user's email or phone number is changed, this data_classes sends a + - `CustomMessage_UpdateUserAttribute` When a user's email or phone number is changed, this trigger sends a verification code automatically to the user. Cannot be used for other attributes. - - `CustomMessage_VerifyUserAttribute` This data_classes sends a verification code to the user when they manually + - `CustomMessage_VerifyUserAttribute` This trigger sends a verification code to the user when they manually request it for a new email or phone number. - `CustomMessage_Authentication` To send MFA code during authentication. @@ -369,7 +369,7 @@ def validation_data(self) -> Optional[Dict[str, str]]: class PreAuthenticationTriggerEvent(BaseTriggerEvent): """Pre Authentication Lambda Trigger - Amazon Cognito invokes this data_classes when a user attempts to sign in, allowing custom validation + Amazon Cognito invokes this trigger when a user attempts to sign in, allowing custom validation to accept or deny the authentication request. Notes: @@ -404,14 +404,14 @@ def user_attributes(self) -> Dict[str, str]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the post authentication data_classes.""" + that you specify for the post authentication trigger.""" return self["request"].get("clientMetadata") class PostAuthenticationTriggerEvent(BaseTriggerEvent): """Post Authentication Lambda Trigger - Amazon Cognito invokes this data_classes after signing in a user, allowing you to add custom logic + Amazon Cognito invokes this trigger after signing in a user, allowing you to add custom logic after authentication. Notes: @@ -462,7 +462,7 @@ def user_attributes(self) -> Dict[str, str]: @property def client_metadata(self) -> Optional[Dict[str, str]]: """One or more key-value pairs that you can provide as custom input to the Lambda function - that you specify for the pre token generation data_classes.""" + that you specify for the pre token generation trigger.""" return self["request"].get("clientMetadata") @@ -531,7 +531,7 @@ def claims_override_details(self) -> ClaimsOverrideDetails: class PreTokenGenerationTriggerEvent(BaseTriggerEvent): """Pre Token Generation Lambda Trigger - Amazon Cognito invokes this data_classes before token generation allowing you to customize identity token claims. + Amazon Cognito invokes this trigger before token generation allowing you to customize identity token claims. Notes: ---- @@ -558,3 +558,266 @@ def request(self) -> PreTokenGenerationTriggerEventRequest: def response(self) -> PreTokenGenerationTriggerEventResponse: """Pre Token Generation Response Parameters""" return PreTokenGenerationTriggerEventResponse(self._data) + + +class ChallengeResult(DictWrapper): + @property + def challenge_name(self) -> str: + """The challenge type. + + One of: CUSTOM_CHALLENGE, SRP_A, PASSWORD_VERIFIER, SMS_MFA, DEVICE_SRP_AUTH, + DEVICE_PASSWORD_VERIFIER, or ADMIN_NO_SRP_AUTH.""" + return self["challengeName"] + + @property + def challenge_result(self) -> bool: + """Set to true if the user successfully completed the challenge, or false otherwise.""" + return bool(self["challengeResult"]) + + @property + def challenge_metadata(self) -> Optional[str]: + """Your name for the custom challenge. Used only if challengeName is CUSTOM_CHALLENGE.""" + return self.get("challengeMetadata") + + +class DefineAuthChallengeTriggerEventRequest(DictWrapper): + @property + def user_attributes(self) -> Dict[str, str]: + """One or more name-value pairs representing user attributes. The attribute names are the keys.""" + return self["request"]["userAttributes"] + + @property + def user_not_found(self) -> Optional[bool]: + """A Boolean that is populated when PreventUserExistenceErrors is set to ENABLED for your user pool client. + A value of true means that the user id (user name, email address, etc.) did not match any existing users. """ + return self["request"].get("userNotFound") + + @property + def session(self) -> List[ChallengeResult]: + """An array of ChallengeResult elements, each of which contains the following elements:""" + return [ChallengeResult(result) for result in self["request"]["session"]] + + @property + def client_metadata(self) -> Optional[Dict[str, str]]: + """One or more key-value pairs that you can provide as custom input to the Lambda function that you specify + for the define auth challenge trigger.""" + return self["request"].get("clientMetadata") + + +class DefineAuthChallengeTriggerEventResponse(DictWrapper): + @property + def challenge_name(self) -> str: + return self["response"]["challengeName"] + + @property + def fail_authentication(self) -> bool: + return bool(self["response"]["failAuthentication"]) + + @property + def issue_tokens(self) -> bool: + return bool(self["response"]["issueTokens"]) + + @challenge_name.setter + def challenge_name(self, value: str): + """A string containing the name of the next challenge. + If you want to present a new challenge to your user, specify the challenge name here.""" + self["response"]["challengeName"] = value + + @fail_authentication.setter + def fail_authentication(self, value: bool): + """Set to true if you want to terminate the current authentication process, or false otherwise.""" + self["response"]["failAuthentication"] = value + + @issue_tokens.setter + def issue_tokens(self, value: bool): + """Set to true if you determine that the user has been sufficiently authenticated by + completing the challenges, or false otherwise.""" + self["response"]["issueTokens"] = value + + +class DefineAuthChallengeTriggerEvent(BaseTriggerEvent): + """Define Auth Challenge Lambda Trigger + + Amazon Cognito invokes this trigger to initiate the custom authentication flow. + + Notes: + ---- + `triggerSource` can be one of the following: + + - `DefineAuthChallenge_Authentication` Define Auth Challenge. + + Documentation: + -------------- + - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html + """ + + @property + def request(self) -> DefineAuthChallengeTriggerEventRequest: + """Define Auth Challenge Request Parameters""" + return DefineAuthChallengeTriggerEventRequest(self._data) + + @property + def response(self) -> DefineAuthChallengeTriggerEventResponse: + """Define Auth Challenge Response Parameters""" + return DefineAuthChallengeTriggerEventResponse(self._data) + + +class CreateAuthChallengeTriggerEventRequest(DictWrapper): + @property + def user_attributes(self) -> Dict[str, str]: + """One or more name-value pairs representing user attributes. The attribute names are the keys.""" + return self["request"]["userAttributes"] + + @property + def user_not_found(self) -> Optional[bool]: + """This boolean is populated when PreventUserExistenceErrors is set to ENABLED for your User Pool client.""" + return self["request"].get("userNotFound") + + @property + def challenge_name(self) -> str: + """The name of the new challenge.""" + return self["request"]["challengeName"] + + @property + def session(self) -> List[ChallengeResult]: + """An array of ChallengeResult elements, each of which contains the following elements:""" + return [ChallengeResult(result) for result in self["request"]["session"]] + + @property + def client_metadata(self) -> Optional[Dict[str, str]]: + """One or more key-value pairs that you can provide as custom input to the Lambda function that you + specify for the create auth challenge trigger..""" + return self["request"].get("clientMetadata") + + +class CreateAuthChallengeTriggerEventResponse(DictWrapper): + @property + def public_challenge_parameters(self) -> Dict[str, str]: + return self["response"]["publicChallengeParameters"] + + @property + def private_challenge_parameters(self) -> Dict[str, str]: + return self["response"]["privateChallengeParameters"] + + @property + def challenge_metadata(self) -> str: + return self["response"]["challengeMetadata"] + + @public_challenge_parameters.setter + def public_challenge_parameters(self, value: Dict[str, str]): + """One or more key-value pairs for the client app to use in the challenge to be presented to the user. + This parameter should contain all of the necessary information to accurately present the challenge to + the user.""" + self["response"]["publicChallengeParameters"] = value + + @private_challenge_parameters.setter + def private_challenge_parameters(self, value: Dict[str, str]): + """This parameter is only used by the Verify Auth Challenge Response Lambda trigger. + This parameter should contain all of the information that is required to validate the user's + response to the challenge. In other words, the publicChallengeParameters parameter contains the + question that is presented to the user and privateChallengeParameters contains the valid answers + for the question.""" + self["response"]["privateChallengeParameters"] = value + + @challenge_metadata.setter + def challenge_metadata(self, value: str): + """Your name for the custom challenge, if this is a custom challenge.""" + self["response"]["challengeMetadata"] = value + + +class CreateAuthChallengeTriggerEvent(BaseTriggerEvent): + """Create Auth Challenge Lambda Trigger + + Amazon Cognito invokes this trigger after Define Auth Challenge if a custom challenge has been + specified as part of the Define Auth Challenge trigger. + It creates a custom authentication flow. + + Notes: + ---- + `triggerSource` can be one of the following: + + - `CreateAuthChallenge_Authentication` Create Auth Challenge. + + Documentation: + -------------- + - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-create-auth-challenge.html + """ + + @property + def request(self) -> CreateAuthChallengeTriggerEventRequest: + """Create Auth Challenge Request Parameters""" + return CreateAuthChallengeTriggerEventRequest(self._data) + + @property + def response(self) -> CreateAuthChallengeTriggerEventResponse: + """Create Auth Challenge Response Parameters""" + return CreateAuthChallengeTriggerEventResponse(self._data) + + +class VerifyAuthChallengeResponseTriggerEventRequest(DictWrapper): + @property + def user_attributes(self) -> Dict[str, str]: + """One or more name-value pairs representing user attributes. The attribute names are the keys.""" + return self["request"]["userAttributes"] + + @property + def private_challenge_parameters(self) -> Dict[str, str]: + """This parameter comes from the Create Auth Challenge trigger, and is + compared against a user’s challengeAnswer to determine whether the user passed the challenge.""" + return self["request"]["privateChallengeParameters"] + + @property + def challenge_answer(self) -> Any: + """The answer from the user's response to the challenge.""" + return self["request"]["challengeAnswer"] + + @property + def client_metadata(self) -> Optional[Dict[str, str]]: + """One or more key-value pairs that you can provide as custom input to the Lambda function that + you specify for the verify auth challenge trigger.""" + return self["request"].get("clientMetadata") + + @property + def user_not_found(self) -> Optional[bool]: + """This boolean is populated when PreventUserExistenceErrors is set to ENABLED for your User Pool client.""" + return self["request"].get("userNotFound") + + +class VerifyAuthChallengeResponseTriggerEventResponse(DictWrapper): + @property + def answer_correct(self) -> bool: + return bool(self["response"]["answerCorrect"]) + + @answer_correct.setter + def answer_correct(self, value: bool): + """Set to true if the user has successfully completed the challenge, or false otherwise.""" + self["response"]["answerCorrect"] = value + + +class VerifyAuthChallengeResponseTriggerEvent(BaseTriggerEvent): + """Verify Auth Challenge Response Lambda Trigger + + Amazon Cognito invokes this trigger to verify if the response from the end user for a custom + Auth Challenge is valid or not. + It is part of a user pool custom authentication flow. + + Notes: + ---- + `triggerSource` can be one of the following: + + - `VerifyAuthChallengeResponse_Authentication` Verify Auth Challenge Response. + + Documentation: + -------------- + - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-verify-auth-challenge-response.html + """ + + @property + def request(self) -> VerifyAuthChallengeResponseTriggerEventRequest: + """Verify Auth Challenge Request Parameters""" + return VerifyAuthChallengeResponseTriggerEventRequest(self._data) + + @property + def response(self) -> VerifyAuthChallengeResponseTriggerEventResponse: + """Verify Auth Challenge Response Parameters""" + return VerifyAuthChallengeResponseTriggerEventResponse(self._data) diff --git a/aws_lambda_powertools/utilities/data_classes/ses_event.py b/aws_lambda_powertools/utilities/data_classes/ses_event.py index 518981618dc..c270a85ddf7 100644 --- a/aws_lambda_powertools/utilities/data_classes/ses_event.py +++ b/aws_lambda_powertools/utilities/data_classes/ses_event.py @@ -193,7 +193,7 @@ def ses(self) -> SESMessage: class SESEvent(DictWrapper): - """Amazon SES to receive message event data_classes + """Amazon SES to receive message event trigger NOTE: There is a 30-second timeout on RequestResponse invocations. diff --git a/docs/content/utilities/data_classes.mdx b/docs/content/utilities/data_classes.mdx index 22c6f4ec856..ec6d2eb5e11 100644 --- a/docs/content/utilities/data_classes.mdx +++ b/docs/content/utilities/data_classes.mdx @@ -114,6 +114,9 @@ Pre authentication | `data_classes.cognito_user_pool_event.PreAuthenticationTrig Pre sign-up | `data_classes.cognito_user_pool_event.PreSignUpTriggerEvent` Pre token generation | `data_classes.cognito_user_pool_event.PreTokenGenerationTriggerEvent` User migration | `data_classes.cognito_user_pool_event.UserMigrationTriggerEvent` +Define Auth Challenge | `data_classes.cognito_user_pool_event.DefineAuthChallengeTriggerEvent` +Create Auth Challenge | `data_classes.cognito_user_pool_event.CreateAuthChallengeTriggerEvent` +Verify Auth Challenge | `data_classes.cognito_user_pool_event.VerifyAuthChallengeResponseTriggerEvent` ```python:title=lambda_app.py from aws_lambda_powertools.utilities.cognito_user_pool_event import PostConfirmationTriggerEvent diff --git a/tests/events/cognitoCreateAuthChallengeEvent.json b/tests/events/cognitoCreateAuthChallengeEvent.json new file mode 100644 index 00000000000..ad018ae0829 --- /dev/null +++ b/tests/events/cognitoCreateAuthChallengeEvent.json @@ -0,0 +1,29 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "CreateAuthChallenge_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "create-auth@mail.com" + }, + "challengeName": "PASSWORD_VERIFIER", + "session" : [ + { + "challengeName": "CUSTOM_CHALLENGE", + "challengeResult": true, + "challengeMetadata": "CAPTCHA_CHALLENGE" + } + ], + "userNotFound": false + }, + "response": {} +} diff --git a/tests/events/cognitoDefineAuthChallengeEvent.json b/tests/events/cognitoDefineAuthChallengeEvent.json new file mode 100644 index 00000000000..80ea5ac2d98 --- /dev/null +++ b/tests/events/cognitoDefineAuthChallengeEvent.json @@ -0,0 +1,32 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "DefineAuthChallenge_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "define-auth@mail.com" + }, + "session" : [ + { + "challengeName": "PASSWORD_VERIFIER", + "challengeResult": true + }, + { + "challengeName": "CUSTOM_CHALLENGE", + "challengeResult": true, + "challengeMetadata": "CAPTCHA_CHALLENGE" + } + ], + "userNotFound": true + }, + "response": {} +} diff --git a/tests/events/cognitoPostAuthenticationEvent.json b/tests/events/cognitoPostAuthenticationEvent.json index 3b1faa81bf9..d34b18eebab 100644 --- a/tests/events/cognitoPostAuthenticationEvent.json +++ b/tests/events/cognitoPostAuthenticationEvent.json @@ -11,7 +11,7 @@ "request": { "newDeviceUsed": true, "userAttributes": { - "email": "test@mail.com" + "email": "post-auth@mail.com" } }, "response": {} diff --git a/tests/events/cognitoPreAuthenticationEvent.json b/tests/events/cognitoPreAuthenticationEvent.json index 75ff9ce34b3..661fea6372e 100644 --- a/tests/events/cognitoPreAuthenticationEvent.json +++ b/tests/events/cognitoPreAuthenticationEvent.json @@ -13,7 +13,7 @@ "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", "email_verified": "true", "name": "First Last", - "email": "test@mail.com" + "email": "pre-auth@mail.com" } }, "response": {} diff --git a/tests/events/cognitoVerifyAuthChallengeResponseEvent.json b/tests/events/cognitoVerifyAuthChallengeResponseEvent.json new file mode 100644 index 00000000000..2ebcdb5c278 --- /dev/null +++ b/tests/events/cognitoVerifyAuthChallengeResponseEvent.json @@ -0,0 +1,28 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "VerifyAuthChallengeResponse_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "verify-auth@mail.com" + }, + "privateChallengeParameters": { + "answer": "challengeAnswer" + }, + "clientMetadata" : { + "foo": "value" + }, + "challengeAnswer": "challengeAnswer", + "userNotFound": true + }, + "response": {} +} diff --git a/tests/functional/test_lambda_trigger_events.py b/tests/functional/test_lambda_trigger_events.py index 21e775b7a5f..d21266bfa0c 100644 --- a/tests/functional/test_lambda_trigger_events.py +++ b/tests/functional/test_lambda_trigger_events.py @@ -17,13 +17,16 @@ SQSEvent, ) from aws_lambda_powertools.utilities.data_classes.cognito_user_pool_event import ( + CreateAuthChallengeTriggerEvent, CustomMessageTriggerEvent, + DefineAuthChallengeTriggerEvent, PostAuthenticationTriggerEvent, PostConfirmationTriggerEvent, PreAuthenticationTriggerEvent, PreSignUpTriggerEvent, PreTokenGenerationTriggerEvent, UserMigrationTriggerEvent, + VerifyAuthChallengeResponseTriggerEvent, ) from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent from aws_lambda_powertools.utilities.data_classes.dynamo_db_stream_event import ( @@ -69,6 +72,7 @@ def test_cloud_watch_trigger_event(): def test_cognito_pre_signup_trigger_event(): event = PreSignUpTriggerEvent(load_event("cognitoPreSignUpEvent.json")) + # Verify BaseTriggerEvent properties assert event.version == "string" assert event.trigger_source == "PreSignUp_SignUp" assert event.region == "us-east-1" @@ -78,12 +82,13 @@ def test_cognito_pre_signup_trigger_event(): assert caller_context.aws_sdk_version == "awsSdkVersion" assert caller_context.client_id == "clientId" + # Verify properties user_attributes = event.request.user_attributes assert user_attributes["email"] == "user@example.com" - assert event.request.validation_data is None assert event.request.client_metadata is None + # Verify setters event.response.auto_confirm_user = True assert event.response.auto_confirm_user is True event.response.auto_verify_phone = True @@ -96,6 +101,8 @@ def test_cognito_pre_signup_trigger_event(): def test_cognito_post_confirmation_trigger_event(): event = PostConfirmationTriggerEvent(load_event("cognitoPostConfirmationEvent.json")) + assert event.trigger_source == "PostConfirmation_ConfirmSignUp" + user_attributes = event.request.user_attributes assert user_attributes["email"] == "user@example.com" assert event.request.client_metadata is None @@ -104,6 +111,8 @@ def test_cognito_post_confirmation_trigger_event(): def test_cognito_user_migration_trigger_event(): event = UserMigrationTriggerEvent(load_event("cognitoUserMigrationEvent.json")) + assert event.trigger_source == "UserMigration_Authentication" + assert compare_digest(event.request.password, event["request"]["password"]) assert event.request.validation_data is None assert event.request.client_metadata is None @@ -129,6 +138,8 @@ def test_cognito_user_migration_trigger_event(): def test_cognito_custom_message_trigger_event(): event = CustomMessageTriggerEvent(load_event("cognitoCustomMessageEvent.json")) + assert event.trigger_source == "CustomMessage_AdminCreateUser" + assert event.request.code_parameter == "####" assert event.request.username_parameter == "username" assert event.request.user_attributes["phone_number_verified"] is False @@ -145,24 +156,30 @@ def test_cognito_custom_message_trigger_event(): def test_cognito_pre_authentication_trigger_event(): event = PreAuthenticationTriggerEvent(load_event("cognitoPreAuthenticationEvent.json")) + assert event.trigger_source == "PreAuthentication_Authentication" + assert event.request.user_not_found is None event["request"]["userNotFound"] = True assert event.request.user_not_found is True - assert event.request.user_attributes["email"] == "test@mail.com" + assert event.request.user_attributes["email"] == "pre-auth@mail.com" assert event.request.validation_data is None def test_cognito_post_authentication_trigger_event(): event = PostAuthenticationTriggerEvent(load_event("cognitoPostAuthenticationEvent.json")) + assert event.trigger_source == "PostAuthentication_Authentication" + assert event.request.new_device_used is True - assert event.request.user_attributes["email"] == "test@mail.com" + assert event.request.user_attributes["email"] == "post-auth@mail.com" assert event.request.client_metadata is None def test_cognito_pre_token_generation_trigger_event(): event = PreTokenGenerationTriggerEvent(load_event("cognitoPreTokenGenerationEvent.json")) + assert event.trigger_source == "TokenGeneration_Authentication" + group_configuration = event.request.group_configuration assert group_configuration.groups_to_override == [] assert group_configuration.iam_roles_to_override == [] @@ -209,6 +226,80 @@ def test_cognito_pre_token_generation_trigger_event(): assert event["response"]["claimsOverrideDetails"]["groupOverrideDetails"]["preferredRole"] == "role_name" +def test_cognito_define_auth_challenge_trigger_event(): + event = DefineAuthChallengeTriggerEvent(load_event("cognitoDefineAuthChallengeEvent.json")) + + assert event.trigger_source == "DefineAuthChallenge_Authentication" + + # Verify properties + assert event.request.user_attributes["email"] == "define-auth@mail.com" + assert event.request.user_not_found is True + session = event.request.session + assert len(session) == 2 + assert session[0].challenge_name == "PASSWORD_VERIFIER" + assert session[0].challenge_result is True + assert session[0].challenge_metadata is None + assert session[1].challenge_metadata == "CAPTCHA_CHALLENGE" + assert event.request.client_metadata is None + + # Verify setters + event.response.challenge_name = "CUSTOM_CHALLENGE" + assert event.response.challenge_name == event["response"]["challengeName"] + assert event.response.challenge_name == "CUSTOM_CHALLENGE" + event.response.fail_authentication = True + assert event.response.fail_authentication is True + assert event.response.fail_authentication == event["response"]["failAuthentication"] + event.response.issue_tokens = True + assert event.response.issue_tokens is True + assert event.response.issue_tokens == event["response"]["issueTokens"] + + +def test_create_auth_challenge_trigger_event(): + event = CreateAuthChallengeTriggerEvent(load_event("cognitoCreateAuthChallengeEvent.json")) + + assert event.trigger_source == "CreateAuthChallenge_Authentication" + + # Verify properties + assert event.request.user_attributes["email"] == "create-auth@mail.com" + assert event.request.user_not_found is False + assert event.request.challenge_name == "PASSWORD_VERIFIER" + session = event.request.session + assert len(session) == 1 + assert session[0].challenge_name == "CUSTOM_CHALLENGE" + assert session[0].challenge_metadata == "CAPTCHA_CHALLENGE" + assert event.request.client_metadata is None + + # Verify setters + event.response.public_challenge_parameters = {"test": "value"} + assert event.response.public_challenge_parameters == event["response"]["publicChallengeParameters"] + assert event.response.public_challenge_parameters["test"] == "value" + event.response.private_challenge_parameters = {"private": "value"} + assert event.response.private_challenge_parameters == event["response"]["privateChallengeParameters"] + assert event.response.private_challenge_parameters["private"] == "value" + event.response.challenge_metadata = "meta" + assert event.response.challenge_metadata == event["response"]["challengeMetadata"] + assert event.response.challenge_metadata == "meta" + + +def test_verify_auth_challenge_response_trigger_event(): + event = VerifyAuthChallengeResponseTriggerEvent(load_event("cognitoVerifyAuthChallengeResponseEvent.json")) + + assert event.trigger_source == "VerifyAuthChallengeResponse_Authentication" + + # Verify properties + assert event.request.user_attributes["email"] == "verify-auth@mail.com" + assert event.request.private_challenge_parameters["answer"] == "challengeAnswer" + assert event.request.challenge_answer == "challengeAnswer" + assert event.request.client_metadata is not None + assert event.request.client_metadata["foo"] == "value" + assert event.request.user_not_found is True + + # Verify setters + event.response.answer_correct = True + assert event.response.answer_correct == event["response"]["answerCorrect"] + assert event.response.answer_correct is True + + def test_dynamo_db_stream_trigger_event(): event = DynamoDBStreamEvent(load_event("dynamoStreamEvent.json"))