79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
import time
|
||
|
|
from datetime import datetime, UTC
|
||
|
|
|
||
|
|
from yuxi.utils.logging_config import logger
|
||
|
|
|
||
|
|
|
||
|
|
class SecurityAuditLogger:
|
||
|
|
_audit_logger = logger
|
||
|
|
_output_format: str = "text"
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def set_output_format(cls, fmt: str) -> None:
|
||
|
|
cls._output_format = fmt
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def _log(cls, event_type: str, details: dict) -> None:
|
||
|
|
entry = {
|
||
|
|
"timestamp": datetime.now(UTC).isoformat(),
|
||
|
|
"event_type": event_type,
|
||
|
|
"unix_ts": time.time(),
|
||
|
|
**details,
|
||
|
|
}
|
||
|
|
if cls._output_format == "json":
|
||
|
|
cls._audit_logger.warning(f"[SECURITY_AUDIT] {json.dumps(entry, ensure_ascii=False)}")
|
||
|
|
else:
|
||
|
|
cls._audit_logger.warning(f"[SECURITY_AUDIT] {entry}")
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_dm_policy_blocked(cls, user_id: str, reason: str, policy: str) -> None:
|
||
|
|
cls._log(
|
||
|
|
"dm_policy_blocked",
|
||
|
|
{"user_id": user_id, "reason": reason, "dm_policy": policy},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_group_access_blocked(cls, group_id: str, user_id: str, reason: str) -> None:
|
||
|
|
cls._log(
|
||
|
|
"group_access_blocked",
|
||
|
|
{"group_id": group_id, "user_id": user_id, "reason": reason},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_mention_required_blocked(cls, group_id: str, user_id: str) -> None:
|
||
|
|
cls._log(
|
||
|
|
"mention_required_blocked",
|
||
|
|
{"group_id": group_id, "user_id": user_id, "reason": "missing_mention"},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_unauthorized_access(cls, user_id: str, resource: str, detail: str = "") -> None:
|
||
|
|
cls._log(
|
||
|
|
"unauthorized_access",
|
||
|
|
{"user_id": user_id, "resource": resource, "detail": detail},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_rate_limit_exceeded(cls, user_id: str, limit_type: str) -> None:
|
||
|
|
cls._log(
|
||
|
|
"rate_limit_exceeded",
|
||
|
|
{"user_id": user_id, "limit_type": limit_type},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_circuit_breaker_open(cls, user_id: str = "", reason: str = "") -> None:
|
||
|
|
cls._log(
|
||
|
|
"circuit_breaker_open",
|
||
|
|
{"user_id": user_id, "reason": reason},
|
||
|
|
)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def log_auth_failure(cls, account_id: str, reason: str) -> None:
|
||
|
|
cls._log(
|
||
|
|
"auth_failure",
|
||
|
|
{"account_id": account_id, "reason": reason},
|
||
|
|
)
|