mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-22 08:48:38 +00:00
Pins the auth handshake delivered with the tracer green (no red phase); discriminating: an unauthenticated/cleartext send would be rejected by SES. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
104 lines
3.1 KiB
Python
104 lines
3.1 KiB
Python
"""The SES-over-SMTP email sender (ADR-0059) — delivers a plain-text message to
|
|
the requesting user via an injected SMTP transport."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from email.message import EmailMessage
|
|
from types import TracebackType
|
|
from typing import Any, Optional, Type
|
|
|
|
from infrastructure.email.ses_smtp_email_sender import SesSmtpEmailSender
|
|
|
|
|
|
class _FakeSmtp:
|
|
"""Records what the sender hands the transport, standing in for a live SES
|
|
SMTP connection."""
|
|
|
|
def __init__(self, host: str, port: int) -> None:
|
|
self.host = host
|
|
self.port = port
|
|
self.messages: list[EmailMessage] = []
|
|
self.started_tls = False
|
|
self.login_args: Optional[tuple[str, str]] = None
|
|
|
|
def __enter__(self) -> "_FakeSmtp":
|
|
return self
|
|
|
|
def __exit__(
|
|
self,
|
|
exc_type: Optional[Type[BaseException]],
|
|
exc: Optional[BaseException],
|
|
tb: Optional[TracebackType],
|
|
) -> Optional[bool]:
|
|
return None
|
|
|
|
def starttls(self) -> Any:
|
|
self.started_tls = True
|
|
|
|
def login(self, user: str, password: str) -> Any:
|
|
self.login_args = (user, password)
|
|
|
|
def send_message(self, message: EmailMessage) -> Any:
|
|
self.messages.append(message)
|
|
|
|
|
|
def test_send_delivers_a_plaintext_message_with_the_right_envelope() -> None:
|
|
# Arrange
|
|
created: list[_FakeSmtp] = []
|
|
|
|
def factory(host: str, port: int) -> _FakeSmtp:
|
|
smtp = _FakeSmtp(host, port)
|
|
created.append(smtp)
|
|
return smtp
|
|
|
|
sender = SesSmtpEmailSender(
|
|
host="email-smtp.eu-west-2.amazonaws.com",
|
|
port=587,
|
|
username="AKIA_SMTP_USER",
|
|
password="smtp-password",
|
|
from_address="noreply@domna.homes",
|
|
smtp_factory=factory,
|
|
)
|
|
|
|
# Act
|
|
sender.send(
|
|
to="user@example.com",
|
|
subject="Your document download is ready",
|
|
body="Download it here: https://signed-url",
|
|
)
|
|
|
|
# Assert — one message, correctly addressed, body carried through.
|
|
assert len(created) == 1
|
|
assert len(created[0].messages) == 1
|
|
message = created[0].messages[0]
|
|
assert message["To"] == "user@example.com"
|
|
assert message["From"] == "noreply@domna.homes"
|
|
assert message["Subject"] == "Your document download is ready"
|
|
assert "https://signed-url" in message.get_content()
|
|
|
|
|
|
def test_send_starts_tls_and_authenticates_before_sending() -> None:
|
|
# Arrange — SES SMTP rejects unauthenticated, cleartext senders, so the
|
|
# transport must STARTTLS and log in with the SMTP credentials.
|
|
created: list[_FakeSmtp] = []
|
|
|
|
def factory(host: str, port: int) -> _FakeSmtp:
|
|
smtp = _FakeSmtp(host, port)
|
|
created.append(smtp)
|
|
return smtp
|
|
|
|
sender = SesSmtpEmailSender(
|
|
host="email-smtp.eu-west-2.amazonaws.com",
|
|
port=587,
|
|
username="AKIA_SMTP_USER",
|
|
password="smtp-password",
|
|
from_address="noreply@domna.homes",
|
|
smtp_factory=factory,
|
|
)
|
|
|
|
# Act
|
|
sender.send(to="user@example.com", subject="s", body="b")
|
|
|
|
# Assert
|
|
assert created[0].started_tls is True
|
|
assert created[0].login_args == ("AKIA_SMTP_USER", "smtp-password")
|