readme
This commit is contained in:
+58
-28
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user