Prepare GovOPlaN self-hosted release workflow
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from uuid import uuid4
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.auth import ApiPrincipal
|
||||
from govoplan_core.core.change_sequence import record_change
|
||||
from govoplan_core.core.access import AuditEvent, AuditRecordRef, AuditRecorder, CAPABILITY_AUDIT_RECORDER
|
||||
from govoplan_core.core.events import (
|
||||
EventActorRef,
|
||||
EventObjectRef,
|
||||
@@ -16,8 +18,8 @@ from govoplan_core.core.events import (
|
||||
normalize_trace_id,
|
||||
publish_platform_event,
|
||||
)
|
||||
from govoplan_core.core.runtime import get_registry
|
||||
from govoplan_core.privacy.retention import sanitize_audit_details_for_policy
|
||||
from govoplan_audit.backend.db.models import AuditLog
|
||||
|
||||
|
||||
AUDIT_MODULE_ID = "audit"
|
||||
@@ -47,6 +49,7 @@ _ACTION_MODULE_PREFIXES = {
|
||||
"configuration_change": "access",
|
||||
"configuration_package": "access",
|
||||
"group": "access",
|
||||
"idm": "idm",
|
||||
"profile": "access",
|
||||
"role": "access",
|
||||
"system_access": "access",
|
||||
@@ -169,7 +172,33 @@ def _module_id_for_audit_action(action: str) -> str:
|
||||
return _ACTION_MODULE_PREFIXES.get(prefix, prefix or AUDIT_MODULE_ID)
|
||||
|
||||
|
||||
def _publish_audit_platform_event(item: AuditLog) -> None:
|
||||
def _audit_recorder() -> AuditRecorder:
|
||||
registry = get_registry()
|
||||
if registry is None or not hasattr(registry, "has_capability") or not registry.has_capability(CAPABILITY_AUDIT_RECORDER):
|
||||
return _NullAuditRecorder()
|
||||
capability = registry.require_capability(CAPABILITY_AUDIT_RECORDER)
|
||||
if not isinstance(capability, AuditRecorder):
|
||||
raise RuntimeError("Audit recorder capability is invalid")
|
||||
return capability
|
||||
|
||||
|
||||
class _NullAuditRecorder:
|
||||
def record_event(self, session: object, event: AuditEvent) -> AuditRecordRef:
|
||||
del session
|
||||
return AuditRecordRef(
|
||||
id=str(uuid4()),
|
||||
scope=event.scope,
|
||||
tenant_id=event.tenant_id,
|
||||
user_id=event.user_id,
|
||||
api_key_id=event.api_key_id,
|
||||
action=event.action,
|
||||
object_type=event.resource_type,
|
||||
object_id=event.resource_id,
|
||||
details=dict(event.details or {}),
|
||||
)
|
||||
|
||||
|
||||
def _publish_audit_platform_event(item: AuditRecordRef) -> None:
|
||||
trace = _compact_trace(item.details.get("_trace") if isinstance(item.details, Mapping) else None)
|
||||
publish_platform_event(
|
||||
PlatformEvent(
|
||||
@@ -206,7 +235,7 @@ def audit_event(
|
||||
correlation_id: str | None = None,
|
||||
causation_id: str | None = None,
|
||||
commit: bool = False,
|
||||
) -> AuditLog:
|
||||
) -> AuditRecordRef:
|
||||
"""Persist one audit event.
|
||||
|
||||
The function deliberately accepts primitive IDs so it can be used from API
|
||||
@@ -227,18 +256,17 @@ def audit_event(
|
||||
trace,
|
||||
)
|
||||
|
||||
item = AuditLog(
|
||||
item = _audit_recorder().record_event(session, AuditEvent(
|
||||
event_type=action,
|
||||
action=action,
|
||||
scope=scope,
|
||||
tenant_id=tenant_id,
|
||||
user_id=user_id,
|
||||
api_key_id=api_key_id,
|
||||
action=action,
|
||||
object_type=object_type,
|
||||
object_id=object_id,
|
||||
resource_type=object_type,
|
||||
resource_id=object_id,
|
||||
details=stored_details,
|
||||
)
|
||||
session.add(item)
|
||||
session.flush()
|
||||
))
|
||||
record_change(
|
||||
session,
|
||||
module_id=AUDIT_MODULE_ID,
|
||||
@@ -269,7 +297,7 @@ def audit_from_principal(
|
||||
correlation_id: str | None = None,
|
||||
causation_id: str | None = None,
|
||||
commit: bool = False,
|
||||
) -> AuditLog:
|
||||
) -> AuditRecordRef:
|
||||
return audit_event(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
|
||||
Reference in New Issue
Block a user