Files
wecom_it_smart_desk/backend/app/models/audit_log.py
T
Simon 78f60c6857 feat(v0.7.1): P0 修复 + 企微 SSO + RBAC 细粒度 + audit_log
P0 修复:
- /api/ready import 错误 (_get_engine + settings.create_redis_client)
- 删 agent.otp_secret/otp_enabled 双字段 (migration 026)
- 重建 021_rbac migration (IF NOT EXISTS 兼容)

P1 新增:
- 企微 SSO (auth_wecom_sso.py, useWeChatWorkSSO composable, PortalSelect UA 检测)
- RBAC 5 角色 × 4 资源 × 4 操作 × 3 范围 (rbac_service + seed_rbac + require_permission)
- audit_log 模型 + migration 027 + 服务 + API
- 管理后台 RBAC 权限矩阵 UI (PermissionsMatrix.vue)

质量:
- pytest 405 passed / 33 pre-existing failed / 4 xfailed (v0.7.1 引入失败 = 0)
- conftest GBK patch 强制 UTF-8 读 .env
- .gitignore 排除 *.b64 (含 admin token 凭据)
- DEPLOY-v0.7.1.md 7 步 runbook + 4 坑 + 回滚预案
2026-06-22 17:38:47 +08:00

131 lines
4.1 KiB
Python

# =============================================================================
# 企微IT智能服务台 — 审计日志模型
# =============================================================================
# 说明: 对应数据库 audit_logs 表,记录所有高危/RBAC 操作 + 登录/MFA 事件
# 给 auditor 角色 + admin 提供只读审计能力
#
# 何时写入:
# - 高危操作 (role_change / config_change / data_export / account_disable / account_create_reset)
# - RBAC 操作 (assign_role / revoke_role / create_mapping_rule / delete_mapping_rule)
# - 登录事件 (qrcode_login / sso_login / password_login)
# - MFA 事件 (bind / verify / reset)
# - 业务敏感操作 (resolve_conversation / transfer_conversation)
# =============================================================================
import uuid
from datetime import datetime
from typing import Optional
from sqlalchemy import JSON, DateTime, Index, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class AuditLog(Base):
"""审计日志模型 — 对应 audit_logs 表。
Attributes:
id: 日志唯一标识(UUID)
employee_id: 操作人(企微 UserID,系统操作填 "system")
action: 操作类型(如 "role_change", "login", "mfa_verify")
resource: 目标资源类型("agent" / "conversation" / "system_config" 等)
resource_id: 目标资源 ID
details: 详细上下文(JSON,前后值/IP/UA 等)
result: "success" / "failure" / "partial"
ip_address: 操作来源 IP(可选)
user_agent: 操作来源 UA(可选)
created_at: 时间
"""
__tablename__ = "audit_logs"
# 主键:UUID
id: Mapped[str] = mapped_column(
String(36),
primary_key=True,
default=lambda: str(uuid.uuid4()),
)
# 操作人(企微 UserID, 系统操作填 "system")
employee_id: Mapped[str] = mapped_column(
String(100),
nullable=False,
comment="操作人(employee_id / 'system')",
)
# 操作类型
# 例: "role_change" / "config_change" / "login" / "mfa_verify" /
# "qrcode_login" / "sso_login" / "password_login" /
# "resolve_conversation" / "transfer_conversation" / "data_export"
action: Mapped[str] = mapped_column(
String(50),
nullable=False,
comment="操作类型",
)
# 目标资源类型
# 例: "agent" / "conversation" / "system_config" / "role" / "user_role"
resource: Mapped[str] = mapped_column(
String(50),
nullable=False,
comment="目标资源类型",
)
# 目标资源 ID(字符串,跨表通用)
resource_id: Mapped[Optional[str]] = mapped_column(
String(100),
nullable=True,
comment="目标资源 ID",
)
# 详细上下文(JSON)
# 例: {"role": "agent", "reason": "新员工转岗", "ip": "10.80.0.5"}
details: Mapped[Optional[dict]] = mapped_column(
JSON,
nullable=True,
comment="详细上下文(JSON)",
)
# 结果
# "success" / "failure" / "partial"
result: Mapped[str] = mapped_column(
String(20),
nullable=False,
default="success",
comment="执行结果",
)
# 来源 IP
ip_address: Mapped[Optional[str]] = mapped_column(
String(64),
nullable=True,
comment="来源 IP",
)
# 来源 User-Agent
user_agent: Mapped[Optional[str]] = mapped_column(
Text,
nullable=True,
comment="来源 User-Agent",
)
# 时间
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
nullable=False,
default=datetime.now,
comment="时间",
)
# 索引:按 employee_id / action / time 查询
__table_args__ = (
Index("idx_audit_employee_id", "employee_id"),
Index("idx_audit_action", "action"),
Index("idx_audit_resource", "resource", "resource_id"),
Index("idx_audit_created_at", "created_at"),
)
def __repr__(self) -> str:
return f"<AuditLog(action={self.action}, employee={self.employee_id}, result={self.result})>"