Skip to content

Commit

Permalink
re-adding files for demo
Browse files Browse the repository at this point in the history
  • Loading branch information
nataliejschultz committed Jan 25, 2024
1 parent 8411fc3 commit 63f970c
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 0 deletions.
175 changes: 175 additions & 0 deletions email_automation/email-config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import boto3
from botocore.exceptions import ClientError
import json
import os
import logging
import sys
import argparse
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# If you don't have boto3 installed, make sure to `pip install boto3` before running this script.

if __name__ == "__main__":
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-l', '--local',
help = 'Running locally. Provide full path to config file + install boto3 prior to running.' )
group.add_argument('-g', '--github',
help = 'Must be run on GitHub. To run locally, use -l argument.')
args = parser.parse_args()
filepath_raw = sys.argv[2]
filename_raw = filepath_raw.split("/")[-1]
filename = filename_raw.split('.')[0]
pool_name = "nrelopenpath-prod-" + filename
current_path = os.path.dirname(__file__)
maindir = current_path.rsplit("/",1)[0]
config_path = filepath_raw if args.local else maindir + f'/configs/{filename_raw}'

if args.local:
#Set up AWS credentials as environment variables + set variables
ACCESS = os.environ.get("AWS_ACCESS_KEY_ID")
SECRET = os.environ.get("AWS_SECRET_ACCESS_KEY")
TOKEN = os.environ.get("AWS_SESSION_TOKEN")
AWS_REGION = "us-west-2"

#Set up clients
cognito_client = boto3.client(
'cognito-idp',
aws_access_key_id = ACCESS,
aws_secret_access_key= SECRET,
aws_session_token=TOKEN,
region_name=AWS_REGION
)

sts_client = boto3.client(
'sts',
aws_access_key_id = ACCESS,
aws_secret_access_key= SECRET,
aws_session_token=TOKEN,
region_name=AWS_REGION
)
if args.github:
AWS_REGION = os.environ.get("AWS_REGION")
cognito_client = boto3.client('cognito-idp', region_name=AWS_REGION)
sts_client = ''
# Functions
def get_userpool_name(pool_name, cognito_client):
response = cognito_client.list_user_pools(MaxResults=60)
is_userpool_exist = False
user_pools = [user_pool["Name"] for user_pool in response["UserPools"]]
is_userpool_exist = True if pool_name in user_pools else False
user_pool_index = user_pools.index(pool_name) if is_userpool_exist else None
pool_id = response["UserPools"][user_pool_index]["Id"]
return is_userpool_exist, pool_id

def user_already_exists(pool_id, email, cognito_client):

try:
response = cognito_client.list_users(UserPoolId=pool_id)
users = response["Users"]
result = False
if str(users).find(email) > 1:
result = True
return result
except ClientError as err:
logger.error(
"Couldn't list users for %s. Here's why: %s: %s",
pool_id,
err.response["Error"]["Code"],
err.response["Error"]["Message"],
)
raise

def get_verified_arn(sts_client):
if args.local:
account_num = sts_client.get_caller_identity()["Account"]
identity_arn = "arn:aws:ses:" + AWS_REGION + ":" + account_num + ":identity/[email protected]"
if args.github:
AWS_ACCT_ID = os.environ.get("AWS_ACCT_ID")
identity_arn = "arn:aws:ses:" + AWS_REGION + ":" + AWS_ACCT_ID + ":identity/[email protected]"
return identity_arn

def email_extract():
with open (config_path) as config_file:
data = json.load(config_file)
admindash_prefs = data['admin_dashboard']
emails = [i.strip() for i in admindash_prefs['admin_access'].split(",")]
columns_exclude = admindash_prefs['data_trips_columns_exclude']
map_trip_lines_enabled = admindash_prefs['map_trip_lines']
return emails, map_trip_lines_enabled, columns_exclude

def create_account(pool_id, email, cognito_client):
response = cognito_client.admin_create_user(
UserPoolId = pool_id,
Username=email,
UserAttributes=[
{
'Name': 'email',
'Value': email,
},
],
ForceAliasCreation=True,
DesiredDeliveryMediums=[
'EMAIL',
],
)
return response

def format_email(filename, map_trip_lines_enabled, columns_exclude):
with open(maindir + '/email_automation/welcome-template.txt', 'r') as f:
html = f.read()
html = html.replace('<filename>', filename)
if map_trip_lines_enabled:
html = html.replace ('<map_trip_lines>', 'Additionally, you can view individual user-origin destination points using the "Map Lines" option from the map page.')
else:
html = html.replace ('<map_trip_lines>', '')
if 'data.start_loc.coordinates' in columns_exclude or 'data.end_loc.coordinates' in columns_exclude:
html = html.replace ('<columns_exclude>', 'Per your requested configuration, your trip table excludes trip start/end coordinates for greater anonymity. Let us know if you need them to be enabled for improved analysis.')
elif columns_exclude == '':
html = html.replace ('<columns_exclude>', 'Since you indicated that you want to map the data to infrastructure updates, your configuration includes trip start/end in the trip table. Let us know if you would like to exclude those for greater anonymity.')
return html


def update_user_pool(pool_id, pool_name, html, identity_arn, cognito_client):
response = cognito_client.update_user_pool(
UserPoolId= pool_id,
AutoVerifiedAttributes=['email'],
EmailConfiguration={
'SourceArn': identity_arn,
'EmailSendingAccount': 'DEVELOPER',
'From': '[email protected]'
},
AdminCreateUserConfig={
'AllowAdminCreateUserOnly': True,
'InviteMessageTemplate': {
'EmailMessage': str(html),
'EmailSubject': f'Welcome to {pool_name} user pool!'
}
},
)
######################################################################
is_userpool_exist, pool_id = get_userpool_name(pool_name, cognito_client)

# Start by checking for the User Pool. If the User Pool does not yet exist, wait until it is set up to add users.
if is_userpool_exist:
#extract email addresses from config file
emails, map_trip_lines_enabled, columns_exclude = email_extract()
#Loop over each email address. Check if they're in the user pool.
for email in emails:
if not user_already_exists(pool_id, email, cognito_client):
#If user not in pool, format the email template for their welcome email, update the user pool, and create an account for them.
print(email + " not in user pool! Creating account...")
html = format_email(filename, map_trip_lines_enabled, columns_exclude)
identity_arn = get_verified_arn(sts_client)
update_user_pool(pool_id, pool_name, html, identity_arn, cognito_client)
response = create_account(pool_id, email, cognito_client)
if response['ResponseMetadata']['HTTPStatusCode'] == 200:
print("Account created! Sending welcome email.")
else:
print("Account creation unsuccessful.")
print(response['ResponseMetadata']['HTTPStatusCode'])
else:
print(email + " already in user pool!")
else:
print(pool_name + " does not exist! Try again later.")

32 changes: 32 additions & 0 deletions email_automation/welcome-template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<html>
<head></head>
<body>
<h1>Welcome to OpenPATH!</h1>
<p> Thank you for joining the OpenPATH project.<br>
<br>
<strong>Your admin dashboard can be found at:</strong> <br>
<br>
<a href='https://<filename>-openpath.nrel.gov/admin/'>
https://<filename>-openpath.nrel.gov/admin/</a>.<br>
<br>
An account has been created for you with AWS Cognito. Please log in and change your
temporary password:<br>
<br>
Username: {username}
Temporary Password: {####}
<br>
<br>
The login to the admin dashboard uses 2-factor authentication. You will have to install an authenticator app (e.g. Microsoft Authenticator, Google Authenticator) to receive One Time Passcodes (OTP) every time you want to log in. This is a requirement from NREL cyber to ensure that the data access to individual user information is secure.<br>
<br>
For the specified date range, you can download trip, user and trajectory tables as csv and view aggregate origin-destination points in the maps. <map_trip_lines> <br>
<br>
<columns_exclude>

Please let us know if you have any problems with signing in.<br>
<br>
Thank you,<br>
<br>
NREL's OpenPATH Team
</p>
</body>
</html>

0 comments on commit 63f970c

Please sign in to comment.