feat(campaign): enforce attachment delivery policies
This commit is contained in:
@@ -245,6 +245,26 @@ def _message_issues_from_attachment_resolution(resolution: EntryAttachmentResolu
|
||||
]
|
||||
|
||||
|
||||
def _append_no_attachment_coverage_issue(issues: list[MessageIssue]) -> None:
|
||||
if any(issue.code == "missing_attachment_coverage" for issue in issues):
|
||||
return
|
||||
issues.append(
|
||||
MessageIssue(
|
||||
severity="error",
|
||||
code="missing_attachment_coverage",
|
||||
message="No attachment file was resolved for this message, and sending without attachments is not allowed.",
|
||||
behavior=Behavior.BLOCK.value,
|
||||
source="attachments",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _send_without_attachments_behavior(config: CampaignConfig) -> Behavior:
|
||||
return config.attachments.send_without_attachments_behavior or (
|
||||
Behavior.CONTINUE if config.attachments.send_without_attachments else Behavior.BLOCK
|
||||
)
|
||||
|
||||
|
||||
def _safe_filename(value: str | None, fallback: str) -> str:
|
||||
raw = value or fallback
|
||||
safe = re.sub(r"[^A-Za-z0-9_.-]+", "_", raw).strip("._")
|
||||
@@ -391,6 +411,7 @@ def _attach_files(
|
||||
for attachment in resolution.attachments:
|
||||
attachment.message_filenames = []
|
||||
attachment.zip_entry_names = []
|
||||
attachment.zip_filename = None
|
||||
|
||||
for attachment in resolution.attachments:
|
||||
if attachment.status != AttachmentMatchStatus.OK or not attachment.matches:
|
||||
@@ -435,6 +456,7 @@ def _attach_files(
|
||||
work_dir / "_zip" / f"entry-{entry_index:04d}" / _safe_filename(archive.id, "archive") / filename,
|
||||
members,
|
||||
password,
|
||||
archive.method.value,
|
||||
)
|
||||
data, maintype, subtype = _attachment_bytes(archive_path)
|
||||
message.add_attachment(data, maintype=maintype, subtype=subtype, filename=filename)
|
||||
@@ -740,6 +762,14 @@ def _build_mime_message(
|
||||
values=rendered.values,
|
||||
work_dir=work_dir,
|
||||
)
|
||||
if attachment_count == 0 and context.resolution.attachments and _send_without_attachments_behavior(config) == Behavior.BLOCK:
|
||||
_append_no_attachment_coverage_issue(context.issues)
|
||||
return _MimeBuildResult(
|
||||
message=None,
|
||||
build_status=BuildStatus.BUILD_FAILED,
|
||||
validation_status=MessageValidationStatus.BLOCKED,
|
||||
attachment_count=0,
|
||||
)
|
||||
return _MimeBuildResult(
|
||||
message=message,
|
||||
build_status=BuildStatus.BUILT,
|
||||
|
||||
Reference in New Issue
Block a user