diff --git a/apps/audits/api.py b/apps/audits/api.py index 7dc1a5725..209bc30fd 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -41,6 +41,7 @@ from .serializers import ( PasswordChangeLogSerializer, ActivityUnionLogSerializer, FileSerializer, UserSessionSerializer ) +from .utils import construct_userlogin_usernames logger = get_logger(__name__) @@ -126,15 +127,16 @@ class UserLoginCommonMixin: class UserLoginLogViewSet(UserLoginCommonMixin, OrgReadonlyModelViewSet): @staticmethod - def get_org_members(): - users = current_org.get_members().values_list('username', flat=True) + def get_org_member_usernames(): + user_queryset = current_org.get_members() + users = construct_userlogin_usernames(user_queryset) return users def get_queryset(self): queryset = super().get_queryset() if current_org.is_root(): return queryset - users = self.get_org_members() + users = self.get_org_member_usernames() queryset = queryset.filter(username__in=users) return queryset diff --git a/apps/audits/utils.py b/apps/audits/utils.py index 4312962e6..d9728fbbd 100644 --- a/apps/audits/utils.py +++ b/apps/audits/utils.py @@ -4,6 +4,8 @@ from itertools import chain from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.db import models +from django.db.models import F, Value, CharField +from django.db.models.functions import Concat from common.db.fields import RelatedManager from common.utils import validate_ip, get_ip_city, get_logger @@ -115,3 +117,12 @@ def model_to_dict_for_operate_log( get_related_values(f) return data + + +def construct_userlogin_usernames(user_queryset): + usernames_original = user_queryset.values_list('username', flat=True) + usernames_combined = user_queryset.annotate( + usernames_combined_field=Concat(F('name'), Value('('), F('username'), Value(')'), output_field=CharField()) + ).values_list("usernames_combined_field", flat=True) + usernames = list(chain(usernames_original, usernames_combined)) + return usernames diff --git a/apps/authentication/utils.py b/apps/authentication/utils.py index 5fd41aec7..4cb1e7368 100644 --- a/apps/authentication/utils.py +++ b/apps/authentication/utils.py @@ -25,9 +25,10 @@ def check_different_city_login_if_need(user, request): is_private = ipaddress.ip_address(ip).is_private if is_private: return + usernames = [user.username, f"{user.name}({user.username})"] last_user_login = UserLoginLog.objects.exclude( city__in=city_white - ).filter(username=user.username, status=True).first() + ).filter(username__in=usernames, status=True).first() if not last_user_login: return diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py index 63d13df55..cfa6b771d 100644 --- a/apps/jumpserver/api.py +++ b/apps/jumpserver/api.py @@ -17,6 +17,7 @@ from assets.models import Asset from audits.api import OperateLogViewSet from audits.const import LoginStatusChoices from audits.models import UserLoginLog, PasswordChangeLog, OperateLog, FTPLog, JobLog +from audits.utils import construct_userlogin_usernames from common.utils import lazyproperty from common.utils.timezone import local_now, local_zero_hour from ops.const import JobStatus @@ -79,7 +80,7 @@ class DateTimeMixin: if not self.org.is_root(): if query_params == 'username': query = { - f'{query_params}__in': users.values_list('username', flat=True) + f'{query_params}__in': construct_userlogin_usernames(users) } else: query = {