feat: cover tenant erasure evidence in DSAR
Module Package Release / publish-packages (push) Successful in 12s
Module Package Release / publish-packages (push) Successful in 12s
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.core.dsar import DsarSubjectRef
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_tenancy.backend.db.models import TenantErasureOperation
|
||||
from govoplan_tenancy.backend.dsar_provider import TenancyDsarProvider
|
||||
|
||||
|
||||
def _operation(now: datetime) -> TenantErasureOperation:
|
||||
return TenantErasureOperation(
|
||||
tenant_id="tenant-1",
|
||||
state="ready",
|
||||
idempotency_key="request-1234",
|
||||
request_digest="a" * 64,
|
||||
preview_digest="b" * 64,
|
||||
preview={"schema_version": 1},
|
||||
previewed_at=now,
|
||||
preview_expires_at=now + timedelta(minutes=15),
|
||||
policy={"required_approvals": 2},
|
||||
approvals=[
|
||||
{"account_id": "account-1", "approved_at": now.isoformat()},
|
||||
{"account_id": "account-2", "approved_at": now.isoformat()},
|
||||
],
|
||||
steps=[],
|
||||
requested_by_account_id="account-1",
|
||||
reason="Contract ended",
|
||||
destructive_started=False,
|
||||
revision=3,
|
||||
)
|
||||
|
||||
|
||||
def test_dsar_exports_only_subject_actor_evidence_and_retains_it() -> None:
|
||||
engine = create_engine("sqlite+pysqlite:///:memory:")
|
||||
Base.metadata.create_all(engine)
|
||||
now = datetime(2026, 8, 24, 12, 0, tzinfo=UTC)
|
||||
with Session(engine) as session:
|
||||
operation = _operation(now)
|
||||
session.add(operation)
|
||||
session.commit()
|
||||
provider = TenancyDsarProvider()
|
||||
|
||||
requester_records = provider.search_subject(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
subject=DsarSubjectRef(account_id="account-1"),
|
||||
)
|
||||
approver_records = provider.search_subject(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
subject=DsarSubjectRef(account_id="account-2"),
|
||||
)
|
||||
|
||||
assert requester_records[0].data["actor_roles"] == ["requester", "approver"]
|
||||
assert requester_records[0].data["request_reason"] == "Contract ended"
|
||||
assert approver_records[0].data["actor_roles"] == ["approver"]
|
||||
assert "request_reason" not in approver_records[0].data
|
||||
assert requester_records[0].immutable_evidence
|
||||
|
||||
actions = provider.plan_erasure(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
subject=DsarSubjectRef(account_id="account-1"),
|
||||
records=requester_records,
|
||||
)
|
||||
assert actions[0].kind == "retain"
|
||||
assert not actions[0].executable
|
||||
results = provider.execute_erasure(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
subject=DsarSubjectRef(account_id="account-1"),
|
||||
actions=actions,
|
||||
request_id="dsar-1",
|
||||
)
|
||||
assert results[0].status == "blocked"
|
||||
|
||||
|
||||
def test_dsar_rejects_conflicting_account_selectors() -> None:
|
||||
engine = create_engine("sqlite+pysqlite:///:memory:")
|
||||
Base.metadata.create_all(engine)
|
||||
with Session(engine) as session:
|
||||
assert (
|
||||
TenancyDsarProvider().search_subject(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
subject=DsarSubjectRef(
|
||||
account_id="account-1",
|
||||
external_references={"access.account": "account-2"},
|
||||
),
|
||||
)
|
||||
== ()
|
||||
)
|
||||
Reference in New Issue
Block a user