This commit is contained in:
Your Name
2026-07-20 13:40:05 +08:00
parent 9e34f6f0f9
commit bca0da7c7d
12 changed files with 1609 additions and 525 deletions
+58 -28
View File
@@ -1,37 +1,67 @@
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, Index
from sqlalchemy import Column, Integer, String, Text, DateTime, Enum
from sqlalchemy.sql import func
from app.core.database import Base
import enum
class AuditAction(str, enum.Enum):
"""操作类型枚举"""
CREATE = "create"
READ = "read"
UPDATE = "update"
DELETE = "delete"
LOGIN = "login"
LOGOUT = "logout"
SCAN = "scan"
IMPORT = "import"
EXPORT = "export"
OTHER = "other"
class AuditResource(str, enum.Enum):
"""资源类型枚举"""
USER = "user"
NETWORK = "network"
IP_ADDRESS = "ip_address"
SNMP_CREDENTIAL = "snmp_credential"
SNMP_DEVICE = "snmp_device"
ALERT = "alert"
WHITELIST_MAC = "whitelist_mac"
SCAN_TASK = "scan_task"
SYSTEM = "system"
class AuditLog(Base):
"""审计日志:记录用户的关键操作"""
"""审计日志"""
__tablename__ = "audit_logs"
id = Column(Integer, primary_key=True, index=True)
# 操作人nullable:登录失败、token 失效等场景可能没有 user_id)
user_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
username = Column(String(50), index=True, comment="冗余存储用户名,便于 user 被删除后仍能查看")
# 操作内容
action = Column(String(50), nullable=False, index=True, comment="操作类型,如:network.create")
resource_type = Column(String(50), nullable=True, index=True, comment="资源类型:network / ip / snmp / user / scan")
resource_id = Column(String(50), nullable=True, comment="资源 ID(字符串以便兼容多种类型)")
resource_name = Column(String(200), nullable=True, comment="资源名称/标识,便于阅读")
# 操作人信息
user_id = Column(Integer, index=True, nullable=True)
username = Column(String(50), index=True)
real_name = Column(String(50))
user_ip = Column(String(50))
user_agent = Column(String(500))
# 操作信息
action = Column(Enum(AuditAction), nullable=False, index=True)
resource = Column(Enum(AuditResource), nullable=False, index=True)
resource_id = Column(String(100), nullable=True) # 操作的资源ID
# 详细信息
description = Column(String(500)) # 操作描述
old_value = Column(Text) # 修改前的值 (JSON)
new_value = Column(Text) # 修改后的值 (JSON)
changed_fields = Column(String(500)) # 变更的字段列表
# 请求信息
method = Column(String(10), comment="HTTP 方法")
path = Column(String(500), comment="请求路径")
ip_address = Column(String(50), comment="客户端 IP")
user_agent = Column(String(500), comment="User-Agent")
# 状态
status = Column(String(20), default="success", index=True, comment="success / failed")
detail = Column(Text, comment="变更详情 / 错误信息 / JSON diff")
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
# 复合索引:按时间+用户查、按时间+资源查更高效
Index("idx_audit_logs_user_created", AuditLog.user_id, AuditLog.created_at.desc())
Index("idx_audit_logs_resource", AuditLog.resource_type, AuditLog.resource_id, AuditLog.created_at.desc())
request_method = Column(String(10))
request_path = Column(String(200))
# 结果
success = Column(Integer, default=1) # 1=成功,0=失败
error_message = Column(Text)
# 时间戳
created_at = Column(DateTime(timezone=True), server_default=func.now(), index=True)