awslabs / service-workbench-on-aws

A platform that provides researchers with one-click access to collaborative workspace environments operating across teams, universities, and datasets while enabling university IT stakeholders to manage, monitor, and control spending, apply security best practices, and comply with corporate governance.
Apache License 2.0
177 stars 119 forks source link

[Bug] Cognito User Pool Domain is sometimes created with an illegal character. #1222

Open rhyslewis-aws opened 1 year ago

rhyslewis-aws commented 1 year ago

Describe the bug The postDeployment lambda uses a function to generate Cognito domains that can sometimes include "_". If this happens the install fails.

To Reproduce Steps to reproduce the behavior:

  1. Carry out the install as described here: https://docs.aws.amazon.com/solutions/latest/service-workbench-on-aws/deploy-using-aws-cloud9.html#step-6-run-the-install-script
  2. The install fails with the error message, "InvalidParameterException: The domain name contains an invalid character. Domain names can only contain lower-case letters, numbers, and hyphens. Please enter a different name that follows this format: ^a-z0-9?$"

Expected behavior A successful install

Screenshots N/A

Versions (please complete the following information):

Additional context

The postDeployment lambda calls generateIdSync to generate a new domain for cognito here: https://github.com/awslabs/service-workbench-on-aws/blob/28f577efe5b1db6f174b1c7175de695ada497413/addons/addon-base-rest-api/packages/services/lib/authentication-providers/built-in-providers/cogito-user-pool/provisioner-service.js#L547

This in turn calls the nanoid library (https://github.com/ai/nanoid#readme) here: https://github.com/awslabs/service-workbench-on-aws/blob/28f577efe5b1db6f174b1c7175de695ada497413/addons/addon-base/packages/services/lib/helpers/utils.js#L237

Nanoid uses an alphabet that includes the character (A-Za-z0-9-), but Cognito does not allow this character. Since generateId is used in multiple places throughout Service Workbench it is probably safer to resolve this issue in the provisioner-service.js file rather than the utils.js file.

provisioner-service.js has retry functionality for other InvalidParameterException cases: https://github.com/awslabs/service-workbench-on-aws/blob/28f577efe5b1db6f174b1c7175de695ada497413/addons/addon-base-rest-api/packages/services/lib/authentication-providers/built-in-providers/cogito-user-pool/provisioner-service.js#L522 but does not include one for the invalid character message.

It would probably be better to implement a replace action in line with the substr and toLowerCase actions (eg. https://github.com/awslabs/service-workbench-on-aws/blob/28f577efe5b1db6f174b1c7175de695ada497413/addons/addon-base-rest-api/packages/services/lib/authentication-providers/built-in-providers/cogito-user-pool/provisioner-service.js#L549 ) so that the domain is always legal.

kpark277 commented 1 year ago

Hi @rhyslewis-aws, can you provide your config file that you used for the deployment?

rhyslewis-aws commented 1 year ago

I don't have the config file from that deployment any more, but this is the script that I used to generate it, where treprod.yml is a copy of .defaults.yml


#!/bin/sh

read -p "Administrator's first name: " FIRSTNAME
read -p "Administrator's surname: " SURNAME
read -p "Administrator's email: " EMAIL
read -p "SSO Metadata URL" SSO_METADATA_URL

TRUE_VALUES="enableEgressStore isAppStreamEnabled restrictAdminWorkspaceConnection disableStudyUploadByResearcher disableAdminBYOBSelfAssignment"

cp treprod.yml treprod.yml.bak
sed -i 's/\(awsRegion:\) .*/\1 ap-southeast-2/' treprod.yml
sed -i 's/\# \(solutionName:\) .*/\1 pj1/' treprod.yml
sed -i 's/\(rootUserName:\) .*/\1 rootuser/' treprod.yml
sed -i "s/\(rootUserFirstName:\) .*/\1 $FIRSTNAME/" treprod.yml
sed -i "s/\(rootUserLastName:\) .*/\1 $SURNAME/" treprod.yml
sed -i "s/\(rootUserEmail:\) .*/\1 $EMAIL/" treprod.yml
for val in $TRUE_VALUES; do
        sed -i "s/\($val:\) .*/\1 true/" treprod.yml
done

echo "fedIdpIds: '[\"AWSIIC\"]'" >> treprod.yml
echo "fedIdpNames: '[\"AWSIIC\"]'" >> treprod.yml
echo "fedIdpDisplayNames: '[\"Login using AWS IAM Identity Center\"]'" >> treprod.yml
echo "fedIdpMetadatas: '[\"$SSO_METADATA_URL\"]'" >> treprod.yml```