Files

82 lines
2.6 KiB
Python

# retoor <retoor@molodetz.nl>
import json
import logging
from molodetz.database import generate_uid, insert_audit, now_iso
from molodetz.services.queue import background
from molodetz.utils.request_meta import client_ip
logger = logging.getLogger(__name__)
CATEGORY_BY_PREFIX = {
"auth": "auth",
"admin": "admin",
"post": "content",
"join": "community",
"security": "security",
"service": "service",
"backup": "service",
"system": "system",
"notification": "system",
"profile": "account",
}
def category_for(event_key):
return CATEGORY_BY_PREFIX.get(event_key.split(".", 1)[0], "other")
def _build(event_key, actor_kind, actor_uid, origin, result, ip, user_agent, message, payload, targets):
uid = generate_uid()
row = {
"uid": uid,
"event_key": event_key,
"category": category_for(event_key),
"actor_kind": actor_kind,
"actor_uid": actor_uid,
"origin": origin,
"result": result,
"ip": ip,
"user_agent": (user_agent or "")[:300] or None,
"message": message,
"payload": json.dumps(payload or {}, default=str),
"created_at": now_iso(),
}
links = [{"audit_uid": uid, "target_type": t, "target_uid": u} for t, u in (targets or [])]
return row, links
def record(request, event_key, result="ok", message=None, payload=None, targets=None, user=None):
try:
if user is None:
user = getattr(request.state, "user_cached", None) if request is not None else None
ip = client_ip(request) if request is not None else None
agent = request.headers.get("user-agent") if request is not None else None
row, links = _build(
event_key,
"user" if user else "guest",
user["uid"] if user else None,
"web",
result,
ip,
agent,
message,
payload,
targets,
)
background.submit(insert_audit, row, links)
return row["uid"]
except Exception:
logger.exception("audit record failed for %s", event_key)
return None
def record_system(event_key, actor_kind="system", origin="system", result="ok", message=None, payload=None, targets=None, actor_uid=None):
try:
row, links = _build(event_key, actor_kind, actor_uid, origin, result, None, None, message, payload, targets)
background.submit(insert_audit, row, links)
return row["uid"]
except Exception:
logger.exception("audit record_system failed for %s", event_key)
return None