-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added audit operation for data source and user #1981
Conversation
@@ -603,6 +608,8 @@ def post(self, request, *args, **kwargs): | |||
operation=OperationEnum.SYNC_DATA_SOURCE, | |||
object_type=ObjectTypeEnum.DATA_SOURCE, | |||
object_id=data_source.id, | |||
data_before={}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议 data_before, data_after, extras 都做成可选参数
|
||
|
||
class CurrentUserDepartmentRelationMixin: | ||
"""获取用户与部门之间的映射关系""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
需要讨论:加这个 mixin 来算数据,是否合适?
) | ||
|
||
# 【审计】批量添加审计记录 | ||
batch_add_audit_records( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nannan00 感觉审计的逻辑有点太多了,比业务逻辑还要多 :(
) | ||
|
||
# 若有数据变更,则添加记录 | ||
if data_before != data_after or extras != {}: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
数据还能有没变更的情况么,如果有得加 warning 日志?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
目前存在一个问题:操作审计的代码远多于业务代码,显得特别乱,可读性很差
@@ -191,8 +293,38 @@ def delete(self, request, *args, **kwargs): | |||
id__in=data["user_ids"], | |||
).values_list("data_source_user_id", flat=True) | |||
|
|||
# 【审计】记录变更前用户-部门映射 | |||
user_department_map_before = self.get_user_department_map(data_source_user_ids=data_source_user_ids) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
为审计预留的数据, 统一命名:
data_before_xxxxx
data_after_xxxx
operator=request.user.username, | ||
tenant_id=self.get_current_tenant_id(), | ||
objects=audit_objects, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nannan00
每个审计看起来还是非常复杂的, 反客为主占用业务逻辑的带宽
是否能针对这类
- 构造 audit_objects 有没有更简单的方法,能够抽象出来
- 对象默认值设置好,只关注需要传入的对象
- 将审计代码抽成
self._get_audit(xxxxx)
?
# 操作后数据 | ||
data_after: Dict | ||
# 额外信息 | ||
extras: Dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 操作对象名称
name: str = ""
...
# 操作前数据
data_before: Dict = Field(default_factory=dict)
# 操作后数据
data_after: Dict = Field(default_factory=dict)
# 额外信息
extras: Dict = Field(default_factory=dict)
tenant_id=cur_tenant_id, | ||
objects=audit_objects, | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
目前是 view -> apps.audit , view -> biz -> apps.audit
在 Biz 模块里,封装业务相关的审计,避免 审计代码过多导致 view 里本身业务逻辑的可读性变差
比如 biz/auditor.py 里 定义 TenantUserUpdateAuditor
# 是否定义对象更具体操作的审计?根据场景考虑,DataSourceDeleteAuditor、TenantUserUpdateAuditor 之类的
class TenantUserUpdateAuditor:
"""用于记录租户用户变更的审计"""
def __init__(self, operator: str, tenant_id: str):
self.operator = operator
self.tenant_id = tenant_id
// 根据实际需要定义
self.data_befores = {}
def pre_record_data_before(self, tenant_user: TenantUser):
# 执行变更前的相关数据记录
# 【审计】记录修改前的数据源用户数据
self.data_befores["data_source_user"] = get_model_dict(tenant_user.data_source_user)
# 【审计】记录修改前的租户用户数据
self.data_befores["tenant_user"] = get_model_dict(tenant_user)
# 【审计】记录修改前的用户部门
self.data_befores["department_ids"] = list(
DataSourceDepartmentUserRelation.objects.filter(
user=data_source_user,
).values_list("department_id", flat=True)
)
# 【审计】记录修改前的用户上级
self.data_befores["leader_ids"] = list(
DataSourceUserLeaderRelation.objects.filter(user=data_source_user).values_list("leader_id", flat=True)
)
def record(self, tenant_user: TenantUser, data_source_user: DataSourceUser, leader_ids: List[int], department_ids: List[int]):
# 组装相关数据,并调用 apps.audit 模块里的方法进行记录
ds_user_object = {"id": data_source_user.id, "name": data_source_user.username, "type": ObjectTypeEnum.DATA_SOURCE_USER}
audit_objects = [
# 数据源用户本身信息
AuditObject(
**ds_user_object,
operation=OperationEnum.MODIFY_DATA_SOURCE_USER,
data_before=self.data_befores["data_source_user"],
data_after=get_model_dict(data_source_user),
),
# 数据源用户的部门
AuditObject(
**ds_user_object,
operation=OperationEnum.MODIFY_USER_DEPARTMENT,
data_before={"department_ids": self.data_befores["department_ids"]},
data_after={"department_ids": department_ids},
),
# 数据源用户的 Leader
AuditObject(
**ds_user_object,
operation=OperationEnum.MODIFY_USER_LEADER,
data_before={"leader_ids": self.data_befores["leader_ids"]},
data_after={"leader_ids": leader_ids},
),
# 租户用户
AuditObject(
id=tenant_user.id,
type=ObjectTypeEnum.TENANT_USER,
operation=OperationEnum.MODIFY_TENANT_USER,
data_before=self.data_befores["tenant_user_before"],
data_after=get_model_dict(tenant_user),
)
]
batch_add_audit_records(self.operator, self.tenant_id, audit_objects)
调用点(暂时不考虑 Context 方式调用):
auditor = TenantUserUpdateAuditor(request.user.username, cur_tenant_id)
auditor.pre_record_data_before(tenant_user)
......
# 执行变更
......
auditor.record(tenant_user.id, data_source_dept_ids , data_source_leader_ids)
operation=OperationEnum.MODIFY_USER_LEADER_RELATIONS, | ||
# 采用 sorted 为了 list 对象比较 | ||
data_before={"leader_ids": sorted(data_source_leader_ids_before)}, | ||
data_after={"leader_ids": sorted(data_source_leader_ids)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
比较
是底层的审计方法职责,上层不需要关注
Description
用户管理 SaaS 操作审计(模型 + 数据源 + 用户)
Checklist