feat: add governed postbox delivery and report hardening
This commit is contained in:
@@ -7,11 +7,24 @@ from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterator
|
||||
|
||||
from govoplan_core.core.postbox import (
|
||||
CAPABILITY_POSTBOX_DIRECTORY,
|
||||
CAPABILITY_POSTBOX_DELIVERY,
|
||||
PostboxDeliveryCatalogRef,
|
||||
PostboxDeliveryProvider,
|
||||
PostboxDeliveryRequest,
|
||||
PostboxDeliveryResult,
|
||||
PostboxDirectoryEntryRef,
|
||||
PostboxDirectoryProvider,
|
||||
PostboxTargetRef,
|
||||
)
|
||||
from govoplan_campaign.backend.runtime import capability
|
||||
|
||||
|
||||
FILES_CAPABILITY = "files.campaign_attachments"
|
||||
MAIL_CAPABILITY = "mail.campaign_delivery"
|
||||
POSTBOX_CAPABILITY = CAPABILITY_POSTBOX_DELIVERY
|
||||
POSTBOX_DIRECTORY_CAPABILITY = CAPABILITY_POSTBOX_DIRECTORY
|
||||
|
||||
|
||||
class OptionalModuleUnavailable(RuntimeError):
|
||||
@@ -50,6 +63,10 @@ class MailProfileError(OptionalModuleUnavailable):
|
||||
pass
|
||||
|
||||
|
||||
class PostboxDeliveryUnavailable(OptionalModuleUnavailable):
|
||||
pass
|
||||
|
||||
|
||||
class _PreparedCampaignSnapshot:
|
||||
def __init__(self, directory: Path, path: Path, raw_json: dict[str, Any]) -> None:
|
||||
self._directory = directory
|
||||
@@ -209,9 +226,89 @@ class MailCampaignIntegration:
|
||||
return self._delegate.mock_mailbox()
|
||||
|
||||
|
||||
class PostboxCampaignIntegration:
|
||||
def __init__(
|
||||
self,
|
||||
delivery_delegate: object | None = None,
|
||||
directory_delegate: object | None = None,
|
||||
) -> None:
|
||||
self._delivery_delegate = (
|
||||
delivery_delegate
|
||||
if isinstance(delivery_delegate, PostboxDeliveryProvider)
|
||||
else None
|
||||
)
|
||||
self._directory_delegate = (
|
||||
directory_delegate
|
||||
if isinstance(directory_delegate, PostboxDirectoryProvider)
|
||||
else None
|
||||
)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
return (
|
||||
self._delivery_delegate is not None
|
||||
and self._directory_delegate is not None
|
||||
)
|
||||
|
||||
def delivery_catalog(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
) -> PostboxDeliveryCatalogRef:
|
||||
if self._directory_delegate is None:
|
||||
raise PostboxDeliveryUnavailable(
|
||||
"Postbox targets are unavailable because the Postbox module "
|
||||
"is not active."
|
||||
)
|
||||
return self._directory_delegate.delivery_catalog(
|
||||
session,
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
|
||||
def resolve_postbox(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
target: PostboxTargetRef,
|
||||
materialize: bool = False,
|
||||
) -> PostboxDirectoryEntryRef | None:
|
||||
if self._directory_delegate is None:
|
||||
raise PostboxDeliveryUnavailable(
|
||||
"Postbox targets are unavailable because the Postbox module "
|
||||
"is not active."
|
||||
)
|
||||
return self._directory_delegate.resolve_postbox(
|
||||
session,
|
||||
tenant_id=tenant_id,
|
||||
target=target,
|
||||
materialize=materialize,
|
||||
)
|
||||
|
||||
def deliver(
|
||||
self,
|
||||
session: object,
|
||||
request: PostboxDeliveryRequest,
|
||||
) -> PostboxDeliveryResult:
|
||||
if self._delivery_delegate is None:
|
||||
raise PostboxDeliveryUnavailable(
|
||||
"Postbox delivery is unavailable because the Postbox module "
|
||||
"is not active."
|
||||
)
|
||||
return self._delivery_delegate.deliver(session, request)
|
||||
|
||||
|
||||
def files_integration() -> FilesCampaignIntegration:
|
||||
return FilesCampaignIntegration(capability(FILES_CAPABILITY))
|
||||
|
||||
|
||||
def mail_integration() -> MailCampaignIntegration:
|
||||
return MailCampaignIntegration(capability(MAIL_CAPABILITY))
|
||||
|
||||
|
||||
def postbox_integration() -> PostboxCampaignIntegration:
|
||||
return PostboxCampaignIntegration(
|
||||
capability(POSTBOX_CAPABILITY),
|
||||
capability(POSTBOX_DIRECTORY_CAPABILITY),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user