diff --git a/trench/backends/base.py b/trench/backends/base.py index bea66f03..99c430e7 100644 --- a/trench/backends/base.py +++ b/trench/backends/base.py @@ -16,6 +16,7 @@ def __init__(self, mfa_method: MFAMethod, config: Dict[str, Any]) -> None: self._mfa_method = mfa_method self._config = config self._to = self._get_source_field() + self.request = None def _get_source_field(self) -> Optional[str]: if SOURCE_FIELD in self._config: diff --git a/trench/backends/basic_mail.py b/trench/backends/basic_mail.py index 89e37030..28c6de98 100644 --- a/trench/backends/basic_mail.py +++ b/trench/backends/basic_mail.py @@ -12,23 +12,38 @@ FailedDispatchResponse, SuccessfulDispatchResponse, ) -from trench.settings import EMAIL_HTML_TEMPLATE, EMAIL_PLAIN_TEMPLATE, EMAIL_SUBJECT +from trench.settings import EMAIL_HTML_TEMPLATE, EMAIL_PLAIN_TEMPLATE, EMAIL_SUBJECT_TEMPLATE, EMAIL_SUBJECT class SendMailMessageDispatcher(AbstractMessageDispatcher): _KEY_MESSAGE = "message" _SUCCESS_DETAILS = _("Email message with MFA code has been sent.") + def get_context(self, request): + return {} + + def get_from_email(self, request): + return settings.DEFAULT_FROM_EMAIL + def dispatch_message(self) -> DispatchResponse: - context = {"code": self.create_code()} + request = self.request + context = self.get_context(request) + context.update({"code": self.create_code()}) + email_subject = self._config[EMAIL_SUBJECT] + email_subject_template = self._config[EMAIL_SUBJECT_TEMPLATE] email_plain_template = self._config[EMAIL_PLAIN_TEMPLATE] email_html_template = self._config[EMAIL_HTML_TEMPLATE] + from_email = self.get_from_email(request) + if not email_subject: + email_subject = get_template(email_subject_template).render(context).replace('\n','') + email_plain = get_template(email_plain_template).render(context) + email_html = get_template(email_html_template).render(context) try: send_mail( - subject=self._config.get(EMAIL_SUBJECT), - message=get_template(email_plain_template).render(context), - html_message=get_template(email_html_template).render(context), - from_email=settings.DEFAULT_FROM_EMAIL, + subject=email_subject, + message=email_plain, + html_message=email_html, + from_email=from_email, recipient_list=(self._to,), fail_silently=False, ) diff --git a/trench/settings.py b/trench/settings.py index 2a1bfc63..63ef2686 100644 --- a/trench/settings.py +++ b/trench/settings.py @@ -46,6 +46,7 @@ def __getitem__(self, attr: str) -> Any: VALIDITY_PERIOD = "VALIDITY_PERIOD" VERBOSE_NAME = "VERBOSE_NAME" EMAIL_SUBJECT = "EMAIL_SUBJECT" +EMAIL_SUBJECT_TEMPLATE = "EMAIL_SUBJECT_TEMPLATE" EMAIL_PLAIN_TEMPLATE = "EMAIL_PLAIN_TEMPLATE" EMAIL_HTML_TEMPLATE = "EMAIL_HTML_TEMPLATE" SMSAPI_ACCESS_TOKEN = "SMSAPI_ACCESS_TOKEN" @@ -88,6 +89,7 @@ def __getitem__(self, attr: str) -> Any: HANDLER: "trench.backends.basic_mail.SendMailMessageDispatcher", SOURCE_FIELD: "email", EMAIL_SUBJECT: _("Your verification code"), + EMAIL_SUBJECT_TEMPLATE: "trench/backends/email/code_subject.txt", EMAIL_PLAIN_TEMPLATE: "trench/backends/email/code.txt", EMAIL_HTML_TEMPLATE: "trench/backends/email/code.html", }, diff --git a/trench/templates/trench/backends/email/code_subject.html b/trench/templates/trench/backends/email/code_subject.html new file mode 100644 index 00000000..d489277d --- /dev/null +++ b/trench/templates/trench/backends/email/code_subject.html @@ -0,0 +1,4 @@ +{% load i18n %} +{% blocktrans %} +Your verification code +{% endblocktrans %} diff --git a/trench/views/base.py b/trench/views/base.py index c013cc5a..580ba192 100644 --- a/trench/views/base.py +++ b/trench/views/base.py @@ -65,7 +65,10 @@ def post(self, request: Request) -> Response: try: mfa_model = get_mfa_model() mfa_method = mfa_model.objects.get_primary_active(user_id=user.id) - get_mfa_handler(mfa_method=mfa_method).dispatch_message() + mfa_methods = mfa_model.objects.list_active(user_id=user.id) + mfa_backend = get_mfa_handler(mfa_method=mfa_method) + mfa_backend.request = request + mfa_backend.dispatch_message() return Response( data={ "ephemeral_token": user_token_generator.make_token(user), @@ -114,7 +117,9 @@ def post(request: Request, method: str) -> Response: ) except MFAValidationError as cause: return ErrorResponse(error=cause) - return get_mfa_handler(mfa_method=mfa).dispatch_message() + mfa_backend = get_mfa_handler(mfa_method=mfa) + mfa_backend.request = request + return mfa_backend.dispatch_message() class MFAMethodConfirmActivationView(APIView): @@ -221,7 +226,9 @@ def post(request: Request) -> Response: user_id=request.user.id ) mfa = mfa_model.objects.get_by_name(user_id=request.user.id, name=method) - return get_mfa_handler(mfa_method=mfa).dispatch_message() + mfa_backend = get_mfa_handler(mfa_method=mfa) + mfa_backend.request = request + return mfa_backend.dispatch_message() except MFAValidationError as cause: return ErrorResponse(error=cause)