I had a similar requirement. First, the admin must create an account for john.deo@abc.com and jenny.deo@xyz.com (assume these are company users and both abc.com and xyz.com are having Google email accounts). A Cognito profile will be created for them.
When they sign in with their Google account, Cognito by default creates another account for them. So in the Cognito user pool, there will be 4 accounts in total.
To prevent this I was using the "Pre sign-up" trigger as suggested here.
But still, it was allowing any user with a Google account to Sign In. So I modified the code as following if there is no Cognito profile created already the user will be redirected back to the login screen with an error.
import json
import boto3
client = boto3.client('cognito-idp')
def lambda_handler(event, context):
print("Event: ", event)
email = event['request']['userAttributes']['email']
# Find a user with the same email
response = client.list_users(
UserPoolId=event['userPoolId'],
AttributesToGet=[
'email',
],
Filter='email = "{}"'.format(email)
)
if not hasattr(response, 'Users'):
return "You cannot Sign Up with this email";
print('Users found: ', response['Users'])
for user in response['Users']:
provider = None
provider_value = None
# Check which provider it is using
if event['userName'].startswith('google_'):
provider = 'Google'
provider_value = event['userName'].split('_')[1]
print('Linking accounts from Email {} with provider {}: '.format(
email,
provider
))
# If the signup is coming from a social provider, link the accounts
# with admin_link_provider_for_user function
if provider and provider_value:
print('> Linking user: ', user)
print('> Provider Id: ', provider_value)
response = client.admin_link_provider_for_user(
UserPoolId=event['userPoolId'],
DestinationUser={
'ProviderName': 'Cognito',
'ProviderAttributeValue': user['Username']
},
SourceUser={
'ProviderName': provider,
'ProviderAttributeName': 'Cognito_Subject',
'ProviderAttributeValue': provider_value
}
)
# Return the event to continue the workflow
return event