Example usage for com.amazonaws.services.cognitoidentity.model UpdateIdentityPoolRequest setIdentityPoolId

List of usage examples for com.amazonaws.services.cognitoidentity.model UpdateIdentityPoolRequest setIdentityPoolId

Introduction

In this page you can find the example usage for com.amazonaws.services.cognitoidentity.model UpdateIdentityPoolRequest setIdentityPoolId.

Prototype


public void setIdentityPoolId(String identityPoolId) 

Source Link

Document

An identity pool ID in the format REGION:GUID.

Usage

From source file:squash.deployment.lambdas.CognitoCustomResourceLambda.java

License:Apache License

/**
 * Implementation for the AWS Lambda function backing the Cognito resource.
 * //from   w  w w.  j  a v  a  2  s.  c  o  m
 * <p>This lambda requires the following environment variables:
 * <ul>
 *    <li>StackName - name of Cloudformation stack - used as the name of the identity pool.</li>
 *    <li>AuthenticatedRole - arn of role specifying permissions for authenticated users.</li>
 *    <li>AuthenticatedRoleName - name of the authenticated role.</li>
 *    <li>UnauthenticatedRole - arn of role specifying permissions for guest users.</li>
 *    <li>UnauthenticatedRoleName - name of the unauthenticated role.</li>
 *    <li>AdminEmail - initial email address for the admin user</li>
 *    <li>LoginUrl - url of login page for admin user</li>
 *    <li>Region - the AWS region in which the Cloudformation stack is created.</li>
 *    <li>Revision - integer incremented to force stack updates to update this resource.</li>
 * </ul>
 *
 * <p>On success, it returns the following outputs to Cloudformation:
 * <ul>
 *    <li>CognitoIdentityPoolId - id of the created Cognito identity pool.</li>
 *    <li>CognitoUserPoolId - id of the created Cognito user pool.</li>
 *    <li>CognitoUserPoolIdentityProviderName - name of the Cognito user pool identity provider to use from javascript.</li>
 *    <li>JavascriptClientAppId - id of user pool client app to use from javascript</li>
 * </ul>
 *
 * <p>Updates will re-set the pool unauthenticated and authenticated roles
 * 
 * @param request request parameters as provided by the CloudFormation service
 * @param context context as provided by the CloudFormation service
 */
@Override
public Object handleRequest(Map<String, Object> request, Context context) {

    LambdaLogger logger = context.getLogger();
    logger.log("Starting Cognito custom resource handleRequest");

    // Handle standard request parameters
    Map<String, String> standardRequestParameters = LambdaInputLogger.logStandardRequestParameters(request,
            logger);
    String requestType = standardRequestParameters.get("RequestType");

    // Handle required environment variables
    logger.log("Logging required environment variables for custom resource request");
    String stackName = System.getenv("StackName");
    String authenticatedRole = System.getenv("AuthenticatedRole");
    String authenticatedRoleName = System.getenv("AuthenticatedRoleName");
    String unauthenticatedRole = System.getenv("UnauthenticatedRole");
    String unauthenticatedRoleName = System.getenv("UnauthenticatedRoleName");
    String adminEmail = System.getenv("AdminEmail");
    String loginUrl = System.getenv("LoginUrl");
    String region = System.getenv("AWS_REGION");
    String revision = System.getenv("Revision");

    // Log out our required environment variables
    logger.log("StackName: " + stackName);
    logger.log("Authenticated role: " + authenticatedRole);
    logger.log("Authenticated role name: " + authenticatedRoleName);
    logger.log("Unauthenticated role: " + unauthenticatedRole);
    logger.log("Unauthenticated role name: " + unauthenticatedRoleName);
    logger.log("Initial email address of admin user: " + adminEmail);
    logger.log("Login url for the admin user: " + loginUrl);
    logger.log("Region: " + region);
    logger.log("Revision: " + revision);

    // API calls below can sometimes give access denied errors during stack
    // creation which I think is bc required new roles have not yet propagated
    // across AWS. We sleep here to allow time for this propagation.
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        logger.log("Sleep to allow new roles to propagate has been interrupted.");
    }

    // Prepare our response to be sent in the finally block
    CloudFormationResponder cloudFormationResponder = new CloudFormationResponder(standardRequestParameters,
            "DummyPhysicalResourceId");
    // Initialise failure response, which will be changed on success
    String responseStatus = "FAILED";

    String identityPoolName = stackName;
    logger.log("Setting Cognito Identity Pool name to: " + identityPoolName);

    String userPoolId = null;
    String identityPoolId = null;
    String providerName = null;
    String javascriptClientAppId = null;
    try {
        cloudFormationResponder.initialise();

        AmazonCognitoIdentity identityClient = getAmazonCognitoIdentityClient(region);
        ListIdentityPoolsRequest listIdentityPoolsRequest = new ListIdentityPoolsRequest();
        // Set some reasonable maximum (must be >=1 and <= 60)
        listIdentityPoolsRequest.setMaxResults(50);
        Optional<IdentityPoolShortDescription> identityPool = identityClient
                .listIdentityPools(listIdentityPoolsRequest).getIdentityPools().stream()
                .filter(pool -> pool.getIdentityPoolName().equals(identityPoolName)).findFirst();

        AWSCognitoIdentityProvider providerClient = getAmazonCognitoIdentityProviderClient(region);
        ListUserPoolsRequest listUserPoolsRequest = new ListUserPoolsRequest();
        listUserPoolsRequest.setMaxResults(50);
        Optional<UserPoolDescriptionType> userPool = providerClient.listUserPools(listUserPoolsRequest)
                .getUserPools().stream().filter(pool -> pool.getName().equals(identityPoolName)).findFirst();

        if (requestType.equals("Create")) {

            // Check the Cognito Identity or User Pools do not exist already
            Boolean identityPoolAlreadyExists = identityPool.isPresent();
            Boolean userPoolAlreadyExists = userPool.isPresent();

            if (identityPoolAlreadyExists.booleanValue() || userPoolAlreadyExists.booleanValue()) {
                if (identityPoolAlreadyExists.booleanValue()) {
                    logger.log("identityPoolAlreadyExists: " + identityPoolAlreadyExists.toString() + " : "
                            + identityPool.get().getIdentityPoolName());
                    logger.log(
                            "Error: Cognito identity pool with name: " + identityPoolName + " already exists");
                } else {
                    logger.log("userPoolAlreadyExists: " + userPoolAlreadyExists.toString() + " : "
                            + userPool.get().getName());
                    logger.log("Error: Cognito user pool with name: " + identityPoolName + " already exists");
                }
                // Change physical id in responder - this is bc CloudFormation will
                // follow up this failed creation with a Delete request to clean up
                // - and we want to ignore that delete call - but not delete calls
                // for our original resource - and we use the PhysicalId to tell these
                // two cases apart.
                cloudFormationResponder.setPhysicalResourceId("DuplicatePhysicalResourceId");

                return null;
            }

            // Create the Cognito user pool with the specified name
            logger.log("Cognito user pool with name: " + identityPoolName + " does not exist, so creating it");
            CreateUserPoolRequest createUserPoolRequest = new CreateUserPoolRequest();
            createUserPoolRequest.setPoolName(identityPoolName);
            // Prevent users signing themselves up
            AdminCreateUserConfigType adminCreateUserConfigType = new AdminCreateUserConfigType();
            adminCreateUserConfigType.setAllowAdminCreateUserOnly(true);
            adminCreateUserConfigType.setUnusedAccountValidityDays(1);
            MessageTemplateType inviteMessageTemplateType = new MessageTemplateType();
            inviteMessageTemplateType.setEmailSubject("Your squash account details");
            inviteMessageTemplateType.setEmailMessage(
                    "Welcome! Your username is: {username} and your temporary password is: {####} (valid for 24 hours). Please login at: "
                            + loginUrl);
            adminCreateUserConfigType.setInviteMessageTemplate(inviteMessageTemplateType);
            createUserPoolRequest.setAdminCreateUserConfig(adminCreateUserConfigType);

            // Allow user to sign in using their email
            List<String> aliasAttributes = new ArrayList<>();
            aliasAttributes.add("email");
            createUserPoolRequest.setAliasAttributes(aliasAttributes);

            // Don't force password to include symbols
            PasswordPolicyType passwordPolicy = new PasswordPolicyType();
            passwordPolicy.setMinimumLength(6);
            passwordPolicy.setRequireSymbols(false);
            UserPoolPolicyType userPoolPolicy = new UserPoolPolicyType();
            userPoolPolicy.setPasswordPolicy(passwordPolicy);
            createUserPoolRequest.setPolicies(userPoolPolicy);

            // Require email to be verified by entering a code.
            // N.B. Think this attribute is called "auto" verified bc, after a user
            // signs up, Cognito sends out an email to the user without us doing
            // anything more i.e. automatically. (And not bc the verification itself
            // is automatic). Note self-signUp is currently disabled.
            List<String> autoVerifiedAttributes = new ArrayList<>();
            autoVerifiedAttributes.add("email");
            createUserPoolRequest.setAutoVerifiedAttributes(autoVerifiedAttributes);
            // Customise the email verification message. This is used to send a code
            // during the forgot-password flow. It would also be sent to users
            // signing themselves up - though self-signup is currently disabled.
            createUserPoolRequest.setEmailVerificationSubject("Your squash verification code");
            createUserPoolRequest
                    .setEmailVerificationMessage("Please use the following code: {####} (valid for 24 hours).");
            CreateUserPoolResult result = providerClient.createUserPool(createUserPoolRequest);
            userPoolId = result.getUserPool().getId();
            logger.log("Created user pool with id: " + userPoolId);

            // Create admin app for use without SRP in this custom resource
            logger.log("Adding admin client app to user pool");
            CreateUserPoolClientRequest createUserPoolClientRequestAdmin = new CreateUserPoolClientRequest();
            createUserPoolClientRequestAdmin.setClientName("CutomResourceAdminClient");
            createUserPoolClientRequestAdmin.setGenerateSecret(false);
            // Do not require SRP use when called from this custom resource
            List<String> explicitAuthFlows = new ArrayList<>();
            explicitAuthFlows.add("ADMIN_NO_SRP_AUTH");
            createUserPoolClientRequestAdmin.setExplicitAuthFlows(explicitAuthFlows);
            createUserPoolClientRequestAdmin.setUserPoolId(userPoolId);
            CreateUserPoolClientResult resultAdmin = providerClient
                    .createUserPoolClient(createUserPoolClientRequestAdmin);
            String adminClientAppId = resultAdmin.getUserPoolClient().getClientId();
            logger.log("Added admin client app to user pool. Client app id: " + adminClientAppId);

            // Create web app for use with SRP from Angular app
            logger.log("Adding javascript client app to user pool");
            CreateUserPoolClientRequest createUserPoolClientRequestJavascript = new CreateUserPoolClientRequest();
            createUserPoolClientRequestJavascript.setClientName("JavascriptClient");
            // Javascript sdk does not use a client secret:
            createUserPoolClientRequestJavascript.setGenerateSecret(false);
            createUserPoolClientRequestJavascript.setUserPoolId(userPoolId);
            CreateUserPoolClientResult resultJavascript = providerClient
                    .createUserPoolClient(createUserPoolClientRequestJavascript);
            javascriptClientAppId = resultJavascript.getUserPoolClient().getClientId();
            logger.log("Added javascript client app to user pool. Client app id: " + javascriptClientAppId);

            // Create the Cognito identity pool with the specified name
            logger.log(
                    "Cognito identity pool with name: " + identityPoolName + " does not exist, so creating it");
            CreateIdentityPoolRequest createIdentityPoolRequest = new CreateIdentityPoolRequest();
            createIdentityPoolRequest.setIdentityPoolName(identityPoolName);
            createIdentityPoolRequest.setAllowUnauthenticatedIdentities(true);
            CreateIdentityPoolResult pool = identityClient.createIdentityPool(createIdentityPoolRequest);
            identityPoolId = pool.getIdentityPoolId();
            // Add roles to the pool
            addRolesToIdentityPool(unauthenticatedRoleName, unauthenticatedRole, authenticatedRoleName,
                    authenticatedRole, identityPoolId, identityClient, logger);
            logger.log("Created identity pool with id: " + identityPoolId);

            // Create our Admin user with this user pool. This user will have to
            // change their password when they first sign in in order to
            // authenticate.
            logger.log("Creating admin user with user pool");
            AdminCreateUserRequest adminCreateUserRequest = new AdminCreateUserRequest();
            adminCreateUserRequest.setDesiredDeliveryMediums(Arrays.asList("EMAIL"));
            adminCreateUserRequest.setUsername("admin");
            adminCreateUserRequest.setUserPoolId(userPoolId);
            // Set some attributes for the admin user
            List<AttributeType> userAttributes = new ArrayList<>();
            AttributeType nameAttribute = new AttributeType();
            nameAttribute.setName("given_name");
            nameAttribute.setValue("Squash bookings service administrator");
            userAttributes.add(nameAttribute);
            AttributeType emailAttribute = new AttributeType();
            emailAttribute.setName("email");
            emailAttribute.setValue(adminEmail);
            userAttributes.add(emailAttribute);
            // Must set email as verified to enable forgot-password flow (the user's
            // use of their initial random password does not set their email to
            // verified for some reason)
            AttributeType emailVerifiedAttribute = new AttributeType();
            emailVerifiedAttribute.setName("email_verified");
            emailVerifiedAttribute.setValue("True");
            userAttributes.add(emailVerifiedAttribute);
            adminCreateUserRequest.setUserAttributes(userAttributes);
            providerClient.adminCreateUser(adminCreateUserRequest);
            logger.log("Created admin user with user pool");

            // Set user pool identity providers in the identity pool. This allows
            // Cognito to dish out temporary credentials for users who are
            // authenticated with our user pool (although currently only the admin
            // user will exist).
            logger.log("Setting user pool identity providers with the identity pool");
            List<CognitoIdentityProvider> cognitoIdentityProviders = new ArrayList<>();
            providerName = "cognito-idp." + region + ".amazonaws.com/" + userPoolId;
            logger.log("Using identity provider name: " + providerName);
            CognitoIdentityProvider cognitoIdentityProviderAdmin = new CognitoIdentityProvider();
            cognitoIdentityProviderAdmin.setClientId(adminClientAppId);
            cognitoIdentityProviderAdmin.setProviderName(providerName);
            cognitoIdentityProviders.add(cognitoIdentityProviderAdmin);
            CognitoIdentityProvider cognitoIdentityProviderJavascript = new CognitoIdentityProvider();
            cognitoIdentityProviderJavascript.setClientId(javascriptClientAppId);
            cognitoIdentityProviderJavascript.setProviderName(providerName);
            cognitoIdentityProviders.add(cognitoIdentityProviderJavascript);
            // Add these providers to the identity pool
            UpdateIdentityPoolRequest updateIdentityPoolRequest = new UpdateIdentityPoolRequest();
            updateIdentityPoolRequest.setCognitoIdentityProviders(cognitoIdentityProviders);
            updateIdentityPoolRequest.setAllowUnauthenticatedIdentities(true);
            updateIdentityPoolRequest.setIdentityPoolId(identityPoolId);
            updateIdentityPoolRequest.setIdentityPoolName(identityPoolName);
            identityClient.updateIdentityPool(updateIdentityPoolRequest);
            logger.log("Set user pool identity providers with the identity pool");

            // Encode identities of both our pools in the physical resource id
            String physicalResourceId = "Identity pool id: " + identityPoolId + ", User pool id: " + userPoolId;
            logger.log("Setting physical resource id to: " + physicalResourceId);
            cloudFormationResponder.setPhysicalResourceId(physicalResourceId);

        } else if (requestType.equals("Update")) {
            // Updates will only ever be to the 2 pool roles - so just replace them
            logger.log("Updating the Cognito identity pool roles");
            String physicalResourceId = standardRequestParameters.get("PhysicalResourceId");
            cloudFormationResponder.setPhysicalResourceId(physicalResourceId);

            Map<String, String> poolIds = getPoolIdsFromPhysicalResourceId(physicalResourceId, logger);
            identityPoolId = poolIds.get("IdentityPoolId");
            userPoolId = poolIds.get("UserPoolId");
            providerName = "cognito-idp." + region + ".amazonaws.com/" + userPoolId;
            addRolesToIdentityPool(unauthenticatedRoleName, unauthenticatedRole, authenticatedRoleName,
                    authenticatedRole, identityPoolId, identityClient, logger);

        } else if (requestType.equals("Delete")) {

            // Early-out if this is a Delete corresponding to a failed attempt to
            // create a duplicate pool, otherwise we will end up wrongly deleting
            // our (valid) original pool instead.
            String physicalResourceId = standardRequestParameters.get("PhysicalResourceId");
            if (physicalResourceId.equals("DuplicatePhysicalResourceId")) {
                logger.log("Ignoring delete request as it's for a non-existent duplicate pool");
            } else {

                Map<String, String> poolIds = getPoolIdsFromPhysicalResourceId(physicalResourceId, logger);
                identityPoolId = poolIds.get("IdentityPoolId");
                userPoolId = poolIds.get("UserPoolId");

                // Check the Cognito Identity Pool does exist
                if (!identityPool.isPresent()) {
                    logger.log(
                            "Error: Cognito identity pool with name: " + identityPoolName + " does not exist");
                    return null;
                }
                // Delete the Cognito identity pool with the specified name
                logger.log("Deleting Cognito identity pool with name: " + identityPoolName);
                DeleteIdentityPoolRequest deleteIdentityPoolRequest = new DeleteIdentityPoolRequest();
                deleteIdentityPoolRequest.setIdentityPoolId(identityPoolId);
                identityClient.deleteIdentityPool(deleteIdentityPoolRequest);
                logger.log("Deleted Cognito identity pool");

                // Check the Cognito User Pool does exist
                if (!userPool.isPresent()) {
                    logger.log("Error: Cognito user pool with name: " + identityPoolName + " does not exist");
                    return null;
                }
                // Delete the Cognito user pool with the specified name
                logger.log("Deleting Cognito user pool with name: " + identityPoolName);
                DeleteUserPoolRequest deleteUserPoolRequest = new DeleteUserPoolRequest();
                deleteUserPoolRequest.setUserPoolId(userPoolId);
                providerClient.deleteUserPool(deleteUserPoolRequest);
                logger.log("Deleted Cognito user pool");

            }
        }

        responseStatus = "SUCCESS";
        return null;
    } catch (AmazonServiceException ase) {
        ExceptionUtils.logAmazonServiceException(ase, logger);
        return null;
    } catch (AmazonClientException ace) {
        ExceptionUtils.logAmazonClientException(ace, logger);
        return null;
    } catch (Exception e) {
        logger.log("Exception caught in Cognito Lambda: " + e.getMessage());
        return null;
    } finally {
        // Send response to CloudFormation
        cloudFormationResponder.addKeyValueOutputsPair("CognitoIdentityPoolId", identityPoolId);
        cloudFormationResponder.addKeyValueOutputsPair("CognitoUserPoolId", userPoolId);
        cloudFormationResponder.addKeyValueOutputsPair("CognitoUserPoolIdentityProviderName", providerName);
        cloudFormationResponder.addKeyValueOutputsPair("JavascriptClientAppId", javascriptClientAppId);
        cloudFormationResponder.sendResponse(responseStatus, logger);
    }
}