71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import uuid
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from sqlalchemy.orm import Session
|
||
|
|
|
||
|
|
from app.core.logging import get_logger
|
||
|
|
from app.models.audit_log import AuditLog
|
||
|
|
from app.repositories.audit_log import AuditLogRepository
|
||
|
|
from app.schemas.audit_log import AuditLogRead
|
||
|
|
from app.services.agent_foundation import AgentFoundationService
|
||
|
|
|
||
|
|
logger = get_logger("app.services.audit")
|
||
|
|
|
||
|
|
|
||
|
|
class AuditLogService:
|
||
|
|
def __init__(self, db: Session) -> None:
|
||
|
|
self.db = db
|
||
|
|
self.repository = AuditLogRepository(db)
|
||
|
|
|
||
|
|
def list_logs(
|
||
|
|
self,
|
||
|
|
*,
|
||
|
|
resource_type: str | None = None,
|
||
|
|
resource_id: str | None = None,
|
||
|
|
action: str | None = None,
|
||
|
|
limit: int = 50,
|
||
|
|
) -> list[AuditLogRead]:
|
||
|
|
self._ensure_ready()
|
||
|
|
items = self.repository.list(
|
||
|
|
resource_type=resource_type,
|
||
|
|
resource_id=resource_id,
|
||
|
|
action=action,
|
||
|
|
limit=limit,
|
||
|
|
)
|
||
|
|
return [AuditLogRead.model_validate(item) for item in items]
|
||
|
|
|
||
|
|
def log_action(
|
||
|
|
self,
|
||
|
|
*,
|
||
|
|
actor: str,
|
||
|
|
action: str,
|
||
|
|
resource_type: str,
|
||
|
|
resource_id: str,
|
||
|
|
before_json: dict[str, Any] | None = None,
|
||
|
|
after_json: dict[str, Any] | None = None,
|
||
|
|
request_id: str | None = None,
|
||
|
|
) -> AuditLog:
|
||
|
|
log = AuditLog(
|
||
|
|
actor=actor,
|
||
|
|
action=action,
|
||
|
|
resource_type=resource_type,
|
||
|
|
resource_id=resource_id,
|
||
|
|
before_json=before_json,
|
||
|
|
after_json=after_json,
|
||
|
|
request_id=request_id or uuid.uuid4().hex,
|
||
|
|
)
|
||
|
|
created = self.repository.create(log)
|
||
|
|
logger.info(
|
||
|
|
"Created audit log id=%s action=%s resource=%s:%s",
|
||
|
|
created.id,
|
||
|
|
created.action,
|
||
|
|
created.resource_type,
|
||
|
|
created.resource_id,
|
||
|
|
)
|
||
|
|
return created
|
||
|
|
|
||
|
|
def _ensure_ready(self) -> None:
|
||
|
|
AgentFoundationService(self.db).ensure_foundation_ready()
|