Example #1
0
def post(request, cognitoUsername):
    try:
        account_utils.get_user_pool_client().admin_reset_user_password(UserPoolId=account_utils.get_user_pool_id(), Username=cognitoUsername)
    except botocore.exceptions.ClientError as e:
        message = e.response.get('Error', {}).get('Message')
        raise errors.ClientError(message)
    return {}
Example #2
0
def default_search():
    listUsersResponse = account_utils.get_user_pool_client().list_users(
        UserPoolId=account_utils.get_user_pool_id(), Limit=50)
    usersByName = {
        user.get('Username', ''): user
        for user in listUsersResponse.get('Users', [])
    }

    accounts = []
    scanResponse = account_utils.get_account_table().scan(Limit=50)
    for accountItem in scanResponse.get('Items', []):
        account = account_utils.convert_account_from_dynamo_to_admin_model(
            accountItem)
        username = account.get('CognitoUsername')
        if username:
            user = usersByName.get(username)
            if user:
                account['IdentityProviders'] = {
                    account_utils.IDP_COGNITO:
                    account_utils.convert_user_from_cognito_to_model(user)
                }
                del usersByName[username]
            else:
                populate_identity_provider(account)
        accounts.append(account)

    for username, user in usersByName.iteritems():
        account = populate_account_for_user(user)
        accounts.append(account)

    accounts.sort(cmp=account_utils.compare_accounts)

    return {'Accounts': accounts}
def post(request, cognitoUsername):
    try:
        account_utils.get_user_pool_client().admin_confirm_sign_up(
            UserPoolId=account_utils.get_user_pool_id(),
            Username=cognitoUsername)
    except botocore.exceptions.ClientError as e:
        code = e.response.get('Error', {}).get('Code')
        message = e.response.get('Error', {}).get('Message')

        if code == 'NotAuthorizedException' and 'CONFIRMED' in message:
            print 'The user is already confirmed: {}'.format(message)
            return {}

        raise

    return {}
def __get_identity_provider_response(event, password):
    idpResponse = account_utils.get_user_pool_client().admin_initiate_auth(
        UserPoolId=event['userPoolId'],
        ClientId=event['callerContext']['clientId'],
        AuthFlow='ADMIN_NO_SRP_AUTH',
        AuthParameters={
            'USERNAME': event['userName'],
            'PASSWORD': password
        })
    return idpResponse
def get(request, IdentityProviderId):
    if IdentityProviderId != account_utils.IDP_COGNITO:
        raise errors.ClientError(
            'Only the {} identity provider is supported.'.format(
                account_utils.IDP_COGNITO))

    pool = account_utils.get_user_pool_client().describe_user_pool(
        UserPoolId=account_utils.get_user_pool_id())
    numberOfUsers = pool.get('UserPool', {}).get('EstimatedNumberOfUsers', 0)

    return {'EstimatedNumberOfUsers': numberOfUsers}
Example #6
0
def load_user(account):
    if 'CognitoUsername' in account:
        try:
            user = account_utils.get_user_pool_client().admin_get_user(
                UserPoolId=account_utils.get_user_pool_id(),
                Username=account['CognitoUsername']
            )
            account['IdentityProviders'] = {}
            account['IdentityProviders'][account_utils.IDP_COGNITO] = account_utils.convert_user_from_cognito_to_model(user)
        except botocore.exceptions.ClientError as e:
            code = e.response.get('Error', {}).get('Code', None)
            if code == 'UserNotFoundException':
                print 'User {} not found for account {}.'.format(account['CognitoUsername'], account.get('AccountId'))
                return
            raise
Example #7
0
def populate_identity_provider(account):
    if 'CognitoUsername' in account:
        try:
            user = account_utils.get_user_pool_client().admin_get_user(
                UserPoolId=account_utils.get_user_pool_id(),
                Username=account['CognitoUsername'])
            if 'IdentityProviders' not in account:
                account['IdentityProviders'] = {}
            account['IdentityProviders'][
                account_utils.
                IDP_COGNITO] = account_utils.convert_user_from_cognito_to_model(
                    user)
        except:
            print 'Failed to lookup username {} for account {}:'.format(
                account['CognitoUsername'], account['AccountId'])
            traceback.print_exc()
Example #8
0
def search_by_email(Email):
    response = account_utils.get_user_pool_client().list_users(
        UserPoolId=account_utils.get_user_pool_id(),
        Filter='email ^= "{}"'.format(Email.replace('"', '')),
        Limit=20)

    users = response.get('Users', [])
    if not users:
        print 'No users found for the requested email prefix.'
        return {'Accounts': []}

    accounts = []

    for user in users:
        accounts.append(populate_account_for_user(user))

    accounts.sort(cmp=account_utils.compare_accounts)

    return {'Accounts': accounts}
def search_by_username(Username):
    response = account_utils.get_user_pool_client().list_users(
        UserPoolId=account_utils.get_user_pool_id(),
        Filter='username ^= "{}"'.format(Username.replace('"', '')),
        Limit=20)

    users = response.get('Users', [])
    if not users:
        print('No users found for the requested username prefix.')
        return {'Accounts': []}

    accounts = []

    for user in users:
        accounts.append(populate_account_for_user(user))

    accounts.sort(key=functools.cmp_to_key(account_utils.compare_accounts))

    return {'Accounts': accounts}
Example #10
0
def put(request, cognitoUsername, UpdateCognitoUser=None):
    updates = []
    if UpdateCognitoUser:
        for key, value in iteritems(UpdateCognitoUser):
            if key in account_utils.COGNITO_ATTRIBUTES:
                updates.append({'Name': key, 'Value': value})
            else:
                raise errors.ClientError('Invalid field {}.'.format(key))

    if updates:
        response = account_utils.get_user_pool_client(
        ).admin_update_user_attributes(
            UserPoolId=account_utils.get_user_pool_id(),
            Username=cognitoUsername,
            UserAttributes=updates)
        print('Updated: {}'.format(account_utils.logging_filter(updates)))
    else:
        print('No updates provided in the request')

    user = account_utils.get_user(cognitoUsername)
    return account_utils.convert_user_from_cognito_to_model(user)
Example #11
0
def verify_auth_challenge_response(event):
    if 'privateChallengeParameters' not in event['request'] or 'type' not in event['request']['privateChallengeParameters']:
        print 'The request is missing privateChallengeParameters.type'
        event['response']['answerCorrect'] = False
        return

    challenge_type = event['request']['privateChallengeParameters']['type']
    password = None
    new_password = None
    if challenge_type == 'BasicAuth':
        password = event['request']['challengeAnswer']
    elif challenge_type == 'ForceChangePassword':
        try:
            answer = json.loads(event['request']['challengeAnswer'])
        except ValueError as e:
            print 'Unable to parse the answer for ForceChangePassword as json'
            event['response']['answerCorrect'] = False
            return

        password = answer.get('password')
        new_password = answer.get('newPassword')
        if password == None or new_password == None:
            print 'The answer for the ForceChangePassword challenge is missing the password or newPassword.'
            event['response']['answerCorrect'] = False
            return
    else:
        print 'Unsupported challenge type: {}'.format(challenge_type)
        event['response']['answerCorrect'] = False
        return

    # Use the provided username and password to attempt authentication using the admin API.
    try:
        idpResponse = account_utils.get_user_pool_client().admin_initiate_auth(
            UserPoolId = event['userPoolId'],
            ClientId = event['callerContext']['clientId'],
            AuthFlow = 'ADMIN_NO_SRP_AUTH',
            AuthParameters = {
                'USERNAME': event['userName'],
                'PASSWORD': password
            }
        )
    except:
        traceback.print_exc()
        raise errors.ClientError("Authentication failed")

    if 'AuthenticationResult' not in idpResponse:
        if 'ChallengeName' in idpResponse:
            print 'The response from AdminInitiateAuth contained a {} challenge.'.format(idpResponse.get('ChallengeName'))

        if idpResponse.get('ChallengeName') == 'NEW_PASSWORD_REQUIRED':
            idpResponse = account_utils.get_user_pool_client().admin_respond_to_auth_challenge(
                UserPoolId=event['userPoolId'],
                ClientId=event['callerContext']['clientId'],
                ChallengeName='NEW_PASSWORD_REQUIRED',
                ChallengeResponses={
                    'NEW_PASSWORD': new_password,
                    'USERNAME': event['userName']
                },
                Session=idpResponse['Session']
            )

            if 'AuthenticationResult' not in idpResponse:
                if 'ChallengeName' in idpResponse:
                    print 'The response from AdminInitiateAuth contained a {} challenge.'.format(idpResponse.get('ChallengeName'))
                print 'Authentication failed: the response from AdminInitiateAuth did not contain AuthenticationResult'
                event['response']['answerCorrect'] = False
                return
        else:
            print 'Authentication failed: the response from AdminInitiateAuth did not contain AuthenticationResult'
            event['response']['answerCorrect'] = False
            return

    if 'IdToken' not in idpResponse['AuthenticationResult']:
        print 'The response from AdminInitiateAuth did not contain an IdToken'
        event['response']['answerCorrect'] = False
        return

    # Use the token to get the identity for the user.
    provider_id = 'cognito-idp.' + event['region'] + '.amazonaws.com/' + event['userPoolId']
    idResponse = account_utils.get_identity_pool_client().get_id(
        IdentityPoolId = account_utils.get_identity_pool_id(),
        Logins = {
            provider_id: idpResponse['AuthenticationResult']['IdToken']
        }
    )

    if 'IdentityId' not in idResponse:
        print 'The response from GetId did not contain an IdentityId'
        event['response']['answerCorrect'] = False
        return

    # Update the identity to username mapping.
    account = account_utils.get_account_for_identity(idResponse['IdentityId'])
    if account:
        if account.get('AccountBlacklisted'):
            raise errors.ClientError("Authentication failed: the account is blacklisted")

        account_utils.update_account({
             'AccountId': account['AccountId'],
             'CognitoIdentityId': idResponse['IdentityId'],
             'CognitoUsername': event['userName']
        })
    else:
        account_utils.create_account({
             'AccountId': str(uuid.uuid4()),
             'CognitoIdentityId': idResponse['IdentityId'],
             'CognitoUsername': event['userName']
        })

    event['response']['answerCorrect'] = True
Example #12
0
def put_account(AccountId, AccountRequest, create_account):
    account_utils.validate_account_update_request(AccountRequest)

    # Collect the attribute changes for the Cognito user.
    cognito_request = AccountRequest.get('IdentityProviders', {}).get(account_utils.IDP_COGNITO, {})
    cognito_updates = get_cognito_updates(cognito_request)

    # Get the existing account if needed and determine the Cognito username.
    create_user = False
    existing_account = {}
    username = None
    if create_account:
        username = AccountRequest.get('CognitoUsername')
        create_user = '******' in AccountRequest
    else:
        existing_account = account_utils.get_account_table().get_item(Key = { 'AccountId': AccountId }, ConsistentRead = False).get('Item', {})
        username = existing_account.get('CognitoUsername')
        if 'CognitoUsername' in AccountRequest and 'CognitoUsername' in existing_account and username != AccountRequest.get('CognitoUsername'):
            raise errors.ClientError('Changing the account username is not supported.')
        create_user = '******' in AccountRequest and 'CognitoUsername' not in existing_account

    if cognito_updates and not username:
        raise errors.ClientError('Unable to update Cognito: There is no Cognito user associated with this account.')

    # Collect the attribute changes for the account row.
    account_updates, delete_keys, added_to_blacklist = get_account_updates(AccountRequest, existing_account)

    # Create or update the account.
    updated_account = None
    account = account_updates.copy()
    account['AccountId'] = AccountId
    if create_account:
        account_utils.create_account(account)
        updated_account = account
        print 'Created account: ', account
    elif account_updates or delete_keys:
        updated_account = account_utils.update_account(account, delete_keys, existing_account)
        print 'Updated account: ', account

    # Create or update the Cognito user, and roll back the account changes if that fails.
    try:
        if create_user:
            account_utils.get_user_pool_client().admin_create_user(
                UserPoolId=account_utils.get_user_pool_id(),
                Username=username,
                UserAttributes=cognito_updates,
                DesiredDeliveryMediums=['EMAIL']
            )
            print 'Created: ', account_utils.logging_filter(cognito_updates)
        elif cognito_updates:
            account_utils.get_user_pool_client().admin_update_user_attributes(
                UserPoolId=account_utils.get_user_pool_id(),
                Username=username,
                UserAttributes=cognito_updates
            )
            print 'Updated: ', account_utils.logging_filter(cognito_updates)
    except botocore.exceptions.ClientError as e:
        if updated_account:
            undo_account_changes(AccountId, create_account, existing_account, account_updates)

        code = e.response.get('Error', {}).get('Code', None)
        if code == 'UserNotFoundException':
            raise errors.ClientError('User does not exist in Cognito.')
        if code == 'UsernameExistsException':
            raise errors.ClientError('The username already exists in Cognito.')
        raise
    except:
        if updated_account:
            undo_account_changes(AccountId, create_account, existing_account, account_updates)

        raise

    if added_to_blacklist and username:
        # Invalidate existing tokens for the user after adding to the blacklist.
        account_utils.get_user_pool_client().admin_user_global_sign_out(UserPoolId=account_utils.get_user_pool_id(), Username=username)

    account = account_utils.convert_account_from_dynamo_to_admin_model(updated_account or existing_account)
    load_user(account)

    return account