From affa562384de0c17c6301684687b27dbba4039b8 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 10 Oct 2023 17:39:41 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/asset/common.py | 2 +- apps/audits/api.py | 2 ++ apps/audits/models.py | 6 +++- apps/audits/signal_handlers/activity_log.py | 4 ++- apps/users/tasks.py | 36 ++++++++++++++++++--- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index b88d22ce7..ea2be442c 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -159,7 +159,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali return if isinstance(self.initial_data, list): return - accounts = self.initial_data.pop('accounts', None) + accounts = self.initial_data.get('accounts', None) self._accounts = accounts def _get_protocols_required_default(self): diff --git a/apps/audits/api.py b/apps/audits/api.py index 72c1d8a99..17a58b2f2 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -185,6 +185,8 @@ class ResourceActivityAPIView(generics.ListAPIView): 'r_user', 'r_action', 'r_type' ) org_q = Q(org_id=Organization.SYSTEM_ID) | Q(org_id=current_org.id) + if resource_id: + org_q |= Q(org_id='') | Q(org_id=Organization.ROOT_ID) with tmp_to_root_org(): qs1 = self.get_operate_log_qs(fields, limit, org_q, resource_id=resource_id) qs2 = self.get_activity_log_qs(fields, limit, org_q, resource_id=resource_id) diff --git a/apps/audits/models.py b/apps/audits/models.py index 34ec301f2..ff58f962a 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -10,7 +10,7 @@ from django.utils import timezone from django.utils.translation import gettext, gettext_lazy as _ from common.db.encoder import ModelJSONFieldEncoder -from common.utils import lazyproperty +from common.utils import lazyproperty, i18n_trans from ops.models import JobExecution from orgs.mixins.models import OrgModelMixin, Organization from orgs.utils import current_org @@ -155,6 +155,10 @@ class ActivityLog(OrgModelMixin): verbose_name = _("Activity log") ordering = ('-datetime',) + def __str__(self): + detail = i18n_trans(self.detail) + return "{} {}".format(detail, self.resource_id) + def save(self, *args, **kwargs): if current_org.is_root() and not self.org_id: self.org_id = Organization.ROOT_ID diff --git a/apps/audits/signal_handlers/activity_log.py b/apps/audits/signal_handlers/activity_log.py index 4b41d2d1d..a391f0007 100644 --- a/apps/audits/signal_handlers/activity_log.py +++ b/apps/audits/signal_handlers/activity_log.py @@ -69,7 +69,9 @@ class ActivityLogHandler: def create_activities(resource_ids, detail, detail_id, action, org_id): if not resource_ids: - return + raise ValueError('resource_ids is empty') + if not org_id: + org_id = Organization.ROOT_ID activities = [ ActivityLog( resource_id=getattr(resource_id, 'pk', resource_id), diff --git a/apps/users/tasks.py b/apps/users/tasks.py index add7a9ed7..ecc59c3bc 100644 --- a/apps/users/tasks.py +++ b/apps/users/tasks.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- # +import uuid from datetime import timedelta -from celery import shared_task +from celery import shared_task, current_task from django.conf import settings +from django.db.models import Q from django.utils import timezone -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext_lazy as _, gettext_noop +from audits.const import ActivityChoices from common.const.crontab import CRONTAB_AT_AM_TEN, CRONTAB_AT_PM_TWO from common.utils import get_logger -from common.utils.timezone import utc_now from ops.celery.decorator import after_app_ready_start, register_as_period_task from ops.celery.utils import create_or_update_celery_periodic_tasks from orgs.utils import tmp_to_root_org @@ -85,5 +87,29 @@ def check_user_expired_periodic(): def check_unused_users(): uncommon_users_ttl = settings.SECURITY_UNCOMMON_USERS_TTL seconds_to_subtract = uncommon_users_ttl * 24 * 60 * 60 - t = utc_now() - timedelta(seconds=seconds_to_subtract) - User.objects.filter(last_login__lte=t).update(is_active=False) + t = timezone.now() - timedelta(seconds=seconds_to_subtract) + last_login_q = Q(last_login__lte=t) | Q(last_login__isnull=True) + api_key_q = Q(date_api_key_last_used__lte=t) | Q(date_api_key_last_used__isnull=True) + + users = User.objects \ + .filter(date_joined__lt=t) \ + .filter(is_active=True) \ + .filter(last_login_q) \ + .filter(api_key_q) + + if not users: + return + print("Some users are not used for a long time, and they will be disabled.") + resource_ids = [] + for user in users: + resource_ids.append(user.id) + print(' - {}'.format(user.name)) + + users.update(is_active=False) + from audits.signal_handlers import create_activities + if current_task: + task_id = current_task.request.id + else: + task_id = str(uuid.uuid4()) + detail = gettext_noop('The user has not logged in recently and has been disabled.') + create_activities(resource_ids, detail, task_id, action=ActivityChoices.task, org_id='')