feat: enforce Mail-owned campaign transport boundary

This commit is contained in:
2026-07-21 17:11:48 +02:00
parent a86a779d5b
commit 88d5012dea
18 changed files with 1548 additions and 260 deletions

View File

@@ -68,9 +68,16 @@ class ImapAppendError(RuntimeError):
configuration or mailbox choice probably needs user/admin attention.
"""
def __init__(self, message: str, *, temporary: bool | None = None):
def __init__(
self,
message: str,
*,
temporary: bool | None = None,
outcome_unknown: bool = False,
):
super().__init__(message)
self.temporary = temporary
self.outcome_unknown = outcome_unknown
@dataclass(frozen=True, slots=True)
@@ -1100,10 +1107,12 @@ def append_message_to_sent(
)
client: imaplib.IMAP4 | None = None
append_started = False
try:
client = _open_imap(imap_config)
target_folder = _effective_sent_folder(config=imap_config, requested_folder=folder, client=client)
internal_date = imaplib.Time2Internaldate(time.time())
append_started = True
typ, data = client.append(_quote_mailbox_name(target_folder), "\\Seen", internal_date, message_bytes)
if typ != "OK":
raise ImapAppendError(f"IMAP APPEND failed for folder {target_folder!r}: {data!r}", temporary=False)
@@ -1119,9 +1128,17 @@ def append_message_to_sent(
except ImapAppendError:
raise
except (OSError, socket.timeout, imaplib.IMAP4.abort) as exc:
raise ImapAppendError(f"IMAP append failed: {exc}", temporary=True) from exc
raise ImapAppendError(
f"IMAP append failed: {exc}",
temporary=not append_started,
outcome_unknown=append_started,
) from exc
except imaplib.IMAP4.error as exc:
raise ImapAppendError(f"IMAP append failed: {exc}", temporary=False) from exc
raise ImapAppendError(
f"IMAP append failed: {exc}",
temporary=False,
outcome_unknown=append_started,
) from exc
finally:
if client is not None:
try: