Fix emailing functionality and update subject and body and file names

This commit is contained in:
Rebecca Hsieh 2024-03-04 16:45:05 -08:00
parent 74f2034487
commit f427076598
No known key found for this signature in database
4 changed files with 55 additions and 44 deletions

View file

@ -4,6 +4,8 @@ import logging
import os import os
import pyzipper import pyzipper
from datetime import datetime
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.conf import settings from django.conf import settings
from registrar.utility import csv_export from registrar.utility import csv_export
@ -13,9 +15,11 @@ from ...utility.email import send_templated_email, EmailSendingError
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
help = ( help = (
"Generates and uploads a current-metadata.csv file to our S3 bucket " "which is based off of all existing Domains." "Generates and uploads a current-metadata.csv file to our S3 bucket "
"which is based off of all existing Domains."
) )
def add_arguments(self, parser): def add_arguments(self, parser):
@ -26,7 +30,7 @@ class Command(BaseCommand):
default=True, default=True,
help="Flag that determines if we do a check for os.path.exists. Used for test cases", help="Flag that determines if we do a check for os.path.exists. Used for test cases",
) )
def handle(self, **options): def handle(self, **options):
"""Grabs the directory then creates current-metadata.csv in that directory""" """Grabs the directory then creates current-metadata.csv in that directory"""
file_name = "current-metadata.csv" file_name = "current-metadata.csv"
@ -58,38 +62,43 @@ class Command(BaseCommand):
# Upload this generated file for our S3 instance # Upload this generated file for our S3 instance
s3_client.upload_file(file_path, file_name) s3_client.upload_file(file_path, file_name)
"""
We want to make sure to upload to s3 for back up
And now we also want to get the file and encrypt it so we can send it in an email
"""
# Encrypt metadata into a zip file # Set zip file name
current_date = datetime.now().strftime("%m%d%Y")
current_filename = f"domain-metadata-{current_date}.zip"
# Pre-set zip file name
encrypted_metadata_output = current_filename
# pre-setting zip file name # Set context for the subject
encrypted_metadata_output = 'encrypted_metadata.zip' current_date_str = datetime.now().strftime("%Y-%m-%d")
# Secret is encrypted into getgov-credentials
# TODO: Update secret in getgov-credentials via cloud.gov and my own .env when ready # TODO: Update secret in getgov-credentials via cloud.gov and my own .env when ready
# Encrypt the metadata # Encrypt the metadata
# TODO: UPDATE SECRET_ENCRYPT_METADATA pw getgov-credentials on stable encrypted_metadata_in_bytes = self._encrypt_metadata(
encrypted_metadata = self._encrypt_metadata(s3_client.get_file(file_name), encrypted_metadata_output, str.encode(settings.SECRET_ENCRYPT_METADATA)) s3_client.get_file(file_name), encrypted_metadata_output, str.encode(settings.SECRET_ENCRYPT_METADATA)
print("encrypted_metadata is:", encrypted_metadata) )
print("the type is: ", type(encrypted_metadata))
# Send the metadata file that is zipped # Send the metadata file that is zipped
# TODO: Make new .txt files
send_templated_email( send_templated_email(
"emails/metadata_body.txt", template_name="emails/metadata_body.txt",
"emails/metadata_subject.txt", subject_template_name="emails/metadata_subject.txt",
to_address="rebecca.hsieh@truss.works", # TODO: Update to settings.DEFAULT_FROM_EMAIL once tested to_address=settings.DEFAULT_FROM_EMAIL,
file=encrypted_metadata, # to_address="rebecca.hsieh@truss.works <rebecca.hsieh@truss.works>", # TODO: Update to settings.DEFAULT_FROM_EMAIL once tested
context={"current_date_str": current_date_str},
file=encrypted_metadata_in_bytes,
) )
def _encrypt_metadata(self, input_file, output_file, password): def _encrypt_metadata(self, input_file, output_file, password):
current_date = datetime.now().strftime("%m%d%Y")
current_filename = f"domain-metadata-{current_date}.txt"
# Using ZIP_DEFLATED bc it's a more common compression method supported by most zip utilities and faster # Using ZIP_DEFLATED bc it's a more common compression method supported by most zip utilities and faster
# We could also use compression=pyzipper.ZIP_LZMA if we are looking for smaller file size # We could also use compression=pyzipper.ZIP_LZMA if we are looking for smaller file size
with pyzipper.AESZipFile(output_file, 'w', compression=pyzipper.ZIP_DEFLATED, encryption=pyzipper.WZ_AES) as f_out: with pyzipper.AESZipFile(
output_file, "w", compression=pyzipper.ZIP_DEFLATED, encryption=pyzipper.WZ_AES
) as f_out:
f_out.setpassword(password) f_out.setpassword(password)
f_out.writestr('encrypted_metadata.txt', input_file) f_out.writestr(current_filename, input_file)
return output_file with open(output_file, "rb") as file_data:
attachment_in_bytes = file_data.read()
return attachment_in_bytes

View file

@ -0,0 +1 @@
An export of all .gov metadata.

View file

@ -0,0 +1,2 @@
Domain metadata - {{current_date_str}}

View file

@ -2,6 +2,7 @@
import boto3 import boto3
import logging import logging
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.template.loader import get_template from django.template.loader import get_template
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
@ -19,7 +20,7 @@ class EmailSendingError(RuntimeError):
pass pass
def send_templated_email(template_name: str, subject_template_name: str, to_address: str, context={}, file: str=None): def send_templated_email(template_name: str, subject_template_name: str, to_address: str, context={}, file: str = None):
"""Send an email built from a template to one email address. """Send an email built from a template to one email address.
template_name and subject_template_name are relative to the same template template_name and subject_template_name are relative to the same template
@ -56,8 +57,7 @@ def send_templated_email(template_name: str, subject_template_name: str, to_addr
}, },
}, },
) )
if file is not None: else:
# TODO: Update sender email when we figure out
ses_client = boto3.client( ses_client = boto3.client(
"ses", "ses",
region_name=settings.AWS_REGION, region_name=settings.AWS_REGION,
@ -65,35 +65,34 @@ def send_templated_email(template_name: str, subject_template_name: str, to_addr
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY, aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
config=settings.BOTO_CONFIG, config=settings.BOTO_CONFIG,
) )
# Define the subject line with the current date
#TODO: Update sender to settings.DEFAULT_FROM_EMAIL response = send_email_with_attachment(
response = send_email_with_attachment(settings.DEFAULT_FROM_EMAIL, to_address, subject, email_body, file, ses_client) settings.DEFAULT_FROM_EMAIL, to_address, subject, email_body, file, ses_client
)
# TODO: Remove this print statement
print("Response from send_email_with_attachment_is:", response) print("Response from send_email_with_attachment_is:", response)
except Exception as exc: except Exception as exc:
raise EmailSendingError("Could not send SES email.") from exc raise EmailSendingError("Could not send SES email.") from exc
def send_email_with_attachment(sender, recipient, subject, body, attachment_file, ses_client): def send_email_with_attachment(sender, recipient, subject, body, attachment_file, ses_client):
# Create a multipart/mixed parent container # Create a multipart/mixed parent container
msg = MIMEMultipart('mixed') msg = MIMEMultipart("mixed")
msg['Subject'] = subject msg["Subject"] = subject
msg['From'] = sender msg["From"] = sender
msg['To'] = recipient msg["To"] = recipient
# Add the text part # Add the text part
text_part = MIMEText(body, 'plain') text_part = MIMEText(body, "plain")
msg.attach(text_part) msg.attach(text_part)
# Add the attachment part # Add the attachment part
# set it into this "type"
attachment_part = MIMEApplication(attachment_file) attachment_part = MIMEApplication(attachment_file)
# Adding attachment header + filename that the attachment will be called # Adding attachment header + filename that the attachment will be called
attachment_part.add_header('Content-Disposition', f'attachment; filename="encrypted_metadata.zip"') current_date = datetime.now().strftime("%m%d%Y")
current_filename = f"domain-metadata-{current_date}.zip"
attachment_part.add_header("Content-Disposition", f'attachment; filename="{current_filename}"')
msg.attach(attachment_part) msg.attach(attachment_part)
response = ses_client.send_raw_email( response = ses_client.send_raw_email(Source=sender, Destinations=[recipient], RawMessage={"Data": msg.as_string()})
Source=sender,
Destinations=[recipient],
RawMessage={"Data": msg.as_string()}
)
return response return response