first commit
This commit is contained in:
69
backend/services/audit.py
Normal file
69
backend/services/audit.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
Audit logging service.
|
||||
Gebruik: from services.audit import audit_log
|
||||
audit_log('user.create', 'user', target_id=str(user.id), detail={'email': email})
|
||||
"""
|
||||
import json
|
||||
from datetime import datetime
|
||||
from flask import request
|
||||
from flask_login import current_user
|
||||
from app import db
|
||||
|
||||
|
||||
def audit_log(action: str, category: str, *,
|
||||
target_type: str = None, target_id: str = None,
|
||||
detail: dict = None, school_id: int = None,
|
||||
user_id: int = None):
|
||||
"""
|
||||
Schrijf een audit entry naar de database.
|
||||
|
||||
action: korte actienaam, bv. 'user.create', 'school.delete', 'login.success'
|
||||
category: auth | user | school | class | assessment | doelen | system
|
||||
target_type: wat er veranderd is, bv. 'user', 'school', 'class'
|
||||
target_id: identifier van het object (als string)
|
||||
detail: dict met extra context, wordt als JSON opgeslagen
|
||||
school_id: override school_id (standaard current_user.school_id)
|
||||
user_id: override user_id (standaard current_user.id)
|
||||
"""
|
||||
from models import AuditLog
|
||||
|
||||
try:
|
||||
uid = user_id
|
||||
sid = school_id
|
||||
|
||||
if uid is None:
|
||||
try:
|
||||
uid = current_user.id if current_user.is_authenticated else None
|
||||
except Exception:
|
||||
uid = None
|
||||
|
||||
if sid is None:
|
||||
try:
|
||||
sid = current_user.school_id if current_user.is_authenticated else None
|
||||
except Exception:
|
||||
sid = None
|
||||
|
||||
ip = None
|
||||
try:
|
||||
ip = request.remote_addr
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
entry = AuditLog(
|
||||
timestamp = datetime.utcnow(),
|
||||
user_id = uid,
|
||||
school_id = sid,
|
||||
action = action,
|
||||
category = category,
|
||||
target_type = target_type,
|
||||
target_id = str(target_id) if target_id is not None else None,
|
||||
detail = json.dumps(detail, ensure_ascii=False) if detail else None,
|
||||
ip_address = ip,
|
||||
)
|
||||
db.session.add(entry)
|
||||
# Geen commit hier — de aanroeper commit zelf (of we flushen mee)
|
||||
db.session.flush()
|
||||
except Exception as e:
|
||||
# Audit failures mogen de hoofdflow nooit blokkeren
|
||||
import logging
|
||||
logging.getLogger(__name__).warning(f"Audit log failed: {e}")
|
||||
Reference in New Issue
Block a user