feat: govern campaign archive encryption
This commit is contained in:
@@ -9,8 +9,10 @@ from sqlalchemy.orm import Session
|
||||
from govoplan_policy.backend.db.models import PolicyOverride
|
||||
|
||||
|
||||
POLICY_SCOPE_TYPES = frozenset({"system", "tenant", "group", "user"})
|
||||
POLICY_FAMILIES = frozenset({"definition", "distribution_channels", "view"})
|
||||
POLICY_SCOPE_TYPES = frozenset({"system", "tenant", "group", "user", "campaign"})
|
||||
POLICY_FAMILIES = frozenset(
|
||||
{"campaign_archive_encryption", "definition", "distribution_channels", "view"}
|
||||
)
|
||||
|
||||
|
||||
class PolicyOverrideError(ValueError):
|
||||
@@ -22,7 +24,7 @@ def normalize_policy_target(policy_family: str, target_key: str) -> tuple[str, s
|
||||
target = target_key.strip().casefold()
|
||||
if family not in POLICY_FAMILIES:
|
||||
raise PolicyOverrideError(
|
||||
"Policy family must be definition, distribution_channels, or view"
|
||||
"Policy family must be campaign_archive_encryption, definition, distribution_channels, or view"
|
||||
)
|
||||
if not target or len(target) > 120:
|
||||
raise PolicyOverrideError("Policy target must contain 1 to 120 characters")
|
||||
@@ -40,7 +42,9 @@ def normalize_policy_scope(
|
||||
clean_scope = scope_type.strip().casefold()
|
||||
clean_id = str(scope_id or "").strip() or None
|
||||
if clean_scope not in POLICY_SCOPE_TYPES:
|
||||
raise PolicyOverrideError("Policy scope must be system, tenant, group, or user")
|
||||
raise PolicyOverrideError(
|
||||
"Policy scope must be system, tenant, group, user, or campaign"
|
||||
)
|
||||
if clean_scope == "system":
|
||||
if clean_id is not None:
|
||||
raise PolicyOverrideError("System policy cannot declare a scope ID")
|
||||
@@ -142,6 +146,7 @@ def resolution_policy_overrides(
|
||||
tenant_id: str,
|
||||
group_ids: Iterable[str] = (),
|
||||
user_ids: Iterable[str] = (),
|
||||
campaign_ids: Iterable[str] = (),
|
||||
) -> tuple[PolicyOverride, ...]:
|
||||
family = policy_family.strip().casefold()
|
||||
targets = tuple(
|
||||
@@ -151,6 +156,9 @@ def resolution_policy_overrides(
|
||||
)
|
||||
groups = tuple(sorted({str(value) for value in group_ids if str(value)}))
|
||||
users = tuple(sorted({str(value) for value in user_ids if str(value)}))
|
||||
campaigns = tuple(
|
||||
sorted({str(value) for value in campaign_ids if str(value)})
|
||||
)
|
||||
scope_filters = [
|
||||
PolicyOverride.scope_key == "system",
|
||||
PolicyOverride.scope_key == f"tenant:{tenant_id}",
|
||||
@@ -167,6 +175,15 @@ def resolution_policy_overrides(
|
||||
[f"user:{tenant_id}:{user_id}" for user_id in users]
|
||||
)
|
||||
)
|
||||
if campaigns:
|
||||
scope_filters.append(
|
||||
PolicyOverride.scope_key.in_(
|
||||
[
|
||||
f"campaign:{tenant_id}:{campaign_id}"
|
||||
for campaign_id in campaigns
|
||||
]
|
||||
)
|
||||
)
|
||||
rows = (
|
||||
session.query(PolicyOverride)
|
||||
.filter(
|
||||
@@ -177,7 +194,13 @@ def resolution_policy_overrides(
|
||||
.all()
|
||||
)
|
||||
target_order = {target: index for index, target in enumerate(targets)}
|
||||
scope_order = {"system": 0, "tenant": 1, "group": 2, "user": 3}
|
||||
scope_order = {
|
||||
"system": 0,
|
||||
"tenant": 1,
|
||||
"group": 2,
|
||||
"user": 2,
|
||||
"campaign": 3,
|
||||
}
|
||||
return tuple(
|
||||
sorted(
|
||||
rows,
|
||||
|
||||
Reference in New Issue
Block a user