Skip to content

Instantly share code, notes, and snippets.

@efimk-lu
Last active November 25, 2022 14:11
Show Gist options
  • Save efimk-lu/b48fa118bd29a35fc1767fe749fa3372 to your computer and use it in GitHub Desktop.
Save efimk-lu/b48fa118bd29a35fc1767fe749fa3372 to your computer and use it in GitHub Desktop.
Using Cognito in integration tests
const CognitoIdentityServiceProvider = require("amazon-cognito-identity-js");
// Required in order to use the cognito js library to work.
global.fetch = require("node-fetch");
/**
* Authenticate a cognito user and return its authentication token. Use the auth token in the authorization header
* @param callback Callback function with error as first param and the actual user token in the second param.
*/
function authenticateUser(callback) {
console.info("Authenticating user");
const authenticationData = {
Username: userName,
Password: password
};
const authenticationDetails = new CognitoIdentityServiceProvider.AuthenticationDetails(
authenticationData
);
const poolData = {
UserPoolId: userPoolId, // Your user pool id here
ClientId: clientId // Your client id here
};
const userPool = new CognitoIdentityServiceProvider.CognitoUserPool(poolData);
const userData = {
Username: userName,
Pool: userPool
};
const cognitoUser = new CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function(result) {
const token = result.getIdToken().getJwtToken();
console.info(`User token: ${token}`);
callback(null, token);
},
onFailure: function(err) {
callback(err);
}
});
}
import boto3
from warrant.aws_srp import AWSSRP
from warrant import dict_to_cognito
import click
import random
import string
def admin_create_user(
client,
user_pool_id: str,
username: str,
temporary_password="",
attr_map=None,
**kwargs,
):
"""
Create a user using admin super privileges.
:param username: User Pool username
:param temporary_password: The temporary password to give the user.
Leave blank to make Cognito generate a temporary password for the user.
:param attr_map: Attribute map to Cognito's attributes
:param kwargs: Additional User Pool attributes
:return response: Response from Cognito
"""
response = client.admin_create_user(
UserPoolId=user_pool_id,
Username=username,
UserAttributes=dict_to_cognito(kwargs, attr_map),
TemporaryPassword=temporary_password,
MessageAction="SUPPRESS",
)
response.pop("ResponseMetadata")
return response
@click.command()
@click.argument("cognito_pool_id")
@click.argument("cognito_client_id")
@click.argument("email")
@click.option("--profile", default="default", help="AWS credentials profile")
@click.option("--verbose", default=False, help="Verbose printing", is_flag=True)
def create_user(
cognito_pool_id: str,
cognito_client_id: str,
email: str,
profile: str,
verbose: bool,
):
click.echo("Creating a new user")
click.echo(f"Profile: {profile}")
click.echo(f"Pool ID: {cognito_pool_id}")
click.echo(f"Client ID: {cognito_client_id}")
click.echo(f"Email: {email}")
punctuation = "!#$%&()*+/<=>?@[]^{}~"
tmp_pass = "".join(
random.choices(string.digits + string.ascii_letters + punctuation, k=12)
)
password = f"A!1a{tmp_pass}"
click.echo(f"Password: {password}")
boto3.setup_default_session(profile_name=profile)
client = boto3.client("cognito-idp")
user_details = admin_create_user(
client,
cognito_pool_id,
email,
"Q!w2e3r4",
**{
"email_verified": "True",
"email": email,
},
)
if verbose:
click.echo(f"Creation response:{user_details}")
username = user_details["User"]["Username"]
click.echo("User created successfully")
aws = AWSSRP(
username=username,
password="Q!w2e3r4",
pool_id=cognito_pool_id,
client_id=cognito_client_id,
client=client,
)
token = aws.set_new_password_challenge(password)
if verbose:
click.echo(f"Tokens: {token}")
click.echo(f"Access Token: {token['AuthenticationResult']['AccessToken']}")
if __name__ == "__main__":
try:
create_user()
except Exception as err:
click.echo("Failed!", err=True)
click.echo(str(err), err=True)
exit(1)
#!/usr/bin/env bash
set -eo pipefail
bold=$(tput bold 2>/dev/null || true)
normal=$(tput sgr0 2>/dev/null || true)
echo ".____ .__ .__ ";
echo "| | __ __ _____ |__| ____ ____ |__| ____ ";
echo "| | | | \/ \| |/ ___\ / _ \ | |/ _ \ ";
echo "| |___| | / Y Y \ / /_/ > <_> ) | ( <_> )";
echo "|_______ \____/|__|_| /__\___ / \____/ /\ |__|\____/ ";
echo " \/ \/ /_____/ \/ ";
echo
echo "Prepare your env file"
function usage() {
cat <<EOM
Usage:
If no parameters are used then local deployment is being chosen.
$(basename $0) [options]
[--env] - Optional. Environment to use. Default is USER environment.
[--region] - Optional. Deploy on this aws region. Default is us-west-2.
[--username] - Optional. User name to use for cognito registration. Default is test_email@nomail.com
EOM
exit 0
}
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
--help)
usage
;;
--env)
opt_env="$2"
shift # past argument
shift # past value
;;
--region)
opt_region="$2"
shift # past argument
shift # past value
;;
--username)
opt_username="$2"
shift # past argument
shift # past value
;;
*)
echo "Unknown argument ${1}. Aborting."
exit 1
esac
done
env=${opt_env:-${USER}}
region=${opt_region:-us-west-2}
username=${opt_username:-test_email_$(date +%s|openssl md5 | tail -c 5)@nomail.com}
echo "Env: ${env}"
echo "Region: ${region}"
echo "Username: ${username}"
user_pool_id=$(aws cloudformation describe-stacks --region ${region} --stack-name ${env}-common-resources|jq -r '.Stacks[0]["Outputs"][]| select(.OutputKey | contains("CognitoUserPoolId"))|.OutputValue')
client_id=$(aws cloudformation describe-stacks --region ${region} --stack-name ${env}-common-resources|jq -r '.Stacks[0]["Outputs"][]| select(.OutputKey | contains("UserPoolClient"))|.OutputValue')
echo "User pool id: ${user_pool_id}"
echo "Client id: ${client_id}"
echo "${bold}Creating a new user${normal}"
# Do not fail if folder does not exist
rm -rf venv || true
virtualenv venv -p python3.7
source ./venv/bin/activate
pip install -r requirements.txt
user_password=$(python create_user.py ${user_pool_id} ${client_id} ${username} |grep Password|awk '{print $2}')
echo "User password: ${user_password}"
echo "${bold}Writing .env file${normal}"
cat > .env <<EOM
USER_NAME=${username}
PASSWORD=${user_password}
EOM
cat .env
echo "Done"
boto3==1.9.86
botocore==1.12.86
certifi==2018.11.29
chardet==3.0.4
Click==7.0
docutils==0.14
ecdsa==0.13
envs==1.3
future==0.17.1
idna==2.8
jmespath==0.9.3
pycryptodome==3.3.1
python-dateutil==2.7.5
python-jose-cryptodome==1.3.2
requests==2.21.0
s3transfer==0.1.13
six==1.12.0
urllib3==1.24.1
warrant==0.6.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment