Skip to content
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 operation audit for data source and users #1987

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 26 additions & 30 deletions src/bk-user/bkuser/apis/web/data_source/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
)
from bkuser.apis.web.mixins import CurrentUserTenantMixin
from bkuser.apps.audit.constants import ObjectTypeEnum, OperationEnum
from bkuser.apps.audit.recorder import add_audit_record
from bkuser.apps.audit.data_models import AuditObject
from bkuser.apps.audit.recorder import add_audit_record, batch_add_audit_records
from bkuser.apps.data_source.constants import DataSourceTypeEnum
from bkuser.apps.data_source.models import (
DataSource,
Expand Down Expand Up @@ -80,6 +81,7 @@
from bkuser.idp_plugins.constants import BuiltinIdpPluginEnum
from bkuser.plugins.base import get_default_plugin_cfg, get_plugin_cfg_schema_map, get_plugin_cls
from bkuser.plugins.constants import DataSourcePluginEnum
from bkuser.utils.django import get_model_dict

from .schema import get_data_source_plugin_cfg_json_schema

Expand Down Expand Up @@ -193,11 +195,7 @@ def post(self, request, *args, **kwargs):
operation=OperationEnum.CREATE_DATA_SOURCE,
object_type=ObjectTypeEnum.DATA_SOURCE,
object_id=ds.id,
extras={
"plugin_config": ds.plugin_config,
"field_mapping": ds.field_mapping,
"sync_config": ds.sync_config,
},
data_after=get_model_dict(ds),
)

return Response(
Expand Down Expand Up @@ -253,11 +251,7 @@ def put(self, request, *args, **kwargs):
data = slz.validated_data

# 【审计】记录变更前数据
data_before = {
"plugin_config": data_source.plugin_config,
"field_mapping": data_source.field_mapping,
"sync_config": data_source.sync_config,
}
data_before_data_source = get_model_dict(data_source)

with transaction.atomic():
data_source.field_mapping = data["field_mapping"]
Expand All @@ -274,7 +268,8 @@ def put(self, request, *args, **kwargs):
operation=OperationEnum.MODIFY_DATA_SOURCE,
object_type=ObjectTypeEnum.DATA_SOURCE,
object_id=data_source.id,
extras={"data_before": data_before},
data_before=data_before_data_source,
data_after=get_model_dict(data_source),
)

return Response(status=status.HTTP_204_NO_CONTENT)
Expand Down Expand Up @@ -308,14 +303,23 @@ def delete(self, request, *args, **kwargs):
# 待删除的认证源
waiting_delete_idps = Idp.objects.filter(**idp_filters)

# 【审计】记录变更前数据,数据删除后便无法获取
idps_before_delete = list(
waiting_delete_idps.values("id", "name", "status", "plugin_config", "data_source_match_rules")
# 记录 data_source 删除前数据
data_source_audit_object = AuditObject(
id=data_source.id,
type=ObjectTypeEnum.DATA_SOURCE,
operation=OperationEnum.DELETE_DATA_SOURCE,
data_before=get_model_dict(data_source),
)
data_source_id = data_source.id
plugin_config = data_source.plugin_config
field_mapping = data_source.field_mapping
sync_config = data_source.sync_config
# 记录 idp 删除前数据
idp_audit_objects = [
AuditObject(
id=data_before_idp.id,
type=ObjectTypeEnum.IDP,
operation=OperationEnum.DELETE_IDP,
data_before=get_model_dict(data_before_idp),
)
for data_before_idp in list(waiting_delete_idps)
]

with transaction.atomic():
# 删除认证源敏感信息
Expand All @@ -334,20 +338,12 @@ def delete(self, request, *args, **kwargs):
# 删除数据源 & 关联资源数据
DataSourceHandler.delete_data_source_and_related_resources(data_source)

audit_objects = [data_source_audit_object] + idp_audit_objects
# 审计记录
add_audit_record(
batch_add_audit_records(
operator=request.user.username,
tenant_id=self.get_current_tenant_id(),
operation=OperationEnum.DELETE_DATA_SOURCE,
object_type=ObjectTypeEnum.DATA_SOURCE,
object_id=data_source_id,
extras={
"is_delete_idp": is_delete_idp,
"plugin_config": plugin_config,
"field_mapping": field_mapping,
"sync_config": sync_config,
"idps_before_delete": idps_before_delete,
},
objects=audit_objects,
rolin999 marked this conversation as resolved.
Show resolved Hide resolved
)

return Response(status=status.HTTP_204_NO_CONTENT)
Expand Down
37 changes: 37 additions & 0 deletions src/bk-user/bkuser/apis/web/organization/views/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from bkuser.apps.permission.constants import PermAction
from bkuser.apps.permission.permissions import perm_class
from bkuser.apps.tenant.models import TenantDepartment, TenantUser
from bkuser.biz.auditor import TenantUserDepartmentRelationsAuditor


class TenantDeptUserRelationBatchCreateApi(CurrentUserTenantDataSourceMixin, generics.CreateAPIView):
Expand Down Expand Up @@ -66,6 +67,12 @@ def post(self, request, *args, **kwargs):
id__in=data["user_ids"],
).values_list("data_source_user_id", flat=True)

# 【审计】创建审计对象并记录变更前的数据
auditor = TenantUserDepartmentRelationsAuditor(
operator=request.user.username, tenant_id=cur_tenant_id, data_source_user_ids=data_source_user_ids
)
auditor.pre_record_data_before()

# 复制操作:为数据源部门 & 用户添加关联边,但是不会影响存量的关联边
relations = [
DataSourceDepartmentUserRelation(user_id=user_id, department_id=dept_id, data_source=data_source)
Expand All @@ -74,6 +81,9 @@ def post(self, request, *args, **kwargs):
# 由于复制操作不会影响存量的关联边,所以需要忽略冲突,避免出现用户复选的情况
DataSourceDepartmentUserRelation.objects.bulk_create(relations, ignore_conflicts=True)

# 【审计】将审计记录保存至数据库
auditor.batch_record()

return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down Expand Up @@ -107,6 +117,12 @@ def put(self, request, *args, **kwargs):
id__in=data["user_ids"],
).values_list("data_source_user_id", flat=True)

# 【审计】创建审计对象并记录变更前的数据
auditor = TenantUserDepartmentRelationsAuditor(
operator=request.user.username, tenant_id=cur_tenant_id, data_source_user_ids=data_source_user_ids
)
auditor.pre_record_data_before()

# 移动操作:为数据源部门 & 用户添加关联边,但是会删除这批用户所有的存量关联边
with transaction.atomic():
# 先删除
Expand All @@ -118,6 +134,9 @@ def put(self, request, *args, **kwargs):
]
DataSourceDepartmentUserRelation.objects.bulk_create(relations)

# 【审计】将审计记录保存至数据库
auditor.batch_record(extras={"department_ids": list(data_source_dept_ids)})

return Response(status=status.HTTP_204_NO_CONTENT)

@swagger_auto_schema(
Expand Down Expand Up @@ -147,6 +166,12 @@ def patch(self, request, *args, **kwargs):
id__in=data["user_ids"],
).values_list("data_source_user_id", flat=True)

# 【审计】创建审计对象
auditor = TenantUserDepartmentRelationsAuditor(
operator=request.user.username, tenant_id=cur_tenant_id, data_source_user_ids=data_source_user_ids
)
auditor.pre_record_data_before()

# 移动操作:为数据源部门 & 用户添加关联边,但是会删除这批用户在当前部门的存量关联边
with transaction.atomic():
# 先删除(仅限于指定部门)
Expand All @@ -160,6 +185,9 @@ def patch(self, request, *args, **kwargs):
]
DataSourceDepartmentUserRelation.objects.bulk_create(relations, ignore_conflicts=True)

# 【审计】将审计记录保存至数据库
auditor.batch_record(extras={"department_id": source_data_source_dept.id})

return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down Expand Up @@ -191,8 +219,17 @@ def delete(self, request, *args, **kwargs):
id__in=data["user_ids"],
).values_list("data_source_user_id", flat=True)

# 【审计】创建审计对象
auditor = TenantUserDepartmentRelationsAuditor(
operator=request.user.username, tenant_id=cur_tenant_id, data_source_user_ids=data_source_user_ids
)
auditor.pre_record_data_before()

DataSourceDepartmentUserRelation.objects.filter(
user_id__in=data_source_user_ids, department=source_data_source_dept
).delete()

# 【审计】将审计记录保存至数据库
auditor.batch_record(extras={"department_id": source_data_source_dept.id})

return Response(status=status.HTTP_204_NO_CONTENT)
Loading