Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Federated Identities to User Pool #3

Open
junaway opened this issue Sep 9, 2018 · 1 comment
Open

Adding Federated Identities to User Pool #3

junaway opened this issue Sep 9, 2018 · 1 comment

Comments

@junaway
Copy link

junaway commented Sep 9, 2018

Here's my extension to handle Federated Identities right into User Pools.

const AWS = require('aws-sdk');

exports.handler = async (event) => {
    try {
        var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
        
        switch (event.RequestType) {
            case 'Create':
                console.info(`CFE-Cognito-UserPoolFederation ${event.RequestType} - IN PROGRESS`);
                await cognitoIdentityServiceProvider.createIdentityProvider({
                    UserPoolId: event.ResourceProperties.UserPoolId,
                    ProviderName: event.ResourceProperties.ProviderName,
                    ProviderType: event.ResourceProperties.ProviderType,
                    ProviderDetails: event.ResourceProperties.ProviderDetails,
                    AttributeMapping: event.ResourceProperties.AttributeMapping,
                }).promise();
                break;
                
            case 'Update':
                console.info(`CFE-Cognito-UserPoolFederation ${event.RequestType} - IN PROGRESS`);
                await deleteIdentityProvider(cognitoIdentityServiceProvider, 
                                             event.OldResourceProperties.UserPoolId,
                                             event.OldResourceProperties.ProviderName);
                await cognitoIdentityServiceProvider.createIdentityProvider({
                    UserPoolId: event.ResourceProperties.UserPoolId,
                    ProviderName: event.ResourceProperties.ProviderName,
                    ProviderType: event.ResourceProperties.ProviderType,
                    ProviderDetails: event.ResourceProperties.ProviderDetails,
                    AttributeMapping: event.ResourceProperties.AttributeMapping
                }).promise();
                break;
                
            case 'Delete':
                console.info(`CFE-Cognito-UserPoolFederation ${event.RequestType} - IN PROGRESS`);
                await deleteIdentityProvider(cognitoIdentityServiceProvider, 
                                             event.ResourceProperties.UserPoolId,
                                             event.ResourceProperties.ProviderName);
                break;
        }
        
        await sendCloudFormationResponse(event, 'SUCCESS');
        console.info(`CFE-Cognito-UserPoolFederation ${event.RequestType} - SUCCESS`);
    } catch (error) {
        console.error(`CFE-Cognito-UserPoolFederation ${event.RequestType} - FAILED:`, error);
        await sendCloudFormationResponse(event, 'FAILED', event);
    }
}

async function deleteIdentityProvider(cognitoIdentityServiceProvider, userPoolId, providerName) {
    var response = await cognitoIdentityServiceProvider.describeIdentityProvider({
        UserPoolId: userPoolId,
        ProviderName: providerName
    }).promise();
    
    if (response.IdentityProvider.UserPoolId) {
        await cognitoIdentityServiceProvider.deleteIdentityProvider({
            UserPoolId: response.IdentityProvider.UserPoolId,
            ProviderName: providerName
        }).promise();
    }
}

async function sendCloudFormationResponse(event, responseStatus, responseData) {
    var params = {
        FunctionName: 'CloudFormationSendResponse',
        InvocationType: 'RequestResponse',
        Payload: JSON.stringify({
            StackId: event.StackId,
            RequestId: event.RequestId,
            LogicalResourceId: event.LogicalResourceId,
            ResponseURL: event.ResponseURL,
            ResponseStatus: responseStatus,
            ResponseData: responseData
        })
    };
    
    var lambda = new AWS.Lambda();
    var response = await lambda.invoke(params).promise();
    
    if (response.FunctionError) {
        var responseError = JSON.parse(response.Payload);
        throw new Error(responseError.errorMessage);
    }
}

The required Lambda Role is:

CFECognitoRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: CFE-Cognito-Role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: 'sts:AssumeRole'
          Principal:
            Service: lambda.amazonaws.com
      Policies:
      - PolicyName: CFE-Cognito-WriteCloudWatchLogs
        PolicyDocument: 
          Version: '2012-10-17'
          Statement: 
          - Effect: Allow
            Action:
              - 'logs:CreateLogGroup'
              - 'logs:DeleteLogGroup'
              - 'logs:CreateLogStream'
              - 'logs:DeleteLogStream'
              - 'logs:PutLogEvents'
            Resource: 'arn:aws:logs:*:*:*'
      - PolicyName: CFE-Cognito-InvokeLambdaFunction
        PolicyDocument: 
          Version: '2012-10-17'
          Statement: 
          - Effect: Allow
            Action: 'lambda:InvokeFunction'
            Resource: 'arn:aws:lambda:*:*:function:*'
      - PolicyName: CFE-Cognito-ManageUserPoolIdentityProvider
        PolicyDocument: 
          Version: '2012-10-17'
          Statement: 
          - Effect: Allow
            Action:
            - 'cognito-idp:CreateIdentityProvider'
            - 'cognito-idp:DeleteIdentityProvider'
            Resource: 'arn:aws:cognito-idp:*:*:userpool/*'
          - Effect: Allow
            Action: 'cognito-idp:DescribeIdentityProvider'
            Resource: '*'

There. Didn't bother making a PR, sorry.

@Russ-K
Copy link

Russ-K commented Dec 31, 2018

@juanpablovega / @rosberglinhares - I've created a PR for this including an example custom resource for a Google Identity Provider.

See #8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants