perf: 优化 audit log

pull/9528/head
ibuler 2023-02-13 19:42:42 +08:00
parent e88cb71d3c
commit bd9b1f1a5b
7 changed files with 62 additions and 39 deletions

View File

@ -63,7 +63,7 @@ class DatabaseTypes(BaseType):
cls.SQLSERVER: [{'name': 'SQLServer'}], cls.SQLSERVER: [{'name': 'SQLServer'}],
cls.CLICKHOUSE: [{'name': 'ClickHouse'}], cls.CLICKHOUSE: [{'name': 'ClickHouse'}],
cls.MONGODB: [{'name': 'MongoDB'}], cls.MONGODB: [{'name': 'MongoDB'}],
cls.REDIS: [{'name': 'Redis'}], cls.REDIS: [{'name': 'Redis'}, {'name': 'Redis6+'}],
} }
@classmethod @classmethod

View File

@ -96,6 +96,9 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 6379, 'port': 6379,
'required': True, 'required': True,
'secret_types': ['password'], 'secret_types': ['password'],
'setting': {
'auth_username': True,
}
}, },
} }

View File

@ -38,6 +38,10 @@ class ProtocolSettingSerializer(serializers.Serializer):
) )
script = serializers.JSONField(default=list, label=_("Script")) script = serializers.JSONField(default=list, label=_("Script"))
# Redis
auth_username = serializers.BooleanField(default=False, label=_("Auth with username"),
help_text=_("Auth with username"))
class PlatformAutomationSerializer(serializers.ModelSerializer): class PlatformAutomationSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -4,18 +4,18 @@ from celery import signals
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from audits.models import ActivityLog
from assets.models import Asset, Node
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from accounts.models import AccountBackupAutomation from accounts.models import AccountBackupAutomation
from assets.models import Asset, Node
from audits.models import ActivityLog
from common.utils import get_object_or_none from common.utils import get_object_or_none
from jumpserver.utils import current_request
from ops.celery import app from ops.celery import app
from orgs.utils import tmp_to_root_org from orgs.utils import tmp_to_root_org
from terminal.models import Session from terminal.models import Session
from users.models import User from users.models import User
from jumpserver.utils import current_request
from ..const import ActivityChoices from ..const import ActivityChoices
from ..models import UserLoginLog
class ActivityLogHandler(object): class ActivityLogHandler(object):
@ -118,8 +118,8 @@ class ActivityLogHandler(object):
@staticmethod @staticmethod
def login_log_for_activity(obj): def login_log_for_activity(obj):
login_status = _('Success') if obj.status else _('Failed') login_status = _('Success') if obj.status else _('Failed')
detail = _('User {} login into this service.[{}]').format( detail = _('User {} login this system {}').format(
obj.username, login_status obj.name, login_status
) )
user_id = User.objects.filter(username=obj.username).values('id').first() user_id = User.objects.filter(username=obj.username).values('id').first()
return user_id['id'], detail, ActivityChoices.login_log return user_id['id'], detail, ActivityChoices.login_log
@ -164,12 +164,11 @@ def on_celery_task_pre_run_for_activity_log(task_id='', **kwargs):
activities.append( activities.append(
ActivityLog(id=activity_id, detail_id=task_id) ActivityLog(id=activity_id, detail_id=task_id)
) )
ActivityLog.objects.bulk_update(activities, ('detail_id', )) ActivityLog.objects.bulk_update(activities, ('detail_id',))
@post_save.connect def on_session_or_login_log_created(
def on_object_created( sender, instance=None, created=False, **kwargs
sender, instance=None, created=False, update_fields=None, **kwargs
): ):
handler_mapping = { handler_mapping = {
'Session': activity_handler.session_for_activity, 'Session': activity_handler.session_for_activity,
@ -179,12 +178,13 @@ def on_object_created(
if not created or model_name not in handler_mapping: if not created or model_name not in handler_mapping:
return return
resource_id, detail, a_type = handler_mapping[model_name](instance) resource_id, detail, act_type = handler_mapping[model_name](instance)
ActivityLog.objects.create( ActivityLog.objects.create(
resource_id=resource_id, type=a_type, resource_id=resource_id, type=act_type,
detail=detail, detail_id=instance.id detail=detail, detail_id=instance.id
) )
for sender in [Session, UserLoginLog]:
post_save.connect(on_session_or_login_log_created, sender=sender)

View File

@ -1765,7 +1765,7 @@ msgid "User {} has executed change auth plan for this account.({})"
msgstr "ユーザー {} はこのアカウントのために改密計画を実行しました。({})" msgstr "ユーザー {} はこのアカウントのために改密計画を実行しました。({})"
#: audits/handler.py:168 #: audits/handler.py:168
msgid "User {} login into this service.[{}]" msgid "User [{}] login this system.[{}]"
msgstr "ユーザー {} がサービスにログインしました。[{}]" msgstr "ユーザー {} がサービスにログインしました。[{}]"
#: audits/models.py:32 audits/models.py:59 audits/models.py:101 #: audits/models.py:32 audits/models.py:59 audits/models.py:101

View File

@ -1752,7 +1752,7 @@ msgid "User {} has executed change auth plan for this account.({})"
msgstr "用户 {} 为这个账号执行了改密计划.({})" msgstr "用户 {} 为这个账号执行了改密计划.({})"
#: audits/handler.py:168 #: audits/handler.py:168
msgid "User {} login into this service.[{}]" msgid "User [{}] login this system.[{}]"
msgstr "用户 {} 登录了服务.[{}]" msgstr "用户 {} 登录了服务.[{}]"
#: audits/models.py:32 audits/models.py:59 audits/models.py:101 #: audits/models.py:32 audits/models.py:59 audits/models.py:101

View File

@ -4,12 +4,13 @@ from collections import defaultdict
from functools import partial from functools import partial
from django.conf import settings from django.conf import settings
from django.db.models.signals import post_save, pre_delete, m2m_changed from django.db.models.signals import post_save, pre_delete, m2m_changed, post_delete
from django.db.utils import ProgrammingError, OperationalError from django.db.utils import ProgrammingError, OperationalError
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.functional import LazyObject from django.utils.functional import LazyObject
from common.const.signals import PRE_REMOVE, POST_REMOVE from common.const.signals import PRE_REMOVE, POST_REMOVE
from common.decorators import delay_run
from common.decorators import on_transaction_commit from common.decorators import on_transaction_commit
from common.signals import django_ready from common.signals import django_ready
from common.utils import get_logger from common.utils import get_logger
@ -51,9 +52,21 @@ def subscribe_orgs_mapping_expire(sender, **kwargs):
) )
@delay_run(ttl=5)
def expire_user_orgs(*args):
User.expire_users_rbac_perms_cache()
@receiver(post_save, sender=Organization)
def on_org_create(sender, instance, created=False, **kwargs):
if created:
return
expire_user_orgs()
# 创建对应的root # 创建对应的root
@receiver(post_save, sender=Organization) @receiver(post_save, sender=Organization)
def on_org_create_or_update(sender, instance, created=False, **kwargs): def on_org_create_or_update(sender, instance, **kwargs):
# 必须放到最开始, 因为下面调用Node.save方法时会获取当前组织的org_id(即instance.org_id), 如果不过期会找不到 # 必须放到最开始, 因为下面调用Node.save方法时会获取当前组织的org_id(即instance.org_id), 如果不过期会找不到
expire_orgs_mapping_for_memory(instance.id) expire_orgs_mapping_for_memory(instance.id)
@ -77,7 +90,26 @@ def on_org_delete(sender, instance, **kwargs):
root_node.delete() root_node.delete()
def _remove_users(model, users, org, user_field_name='users'): @receiver(post_delete, sender=Organization)
def on_org_delete(sender, instance, **kwargs):
expire_user_orgs()
@receiver(post_save, sender=User)
@on_transaction_commit
def on_user_created_set_default_org(sender, instance, created, **kwargs):
if not instance.id:
# 用户已被手动删除instance.orgs 时会使用 id 进行查找报错所以判断不存在id时不做处理
return
if not created:
return
if instance.orgs.count() > 0:
return
with tmp_to_org(Organization.default()):
Organization.default().add_member(instance)
def _remove_user_resource(model, users, org, user_field_name='users'):
with tmp_to_org(org): with tmp_to_org(org):
if not isinstance(users, (tuple, list, set)): if not isinstance(users, (tuple, list, set)):
users = (users,) users = (users,)
@ -103,8 +135,8 @@ def _remove_users(model, users, org, user_field_name='users'):
objects = model.objects.filter(id__in=object_id_user_ids_map.keys()) objects = model.objects.filter(id__in=object_id_user_ids_map.keys())
send_m2m_change_signal = partial( send_m2m_change_signal = partial(
m2m_changed.send, m2m_changed.send, sender=m2m_model, reverse=reverse,
sender=m2m_model, reverse=reverse, model=User, using=model.objects.db model=User, using=model.objects.db
) )
for obj in objects: for obj in objects:
@ -126,7 +158,7 @@ def _remove_users(model, users, org, user_field_name='users'):
def _clear_users_from_org(org, users): def _clear_users_from_org(org, users):
""" """
清理用户在该组织下的相关数据 清理用户在该组织下的相关数据, 包括用户组, 资产授权, 用户授权
""" """
if not users: if not users:
return return
@ -134,23 +166,7 @@ def _clear_users_from_org(org, users):
models = (AssetPermission, UserGroup) models = (AssetPermission, UserGroup)
for m in models: for m in models:
_remove_users(m, users, org) _remove_user_resource(m, users, org)
# _remove_users(CommandFilterRule, users, org, user_field_name='reviewers')
@receiver(post_save, sender=User)
@on_transaction_commit
def on_user_created_set_default_org(sender, instance, created, **kwargs):
if not instance.id:
# 用户已被手动删除instance.orgs 时会使用 id 进行查找报错所以判断不存在id时不做处理
return
if not created:
return
if instance.orgs.count() > 0:
return
with tmp_to_org(Organization.default()):
Organization.default().add_member(instance)
@receiver(post_user_leave_org) @receiver(post_user_leave_org)