This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/factors/email/tasks.py

45 lines
1.5 KiB
Python

"""email factor tasks"""
from smtplib import SMTPException
from typing import Any, Dict, List
from celery import group
from django.core.mail import EmailMessage
from structlog import get_logger
from passbook.factors.email.models import EmailFactor
from passbook.root.celery import CELERY_APP
LOGGER = get_logger()
def send_mails(factor: EmailFactor, *messages: List[EmailMessage]):
"""Wrapper to convert EmailMessage to dict and send it from worker"""
tasks = []
for message in messages:
tasks.append(_send_mail_task.s(factor.pk, message.__dict__))
lazy_group = group(*tasks)
promise = lazy_group()
return promise
@CELERY_APP.task(bind=True)
def _send_mail_task(self, email_factor_pk: int, message: Dict[Any, Any]):
"""Send E-Mail according to EmailFactor parameters from background worker.
Automatically retries if message couldn't be sent."""
factor: EmailFactor = EmailFactor.objects.get(pk=email_factor_pk)
backend = factor.backend
backend.open()
# Since django's EmailMessage objects are not JSON serialisable,
# we need to rebuild them from a dict
message_object = EmailMessage()
for key, value in message.items():
setattr(message_object, key, value)
message_object.from_email = factor.from_address
LOGGER.debug("Sending mail", to=message_object.to)
try:
num_sent = factor.backend.send_messages([message_object])
except SMTPException as exc:
raise self.retry(exc=exc)
if num_sent != 1:
raise self.retry()