def notify_users_of_rejected_mail(mail_id, mail_response_date): """If a rejected email is found, this task notifies users of the rejection""" logging.info(f"Notifying users of rejected Mail [{mail_id}, {mail_response_date}]") try: multipart_msg = MIMEMultipart() multipart_msg["From"] = EMAIL_USER multipart_msg["To"] = ",".join(NOTIFY_USERS) multipart_msg["Subject"] = "Mail rejected" body = MIMEText(f"Mail [{mail_id}] received at [{mail_response_date}] was rejected") multipart_msg.attach(body) server = MailServer() smtp_connection = server.connect_to_smtp() send_email(smtp_connection, multipart_msg) server.quit_smtp_connection() except Exception as exc: # noqa error_message = ( f"An unexpected error occurred when notifying users of rejected Mail " f"[{mail_id}, {mail_response_date}] -> {type(exc).__name__}: {exc}" ) # Raise an exception # this will cause the task to be marked as 'Failed' and retried if there are retry attempts left raise Exception(error_message) else: logging.info(f"Successfully notified users of rejected Mail [{mail_id}, {mail_response_date}]")
def _get_email_message_dtos(server: MailServer, number: Optional[int] = 3) -> List[Tuple[EmailMessageDto, Callable]]: pop3_connection = server.connect_to_pop3() emails_iter = get_message_iterator(pop3_connection, server.user) if number: emails = list(islice(emails_iter, number)) else: emails = list(emails_iter) # emails = read_last_three_emails(pop3_connection) server.quit_pop3_connection() return emails
def test_mail_server_not_equal(self): m1 = MailServer(hostname="host", user="******", password="******", pop3_port=1, smtp_port=2) # nosec m2 = MailServer(hostname="host", user="******", password="******", pop3_port=2, smtp_port=1) # nosec self.assertNotEqual(m1, m2)
def get_spire_standin_mailserver() -> MailServer: return MailServer( hostname=settings.SPIRE_STANDIN_EMAIL_HOSTNAME, user=settings.SPIRE_STANDIN_EMAIL_USER, password=settings.SPIRE_STANDIN_EMAIL_PASSWORD, pop3_port=settings.SPIRE_STANDIN_EMAIL_POP3_PORT, smtp_port=settings.SPIRE_STANDIN_EMAIL_SMTP_PORT, )
def get_mock_hmrc_mailserver() -> MailServer: return MailServer( hostname=settings.MOCK_HMRC_EMAIL_HOSTNAME, user=settings.MOCK_HMRC_EMAIL_USER, password=settings.MOCK_HMRC_EMAIL_PASSWORD, pop3_port=settings.MOCK_HMRC_EMAIL_POP3_PORT, smtp_port=settings.MOCK_HMRC_EMAIL_SMTP_PORT, )
def handle(self, *args, **options): email_user = options.pop("mailbox") email_password = options.pop("password") dry_run = options.pop("dry_run") server = MailServer( hostname=settings.EMAIL_HOSTNAME, user=email_user, password=email_password, pop3_port=995, smtp_port=587, ) pop3_connection = server.connect_to_pop3() self.stdout.write(self.style.SUCCESS(f"Connected to {email_user}")) _, mails, _ = pop3_connection.list() self.stdout.write( self.style.SUCCESS(f"Found {len(mails)} in the inbox")) mail_message_ids = [ get_message_id(pop3_connection, m.decode(settings.DEFAULT_ENCODING)) for m in mails ] self.stdout.write( self.style.SUCCESS( f"List of Message-Id and message numbers for existing mails:\n{mail_message_ids}" )) if dry_run.lower() == "false": mailbox_config, _ = models.MailboxConfig.objects.get_or_create( username=email_user) for message_id, message_num in mail_message_ids: if message_id is None: continue read_status, _ = models.MailReadStatus.objects.get_or_create( message_id=message_id, message_num=message_num, mailbox=mailbox_config, ) read_status.status = enums.MailReadStatuses.READ read_status.save() self.stdout.write( self.style.SUCCESS( f"Message-Id {message_id} marked as Read"))
def get_hmrc_to_dit_mailserver() -> MailServer: """ Mailbox that receives reply emails from HMRC These are licenceReply and usageData emails """ return MailServer( hostname=settings.HMRC_TO_DIT_EMAIL_HOSTNAME, user=settings.HMRC_TO_DIT_EMAIL_USER, password=settings.HMRC_TO_DIT_EMAIL_PASSWORD, pop3_port=settings.HMRC_TO_DIT_EMAIL_POP3_PORT, smtp_port=settings.HMRC_TO_DIT_EMAIL_SMTP_PORT, )
def get_spire_to_dit_mailserver() -> MailServer: """ Mailbox that receives emails sent from SPIRE These are licenceData and usageReply emails. They are processed by the service and sent to HMRC. """ return MailServer( hostname=settings.INCOMING_EMAIL_HOSTNAME, user=settings.INCOMING_EMAIL_USER, password=settings.INCOMING_EMAIL_PASSWORD, pop3_port=settings.INCOMING_EMAIL_POP3_PORT, smtp_port=settings.INCOMING_EMAIL_SMTP_PORT, )
def send_licence_data_to_hmrc(): """Sends LITE licence updates to HMRC Return: True if successful """ logging.info("Sending LITE licence updates to HMRC") if not _is_email_slot_free(): logging.info("There is currently an update in progress or an email is in flight") return try: with transaction.atomic(): licences = LicencePayload.objects.filter(is_processed=False).select_for_update(nowait=True) if not licences.exists(): logging.info("There are currently no licences to send") return mail = build_licence_data_mail(licences) mail_dto = build_request_mail_message_dto(mail) licence_references = list(licences.values_list("reference", flat=True)) logging.info( f"Created Mail [{mail.id}] with subject {mail_dto.subject} from licences [{licence_references}]" ) server = MailServer() send(server, mail_dto) update_mail(mail, mail_dto) licences.update(is_processed=True) logging.info(f"Licence references [{licence_references}] marked as processed") except EdifactValidationError as err: # noqa raise err except Exception as exc: # noqa logging.error( f"An unexpected error occurred when sending LITE licence updates to HMRC -> {type(exc).__name__}: {exc}" ) else: logging.info(f"Successfully sent LITE licences updates in Mail [{mail.id}] to HMRC") return True
def send(server: MailServer, email_message_dto: EmailMessageDto): logging.info("Preparing to send email") smtp_connection = server.connect_to_smtp() send_email(smtp_connection, build_email_message(email_message_dto)) server.quit_smtp_connection()