AWS Cognito forgot_password Python call - strange behavior

Viewed 93

Function code:

import json
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import uuid
USER_POOL_ID = 'us-east-X_XXX'
CLIENT_ID = 'XXXXXXXXXX'
CLIENT_SECRET = 'XXXXXXXXXXXXX'


def get_secret_hash(username):
    msg = username + CLIENT_ID
    dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'),
                   msg=str(msg).encode('utf-8'),
                   digestmod=hashlib.sha256).digest()
    d2 = base64.b64encode(dig).decode()
    return d2


def lambda_handler(event, context):
    for field in ["username"]:
        if not event.get(field):
            return {"error": False, "success": True, 'message': f"{field} is not present", "data": None}
    client = boto3.client('cognito-idp')
    username = event['username']
    try:
        print('username - ', username)
        response = client.forgot_password(
            ClientId=CLIENT_ID,
            SecretHash=get_secret_hash(username),
            Username=username,
        )
    except client.exceptions.UserNotFoundException:
        return {"error": True, "success": False, "message":   "Username doesnt exists"}

    except client.exceptions.InvalidParameterException:
        return {"error": True, "success": False, "data": None, "message": f"User <{username}> is not confirmed yet"}

    except Exception as e:
        return {"error": True, "success": False, "message": f"Unknown error {e.__str__()} "}

    print(response)
    return {"error": False, "success": True, "message": f"Please check your Registered email id for validation code", "data": None}

It contains several redundant print statements for debugging.

I call the function:

event = {"username": "exists_in_user_pool_OK"}
handler_response = lambda_handler(event, {})
print(handler_response)

When I submit the real username everything is OK.

It is expected that if I submit the name of a non-existent user, an exception will be thrown. However, when I try it, no exception is thrown. The function seems to work fine and even sends a confirmation code somewhere.

Example 1:

username - non_existent

{'CodeDeliveryDetails': {'Destination': 'n***@y***.com', 'DeliveryMedium': 'EMAIL', 'AttributeName': 'email'}, 'ResponseMetadata': {'RequestId': '87a0b1af-5322-46a2-bf7b-a1afed2639f1', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Wed, 10 Nov 2021 13:55:51 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '104', 'connection': 'keep-alive', 'x-amzn-requestid': '87a0b1af-5322-46a2-bf7b-a1afed2639f1'}, 'RetryAttempts': 0}}

{'error': False, 'success': True, 'message': 'Please check your Registered email id for validation code', 'data': None}

Example 2:

username - some_more_non_existent_user

{'CodeDeliveryDetails': {'Destination': 's***@g***.com', 'DeliveryMedium': 'EMAIL', 'AttributeName': 'email'}, 'ResponseMetadata': {'RequestId': '9b552993-850a-4523-9a88-4160eb5a112c', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Wed, 10 Nov 2021 14:05:11 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '104', 'connection': 'keep-alive', 'x-amzn-requestid': '9b552993-850a-4523-9a88-4160eb5a112c'}, 'RetryAttempts': 0}}

{'error': False, 'success': True, 'message': 'Please check your Registered email id for validation code', 'data': None}

What's going on here? Why isn't an exception thrown?

'Destination': 'n***@y***.com'

'Destination': 's***@g***.com'

What is it? Why did it change?

How do I make the function to throw an exception if the user is not in the User Pool?

0 Answers
Related