Skip to content

Commit

Permalink
perf: optimize user operation logs (jumpserver#13221)
Browse files Browse the repository at this point in the history
  • Loading branch information
O-Jiangweidong authored May 31, 2024
1 parent cdfb115 commit dfd133c
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 10 deletions.
2 changes: 1 addition & 1 deletion apps/audits/backends/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def _get_special_handler(resource_type):
resource_map = {
'Asset permission': lambda k, v: ActionChoices.display(int(v)) if k == 'Actions' else v
}
return resource_map.get(resource_type, lambda k, v: v)
return resource_map.get(resource_type, lambda k, v: _(v))

@classmethod
def convert_diff_friendly(cls, op_log):
Expand Down
3 changes: 3 additions & 0 deletions apps/audits/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class ActionChoices(TextChoices):
approve = 'approve', _('Approve')
close = 'close', _('Close')

# Custom action
finished = 'finished', _('Finished')


class LoginTypeChoices(TextChoices):
web = "W", _("Web")
Expand Down
2 changes: 1 addition & 1 deletion apps/audits/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def cache_instance_before_data(self, instance_dict):
return

key = '%s_%s' % (self.CACHE_KEY, instance_id)
cache.set(key, instance_dict, 3 * 60)
cache.set(key, instance_dict, 3)

def get_instance_dict_from_cache(self, instance_id):
if instance_id is None:
Expand Down
2 changes: 2 additions & 0 deletions apps/audits/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ class Meta:


class UserSession(models.Model):
_OPERATE_LOG_ACTION = {'delete': ActionChoices.finished}

id = models.UUIDField(default=uuid.uuid4, primary_key=True)
ip = models.GenericIPAddressField(verbose_name=_("Login IP"))
key = models.CharField(max_length=128, verbose_name=_("Session key"))
Expand Down
25 changes: 18 additions & 7 deletions apps/audits/signal_handlers/operate_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import uuid

from django.apps import apps
from django.db.models.signals import post_save, pre_save, m2m_changed, pre_delete
from django.db.models.signals import (
pre_delete, pre_save, m2m_changed, post_delete, post_save
)
from django.dispatch import receiver
from django.utils import translation

Expand Down Expand Up @@ -94,7 +96,7 @@ def signal_of_operate_log_whether_continue(
return condition


@receiver(pre_save)
@receiver([pre_save, pre_delete])
def on_object_pre_create_or_update(
sender, instance=None, raw=False, using=None, update_fields=None, **kwargs
):
Expand All @@ -103,6 +105,7 @@ def on_object_pre_create_or_update(
)
if not ok:
return

with translation.override('en'):
# users.PrivateToken Model 没有 id 有 pk字段
instance_id = getattr(instance, 'id', getattr(instance, 'pk', None))
Expand Down Expand Up @@ -145,17 +148,23 @@ def on_object_created_or_update(
)


@receiver(pre_delete)
@receiver(post_delete)
def on_object_delete(sender, instance=None, **kwargs):
ok = signal_of_operate_log_whether_continue(sender, instance, False)
if not ok:
return

with translation.override('en'):
resource_type = sender._meta.verbose_name
action = getattr(sender, '_OPERATE_LOG_ACTION', {})
action = action.get('delete', ActionChoices.delete)
instance_id = getattr(instance, 'id', getattr(instance, 'pk', None))
log_id, before = get_instance_dict_from_cache(instance_id)
if not log_id:
log_id, before = None, model_to_dict(instance)
create_or_update_operate_log(
ActionChoices.delete, resource_type,
resource=instance, before=model_to_dict(instance)
action, resource_type, log_id=log_id,
resource=instance, before=before,
)


Expand All @@ -166,7 +175,7 @@ def on_django_start_set_operate_log_monitor_models(sender, **kwargs):
'django_celery_beat', 'contenttypes', 'sessions', 'auth',
}
exclude_models = {
'UserPasswordHistory', 'ContentType',
'UserPasswordHistory', 'ContentType', 'Asset',
'MessageContent', 'SiteMessage',
'PlatformAutomation', 'PlatformProtocol', 'Protocol',
'HistoricalAccount', 'GatheredUser', 'ApprovalRule',
Expand All @@ -180,11 +189,13 @@ def on_django_start_set_operate_log_monitor_models(sender, **kwargs):
'ApplyCommandTicket', 'ApplyLoginAssetTicket',
'FavoriteAsset',
}
include_models = {'UserSession'}
for i, app in enumerate(apps.get_models(), 1):
app_name = app._meta.app_label
model_name = app._meta.object_name
if app_name in exclude_apps or \
model_name in exclude_models or \
model_name.endswith('Execution'):
continue
if model_name not in include_models:
continue
MODELS_NEED_RECORD.add(model_name)
8 changes: 7 additions & 1 deletion apps/audits/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,15 @@ def _get_instance_field_value(
continue

value = getattr(instance, f.name, None) or getattr(instance, f.attname, None)
if not isinstance(value, bool) and not value:
if not isinstance(value, (bool, int)) and not value:
continue

choices = getattr(f, 'choices', []) or []
for c_value, c_label in choices:
if c_value == value:
value = c_label
break

if getattr(f, 'primary_key', False):
f.verbose_name = 'id'
elif isinstance(value, list):
Expand Down
1 change: 1 addition & 0 deletions apps/users/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def set_public_key(self, public_key):
if self.can_update_ssh_key():
self.public_key = public_key
self.save()
post_user_change_password.send(self.__class__, user=self)

def can_update_password(self):
return self.is_local
Expand Down
5 changes: 5 additions & 0 deletions apps/users/serializers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from rbac.builtin import BuiltinRole
from rbac.models import OrgRoleBinding, SystemRoleBinding, Role
from rbac.permissions import RBACPermission
from users.signals import post_user_change_password
from ..const import PasswordStrategy
from ..models import User

Expand Down Expand Up @@ -268,13 +269,17 @@ def update(self, instance, validated_data):
instance = self.save_and_set_custom_m2m_fields(
validated_data, save_handler, created=False
)
if validated_data.get('public_key'):
post_user_change_password.send(instance.__class__, user=instance)
return instance

def create(self, validated_data):
save_handler = super().create
instance = self.save_and_set_custom_m2m_fields(
validated_data, save_handler, created=True
)
if validated_data.get('public_key'):
post_user_change_password.send(instance.__class__, user=instance)
return instance

@classmethod
Expand Down

0 comments on commit dfd133c

Please sign in to comment.