Source code for ferrosoft.apps.ferrobase.session.password_reset

"""Password reset email dispatch using templated messages."""

from django.core import mail
from django.http import HttpRequest
from django.template import Engine, Context
from django.urls import reverse
from django.utils.translation import gettext as _

from ferrosoft.apps.date_time import now_utc
from ferrosoft.apps.ferrobase.models import PasswordResetRequest


[docs] class UserMissingEmail(Exception): """Raised when a password reset is attempted for a user without an email address."""
[docs] def send_password_reset_email( reset_req: PasswordResetRequest, http_req: HttpRequest, sender_address: str = None, ): """Render and send the password reset email for a pending reset request. The mail body is rendered from the ``ferrobase/session/reset-password-mail.html`` template and contains a tokenised link back to the ``set_new_password`` view. Args: reset_req: The persisted reset-request record carrying the user and access key. http_req: The current HTTP request, used solely to build an absolute URI for the reset link. sender_address: Optional sender address. Falls back to the Django ``DEFAULT_FROM_EMAIL`` setting when omitted. Raises: UserMissingEmail: If the target user has no email address recorded. Exception: Any underlying mail-backend error is propagated; the call uses ``fail_silently=False``. """ from django.conf import settings with mail.get_connection() as conn: if not reset_req.user.email: raise UserMissingEmail( "user is missing email: ID " + str(reset_req.user.pk) ) body_template = Engine.get_default().get_template( "ferrobase/session/reset-password-mail.html" ) reset_url = reverse("ferrobase:set_new_password", args=[reset_req.access_key]) body = body_template.render( Context( { "name": reset_req.user.get_short_name(), "request_time": now_utc().isoformat(), "reset_url": http_req.build_absolute_uri(reset_url), } ) ) msg = mail.EmailMessage( _("Reset password for Ferrosoft Platform"), body, sender_address or getattr(settings, "DEFAULT_FROM_EMAIL"), [reset_req.user.email], connection=conn, ) msg.send(fail_silently=False)