Extend Postbox access classification contract
This commit is contained in:
@@ -5,6 +5,8 @@ from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Literal, Protocol, runtime_checkable
|
||||
|
||||
from govoplan_core.core.events import EventClassification
|
||||
|
||||
|
||||
POSTBOX_MODULE_ID = "postbox"
|
||||
CAPABILITY_POSTBOX_DIRECTORY = "postbox.directory"
|
||||
@@ -14,9 +16,62 @@ CAPABILITY_POSTBOX_DELIVERY = "postbox.delivery"
|
||||
CAPABILITY_POSTBOX_EVIDENCE = "postbox.evidence"
|
||||
CAPABILITY_POSTBOX_ROUTING = "postbox.routing"
|
||||
|
||||
PostboxAction = Literal["discover", "read", "send", "acknowledge", "administer"]
|
||||
PostboxAction = Literal[
|
||||
"discover",
|
||||
"read",
|
||||
"send",
|
||||
"reply",
|
||||
"acknowledge",
|
||||
"administer",
|
||||
]
|
||||
PostboxMessageListState = Literal["all", "unread", "read", "acknowledged"]
|
||||
PostboxMessageAvailability = Literal["available", "withdrawn", "expired"]
|
||||
PostboxBindingStatus = Literal[
|
||||
"active",
|
||||
"missing",
|
||||
"not_effective",
|
||||
"unit_missing",
|
||||
"unit_inactive",
|
||||
"unit_tenant_mismatch",
|
||||
"function_missing",
|
||||
"function_inactive",
|
||||
"function_tenant_mismatch",
|
||||
"function_reassigned",
|
||||
"directory_unavailable",
|
||||
]
|
||||
|
||||
POSTBOX_CLASSIFICATIONS: tuple[EventClassification, ...] = (
|
||||
"public",
|
||||
"internal",
|
||||
"confidential",
|
||||
"restricted",
|
||||
)
|
||||
_POSTBOX_CLASSIFICATION_RANK = {
|
||||
value: rank for rank, value in enumerate(POSTBOX_CLASSIFICATIONS)
|
||||
}
|
||||
|
||||
|
||||
def normalize_postbox_classification(
|
||||
value: str,
|
||||
) -> EventClassification | None:
|
||||
candidate = value.strip().casefold()
|
||||
if candidate not in _POSTBOX_CLASSIFICATION_RANK:
|
||||
return None
|
||||
return candidate # type: ignore[return-value]
|
||||
|
||||
|
||||
def postbox_classification_allows(
|
||||
ceiling: str,
|
||||
content: str,
|
||||
) -> bool:
|
||||
normalized_ceiling = normalize_postbox_classification(ceiling)
|
||||
normalized_content = normalize_postbox_classification(content)
|
||||
if normalized_ceiling is None or normalized_content is None:
|
||||
return False
|
||||
return (
|
||||
_POSTBOX_CLASSIFICATION_RANK[normalized_content]
|
||||
<= _POSTBOX_CLASSIFICATION_RANK[normalized_ceiling]
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
@@ -26,6 +81,9 @@ class PostboxActorRef:
|
||||
selected_assignment_id: str | None = None
|
||||
acting_for_account_id: str | None = None
|
||||
authorized_actions: frozenset[PostboxAction] = frozenset()
|
||||
authorized_classifications: frozenset[EventClassification] = frozenset(
|
||||
{"public", "internal"}
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
@@ -91,6 +149,9 @@ class PostboxAccessDecisionRef:
|
||||
selected_assignment_id: str | None = None
|
||||
holder_count: int = 0
|
||||
vacant: bool = True
|
||||
classification: str = "internal"
|
||||
classification_allowed: bool = True
|
||||
binding_status: PostboxBindingStatus = "active"
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
|
||||
Reference in New Issue
Block a user