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 {}
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}
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
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()
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}
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)
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
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