fix(installer): audit credential retirement

This commit is contained in:
2026-07-21 15:46:20 +02:00
parent 613fb15a80
commit d005040a8e
3 changed files with 100 additions and 15 deletions

View File

@@ -1,7 +1,10 @@
from __future__ import annotations
from dataclasses import replace
from pathlib import Path
from sqlalchemy import inspect
from govoplan_addresses.backend.capabilities import (
CAPABILITY_ADDRESSES_CONTACT_WRITER,
CAPABILITY_ADDRESSES_LOOKUP,
@@ -25,6 +28,47 @@ from govoplan_core.core.modules import (
from govoplan_core.db.base import Base
_addresses_table_retirement_provider = drop_table_retirement_provider(
addresses_models.AddressSyncDiagnostic,
addresses_models.AddressSyncConflict,
addresses_models.AddressSyncTombstone,
addresses_models.AddressSyncSource,
addresses_models.AddressListEntry,
addresses_models.AddressList,
addresses_models.ContactPostalAddress,
addresses_models.ContactPhone,
addresses_models.ContactEmail,
addresses_models.Contact,
addresses_models.AddressBook,
label="Addresses",
)
def _addresses_retirement_provider(session: object | None, module_id: str):
plan = _addresses_table_retirement_provider(session, module_id)
base_executor = plan.destroy_data_executor
if base_executor is None:
return plan
def executor(execute_session: object, execute_module_id: str) -> None:
if not hasattr(execute_session, "get_bind") or not hasattr(execute_session, "query"):
raise RuntimeError("No database session is available for Addresses credential retirement.")
if inspect(execute_session.get_bind()).has_table(addresses_models.AddressSyncSource.__tablename__):
from govoplan_addresses.backend.service import audit_address_credentials_for_retirement
audit_address_credentials_for_retirement(execute_session)
base_executor(execute_session, execute_module_id)
return replace(
plan,
destroy_data_warnings=(
*plan.destroy_data_warnings,
"Addresses-owned encrypted connector credentials are audited and deleted with the sync-source table.",
),
destroy_data_executor=executor,
)
def _permission(scope: str, label: str, description: str) -> PermissionDefinition:
module_id, resource, action = scope.split(":", 2)
return PermissionDefinition(
@@ -128,20 +172,7 @@ manifest = ModuleManifest(
metadata=Base.metadata,
script_location=str(Path(__file__).with_name("migrations") / "versions"),
retirement_supported=True,
retirement_provider=drop_table_retirement_provider(
addresses_models.AddressSyncDiagnostic,
addresses_models.AddressSyncConflict,
addresses_models.AddressSyncTombstone,
addresses_models.AddressSyncSource,
addresses_models.AddressListEntry,
addresses_models.AddressList,
addresses_models.ContactPostalAddress,
addresses_models.ContactPhone,
addresses_models.ContactEmail,
addresses_models.Contact,
addresses_models.AddressBook,
label="Addresses",
),
retirement_provider=_addresses_retirement_provider,
retirement_notes="Destructive retirement drops address-owned database tables after the installer captures a database snapshot.",
),
capability_factories={