From bfd84c680ec69a49b25f3bcf957a29566049da58 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 11 Sep 2025 14:14:13 +0800
Subject: [PATCH] perf: Asset user login notify
---
apps/acls/notifications.py | 16 ++++++++++++++--
.../templates/acls/asset_login_reminder.html | 2 ++
.../acls/templates/acls/user_login_reminder.html | 2 ++
apps/authentication/api/connection_token.py | 11 ++++++++---
apps/terminal/api/session/command.py | 3 +++
apps/terminal/notifications.py | 1 +
apps/terminal/serializers/command.py | 2 +-
.../templates/terminal/_msg_command_warning.html | 3 +++
8 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/apps/acls/notifications.py b/apps/acls/notifications.py
index 1dcc6339c..153deae95 100644
--- a/apps/acls/notifications.py
+++ b/apps/acls/notifications.py
@@ -1,4 +1,5 @@
from django.template.loader import render_to_string
+from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from accounts.models import Account
@@ -15,16 +16,21 @@ class UserLoginReminderMsg(UserMessage):
def __init__(self, user, user_log: UserLoginLog, acl: LoginACL):
self.user_log = user_log
self.acl_name = str(acl)
+ self.login_from = user_log.get_type_display()
+ now = timezone.localtime(user_log.datetime)
+ self.time = now.strftime('%Y-%m-%d %H:%M:%S')
super().__init__(user)
def get_html_msg(self) -> dict:
user_log = self.user_log
context = {
'ip': user_log.ip,
+ 'time': self.time,
'city': user_log.city,
- 'username': user_log.username,
'recipient': self.user,
'acl_name': self.acl_name,
+ 'login_from': self.login_from,
+ 'username': user_log.username,
'user_agent': user_log.user_agent,
}
message = render_to_string('acls/user_login_reminder.html', context)
@@ -47,19 +53,25 @@ class AssetLoginReminderMsg(UserMessage):
def __init__(
self, user, asset: Asset, login_user: User,
account: Account, acl: LoginAssetACL,
- ip, input_username
+ ip, input_username, login_from
):
self.ip = ip
self.asset = asset
self.account = account
self.acl_name = str(acl)
+ self.login_from = login_from
self.login_user = login_user
self.input_username = input_username
+
+ now = timezone.localtime(timezone.now())
+ self.time = now.strftime('%Y-%m-%d %H:%M:%S')
super().__init__(user)
def get_html_msg(self) -> dict:
context = {
'ip': self.ip,
+ 'time': self.time,
+ 'login_from': self.login_from,
'recipient': self.user,
'username': self.login_user.username,
'name': self.login_user.name,
diff --git a/apps/acls/templates/acls/asset_login_reminder.html b/apps/acls/templates/acls/asset_login_reminder.html
index 846797f7f..93eb4f263 100644
--- a/apps/acls/templates/acls/asset_login_reminder.html
+++ b/apps/acls/templates/acls/asset_login_reminder.html
@@ -10,6 +10,8 @@
{% trans 'Assets' %}: [{{ asset }}]
{% trans 'Account' %}: [{{ account_name }}({{ account }})]
{% trans 'Login asset acl' %}: [{{ acl_name }}]
+ {% trans 'Login from' %}: [{{ login_from }}]
+ {% trans 'Time' %}: [{{ time }}]
diff --git a/apps/acls/templates/acls/user_login_reminder.html b/apps/acls/templates/acls/user_login_reminder.html
index 826da7bd2..dbd41ce56 100644
--- a/apps/acls/templates/acls/user_login_reminder.html
+++ b/apps/acls/templates/acls/user_login_reminder.html
@@ -8,8 +8,10 @@
{% trans 'User' %}: [{{ username }}]
IP: [{{ ip }}]
{% trans 'Login city' %}: [{{ city }}]
+ {% trans 'Login from' %}: [{{ login_from }}]
{% trans 'User agent' %}: [{{ user_agent }}]
{% trans 'Login acl' %}: [{{ acl_name }}]
+ {% trans 'Time' %}: [{{ time }}]
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 7d802f069..1b0d4050d 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -431,7 +431,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
if account.username != AliasAccount.INPUT:
data['input_username'] = ''
- ticket = self._validate_acl(user, asset, account, connect_method)
+ ticket = self._validate_acl(user, asset, account, connect_method, protocol)
if ticket:
data['from_ticket'] = ticket
@@ -470,7 +470,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
after=after, object_name=object_name
)
- def _validate_acl(self, user, asset, account, connect_method):
+ def _validate_acl(self, user, asset, account, connect_method, protocol):
from acls.models import LoginAssetACL
kwargs = {'user': user, 'asset': asset, 'account': account}
if account.username == AliasAccount.INPUT:
@@ -523,10 +523,15 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
return
self._record_operate_log(acl, asset)
+ os = get_request_os(self.request) if self.request else 'windows'
+ method = ConnectMethodUtil.get_connect_method(
+ connect_method, protocol=protocol, os=os
+ )
+ login_from = method['label'] if method else connect_method
for reviewer in reviewers:
AssetLoginReminderMsg(
reviewer, asset, user, account, acl,
- ip, self.input_username
+ ip, self.input_username, login_from
).publish_async()
def create_face_verify(self, response):
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index 32f67704a..577de474c 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
#
+from datetime import datetime
+
from django.utils import timezone
from rest_framework import generics
from rest_framework.fields import DateTimeField
@@ -216,6 +218,7 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
cmd_group_mapper = {str(i.id): i for i in cmd_groups}
for command in commands:
+ command['_time'] = datetime.fromtimestamp(command['timestamp'])
cmd_acl = acl_mapper.get(command['cmd_filter_acl'])
command['_cmd_filter_acl'] = cmd_acl
cmd_group = cmd_group_mapper.get(command['cmd_group'])
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index a8b298666..e43151060 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -106,6 +106,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
'protocol': command.get('_protocol', ''),
'remote_addr': command.get('_remote_addr', ''),
'login_from': command.get('_login_from', ''),
+ 'time': command.get('_time', ''),
'cmd_filter_acl': cmd_acl_name,
'cmd_group': cmd_group_name,
'risk_level': RiskLevelChoices.get_label(command['risk_level']),
diff --git a/apps/terminal/serializers/command.py b/apps/terminal/serializers/command.py
index eb99c43a0..679cfed06 100644
--- a/apps/terminal/serializers/command.py
+++ b/apps/terminal/serializers/command.py
@@ -46,7 +46,7 @@ class InsecureCommandAlertSerializer(SimpleSessionCommandSerializer):
class Meta(SimpleSessionCommandSerializer.Meta):
fields = SimpleSessionCommandSerializer.Meta.fields + [
- 'cmd_filter_acl', 'cmd_group',
+ 'cmd_filter_acl', 'cmd_group', 'timestamp'
]
def validate(self, attrs):
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
index 4d9d7594d..d3510e9b3 100644
--- a/apps/terminal/templates/terminal/_msg_command_warning.html
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -26,6 +26,9 @@
{% endif %}
{% trans 'Organization' %}: [{{ org }}]
{% trans 'Command' %}: [{{ command }}]
+ {% if time %}
+ {% trans 'Time' %}: [{{ time }}]
+ {% endif %}