From 9a7919f3aca8f15d7ba572dcb5f300d5f7576b70 Mon Sep 17 00:00:00 2001 From: xinwen Date: Fri, 12 Nov 2021 15:33:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E5=85=AC=E9=92=A5?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=8D=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_msg_rest_public_key_success.html | 14 ++ apps/locale/zh/LC_MESSAGES/django.po | 219 ++++++++++-------- apps/users/api/profile.py | 7 +- apps/users/notifications.py | 32 +++ 4 files changed, 169 insertions(+), 103 deletions(-) create mode 100644 apps/authentication/templates/authentication/_msg_rest_public_key_success.html diff --git a/apps/authentication/templates/authentication/_msg_rest_public_key_success.html b/apps/authentication/templates/authentication/_msg_rest_public_key_success.html new file mode 100644 index 000000000..a95bfdd9b --- /dev/null +++ b/apps/authentication/templates/authentication/_msg_rest_public_key_success.html @@ -0,0 +1,14 @@ +{% load i18n %} +

{% trans 'Hello' %} {{ name }},

+ +

+ {% trans 'Your public key has just been successfully updated' %} +

+

+ {% trans 'IP' %}: {{ ip_address }}
+ {% trans 'Browser' %}: {{ browser }} +

+

+ {% trans 'If the public key update was not initiated by you, your account may have security issues' %}
+ {% trans 'If you have any questions, you can contact the administrator' %} +

diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 2b057ff8f..0b4d4b4be 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-10 17:18+0800\n" +"POT-Creation-Date: 2021-11-12 15:28+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -52,7 +52,7 @@ msgid "Active" msgstr "激活中" #: acls/models/base.py:32 applications/models/application.py:179 -#: assets/models/asset.py:144 assets/models/asset.py:220 +#: assets/models/asset.py:144 assets/models/asset.py:232 #: assets/models/base.py:180 assets/models/cluster.py:29 #: assets/models/cmd_filter.py:23 assets/models/cmd_filter.py:64 #: assets/models/domain.py:25 assets/models/domain.py:65 @@ -128,7 +128,7 @@ msgstr "系统用户" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:37 -#: assets/models/asset.py:357 assets/models/authbook.py:18 +#: assets/models/asset.py:350 assets/models/authbook.py:18 #: assets/models/gathered_user.py:14 assets/serializers/system_user.py:258 #: audits/models.py:38 perms/models/asset_permission.py:99 #: templates/index.html:82 terminal/backends/command/models.py:19 @@ -192,16 +192,17 @@ msgstr "" #: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:32 #: applications/serializers/attrs/application_type/mysql_workbench.py:18 -#: assets/models/asset.py:180 assets/models/domain.py:61 +#: assets/models/asset.py:211 assets/models/domain.py:61 #: assets/serializers/account.py:12 #: authentication/templates/authentication/_msg_rest_password_success.html:8 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:8 #: settings/serializers/terminal.py:8 #: users/templates/users/_granted_assets.html:26 #: users/templates/users/user_asset_permission.html:156 msgid "IP" msgstr "IP" -#: acls/serializers/login_asset_acl.py:35 assets/models/asset.py:181 +#: acls/serializers/login_asset_acl.py:35 assets/models/asset.py:212 #: assets/serializers/account.py:13 assets/serializers/gathered_user.py:23 #: settings/serializers/terminal.py:7 #: users/templates/users/_granted_assets.html:25 @@ -215,7 +216,7 @@ msgid "" "options: {}" msgstr "格式为逗号分隔的字符串, * 表示匹配所有. 可选的协议有: {}" -#: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:184 +#: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:214 #: assets/models/domain.py:63 assets/models/user.py:200 #: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 msgid "Protocol" @@ -323,7 +324,7 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: applications/models/application.py:175 assets/models/asset.py:188 +#: applications/models/application.py:175 assets/models/asset.py:218 #: assets/models/domain.py:30 assets/models/domain.py:64 msgid "Domain" msgstr "网域" @@ -375,7 +376,7 @@ msgstr "主机" #: applications/serializers/attrs/application_type/mysql_workbench.py:22 #: applications/serializers/attrs/application_type/oracle.py:11 #: applications/serializers/attrs/application_type/pgsql.py:11 -#: assets/models/asset.py:185 assets/models/domain.py:62 +#: assets/models/asset.py:215 assets/models/domain.py:62 #: settings/serializers/auth/radius.py:15 #: xpack/plugins/cloud/serializers/account_attrs.py:61 msgid "Port" @@ -463,103 +464,103 @@ msgstr "元数据" msgid "Internal" msgstr "内部的" -#: assets/models/asset.py:163 assets/models/asset.py:187 +#: assets/models/asset.py:163 assets/models/asset.py:217 #: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:43 msgid "Platform" msgstr "系统平台" -#: assets/models/asset.py:186 assets/serializers/asset.py:67 +#: assets/models/asset.py:169 +msgid "Vendor" +msgstr "制造商" + +#: assets/models/asset.py:170 +msgid "Model" +msgstr "型号" + +#: assets/models/asset.py:171 +msgid "Serial number" +msgstr "序列号" + +#: assets/models/asset.py:173 +msgid "CPU model" +msgstr "CPU型号" + +#: assets/models/asset.py:174 +msgid "CPU count" +msgstr "CPU数量" + +#: assets/models/asset.py:175 +msgid "CPU cores" +msgstr "CPU核数" + +#: assets/models/asset.py:176 +msgid "CPU vcpus" +msgstr "CPU总数" + +#: assets/models/asset.py:177 +msgid "Memory" +msgstr "内存" + +#: assets/models/asset.py:178 +msgid "Disk total" +msgstr "硬盘大小" + +#: assets/models/asset.py:179 +msgid "Disk info" +msgstr "硬盘信息" + +#: assets/models/asset.py:181 +msgid "OS" +msgstr "操作系统" + +#: assets/models/asset.py:182 +msgid "OS version" +msgstr "系统版本" + +#: assets/models/asset.py:183 +msgid "OS arch" +msgstr "系统架构" + +#: assets/models/asset.py:184 +msgid "Hostname raw" +msgstr "主机名原始" + +#: assets/models/asset.py:216 assets/serializers/asset.py:67 #: perms/serializers/asset/user_permission.py:41 #: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:42 msgid "Protocols" msgstr "协议组" -#: assets/models/asset.py:189 assets/models/user.py:190 +#: assets/models/asset.py:219 assets/models/user.py:190 #: perms/models/asset_permission.py:100 #: xpack/plugins/change_auth_plan/models/asset.py:44 #: xpack/plugins/gathered_user/models.py:24 msgid "Nodes" msgstr "节点" -#: assets/models/asset.py:190 assets/models/cmd_filter.py:22 +#: assets/models/asset.py:220 assets/models/cmd_filter.py:22 #: assets/models/domain.py:66 assets/models/label.py:22 msgid "Is active" msgstr "激活" -#: assets/models/asset.py:193 assets/models/cluster.py:19 +#: assets/models/asset.py:223 assets/models/cluster.py:19 #: assets/models/user.py:187 assets/models/user.py:340 templates/_nav.html:44 msgid "Admin user" msgstr "特权用户" -#: assets/models/asset.py:196 +#: assets/models/asset.py:226 msgid "Public IP" msgstr "公网IP" -#: assets/models/asset.py:197 +#: assets/models/asset.py:227 msgid "Asset number" msgstr "资产编号" -#: assets/models/asset.py:200 -msgid "Vendor" -msgstr "制造商" - -#: assets/models/asset.py:201 -msgid "Model" -msgstr "型号" - -#: assets/models/asset.py:202 -msgid "Serial number" -msgstr "序列号" - -#: assets/models/asset.py:204 -msgid "CPU model" -msgstr "CPU型号" - -#: assets/models/asset.py:205 -msgid "CPU count" -msgstr "CPU数量" - -#: assets/models/asset.py:206 -msgid "CPU cores" -msgstr "CPU核数" - -#: assets/models/asset.py:207 -msgid "CPU vcpus" -msgstr "CPU总数" - -#: assets/models/asset.py:208 -msgid "Memory" -msgstr "内存" - -#: assets/models/asset.py:209 -msgid "Disk total" -msgstr "硬盘大小" - -#: assets/models/asset.py:210 -msgid "Disk info" -msgstr "硬盘信息" - -#: assets/models/asset.py:212 -msgid "OS" -msgstr "操作系统" - -#: assets/models/asset.py:213 -msgid "OS version" -msgstr "系统版本" - -#: assets/models/asset.py:214 -msgid "OS arch" -msgstr "系统架构" - -#: assets/models/asset.py:215 -msgid "Hostname raw" -msgstr "主机名原始" - -#: assets/models/asset.py:217 templates/_nav.html:46 +#: assets/models/asset.py:229 templates/_nav.html:46 msgid "Labels" msgstr "标签管理" -#: assets/models/asset.py:218 assets/models/base.py:183 +#: assets/models/asset.py:230 assets/models/base.py:183 #: assets/models/cluster.py:28 assets/models/cmd_filter.py:26 #: assets/models/cmd_filter.py:67 assets/models/group.py:21 #: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:25 @@ -570,7 +571,7 @@ msgstr "标签管理" msgid "Created by" msgstr "创建者" -#: assets/models/asset.py:219 assets/models/base.py:181 +#: assets/models/asset.py:231 assets/models/base.py:181 #: assets/models/cluster.py:26 assets/models/domain.py:27 #: assets/models/gathered_user.py:19 assets/models/group.py:22 #: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50 @@ -875,19 +876,14 @@ msgstr "协议重复: {}" msgid "Domain name" msgstr "网域名称" -#: assets/serializers/asset.py:69 +#: assets/serializers/asset.py:70 msgid "Nodes name" msgstr "节点名称" -#: assets/serializers/asset.py:103 +#: assets/serializers/asset.py:104 msgid "Hardware info" msgstr "硬件信息" -#: assets/serializers/asset.py:104 assets/serializers/system_user.py:276 -#: orgs/mixins/serializers.py:26 -msgid "Org name" -msgstr "组织名称" - #: assets/serializers/asset.py:105 msgid "Admin user display" msgstr "特权用户名称" @@ -988,6 +984,10 @@ msgstr "仅允许自动登录的系统用户" msgid "System user name" msgstr "系统用户名称" +#: assets/serializers/system_user.py:276 orgs/mixins/serializers.py:26 +msgid "Org name" +msgstr "组织名称" + #: assets/serializers/system_user.py:285 msgid "Asset hostname" msgstr "资产主机名" @@ -1501,7 +1501,7 @@ msgstr "{ApplicationPermission} 添加 {SystemUser}" msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 移除 {SystemUser}" -#: authentication/api/connection_token.py:239 +#: authentication/api/connection_token.py:248 msgid "Invalid token" msgstr "无效的令牌" @@ -1880,6 +1880,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_different_city.html:3 #: authentication/templates/authentication/_msg_reset_password.html:3 #: authentication/templates/authentication/_msg_rest_password_success.html:2 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:2 #: jumpserver/conf.py:269 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 @@ -1929,6 +1930,7 @@ msgid "Your password has just been successfully updated" msgstr "你的密码刚刚成功更新" #: authentication/templates/authentication/_msg_rest_password_success.html:9 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:9 msgid "Browser" msgstr "浏览器" @@ -1939,9 +1941,20 @@ msgid "" msgstr "如果这次密码更新不是由你发起的,那么你的账号可能存在安全问题" #: authentication/templates/authentication/_msg_rest_password_success.html:13 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:13 msgid "If you have any questions, you can contact the administrator" msgstr "如果有疑问或需求,请联系系统管理员" +#: authentication/templates/authentication/_msg_rest_public_key_success.html:5 +msgid "Your public key has just been successfully updated" +msgstr "你的公钥刚刚成功更新" + +#: authentication/templates/authentication/_msg_rest_public_key_success.html:12 +msgid "" +"If the public key update was not initiated by you, your account may have " +"security issues" +msgstr "如果这次公钥更新不是由你发起的,那么你的账号可能存在安全问题" + #: authentication/templates/authentication/login.html:143 msgid "Welcome back, please enter username and password to login" msgstr "欢迎回来,请输入用户名和密码登录" @@ -3262,7 +3275,9 @@ msgstr "显示未分组节点" #: settings/serializers/other.py:30 msgid "Perm single to ungroup node" -msgstr "放置单独授权的资产到未分组节点, 避免能看到资产所在节点,但该节点未被授权的问题" +msgstr "" +"放置单独授权的资产到未分组节点, 避免能看到资产所在节点,但该节点未被授权的问" +"题" #: settings/serializers/other.py:34 msgid "Help Docs URL" @@ -3280,14 +3295,6 @@ msgstr "支持链接" msgid "default: http://www.jumpserver.org/support/" msgstr "默认: http://www.jumpserver.org/support/" -#: settings/serializers/other.py:44 -msgid "Help Website URL" -msgstr "官网链接" - -#: settings/serializers/other.py:45 -msgid "default: http://www.jumpserver.org" -msgstr "如: http://dev.jumpserver.org:8080" - #: settings/serializers/security.py:8 msgid "Password minimum length" msgstr "密码最小长度" @@ -5064,19 +5071,23 @@ msgstr "重置密码" msgid "Reset password success" msgstr "重置密码成功" -#: users/notifications.py:111 +#: users/notifications.py:117 +msgid "Reset public key success" +msgstr "重置公钥成功" + +#: users/notifications.py:143 msgid "Password is about expire" msgstr "密码即将过期" -#: users/notifications.py:139 +#: users/notifications.py:171 msgid "Account is about expire" msgstr "账号即将过期" -#: users/notifications.py:161 +#: users/notifications.py:193 msgid "Reset SSH Key" msgstr "重置 SSH 密钥" -#: users/notifications.py:182 +#: users/notifications.py:214 msgid "Reset MFA" msgstr "重置 MFA" @@ -5523,8 +5534,8 @@ msgstr "* 新密码不能是最近 {} 次的密码" msgid "Reset password success, return to login page" msgstr "重置密码成功,返回到登录页面" -#: xpack/plugins/change_auth_plan/api/app.py:113 -#: xpack/plugins/change_auth_plan/api/asset.py:100 +#: xpack/plugins/change_auth_plan/api/app.py:114 +#: xpack/plugins/change_auth_plan/api/asset.py:101 msgid "The parameter 'action' must be [{}]" msgstr "参数 'action' 必须是 [{}]" @@ -5655,15 +5666,15 @@ msgstr "* 请输入正确的密码长度" msgid "* Password length range 6-30 bits" msgstr "* 密码长度范围 6-30 位" -#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:248 +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:249 msgid "Invalid/incorrect password" msgstr "无效/错误 密码" -#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:250 +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:251 msgid "Failed to connect to the host" msgstr "连接主机失败" -#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:252 +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:253 msgid "Data could not be sent to remote" msgstr "无法将数据发送到远程" @@ -6021,7 +6032,7 @@ msgstr "执行次数" msgid "Instance count" msgstr "实例个数" -#: xpack/plugins/cloud/utils.py:65 +#: xpack/plugins/cloud/utils.py:68 msgid "Account unavailable" msgstr "账户无效" @@ -6109,6 +6120,12 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "Help Website URL" +#~ msgstr "官网链接" + +#~ msgid "default: http://www.jumpserver.org" +#~ msgstr "如: http://dev.jumpserver.org:8080" + #~ msgid "One-time password invalid, or ntp sync server time" #~ msgstr "MFA 验证码不正确,或者服务器端时间不对" diff --git a/apps/users/api/profile.py b/apps/users/api/profile.py index 372ed5809..14aa1d8f6 100644 --- a/apps/users/api/profile.py +++ b/apps/users/api/profile.py @@ -5,7 +5,10 @@ from rest_framework import generics from common.permissions import IsOrgAdmin from rest_framework.permissions import IsAuthenticated -from users.notifications import ResetPasswordMsg, ResetPasswordSuccessMsg, ResetSSHKeyMsg +from users.notifications import ( + ResetPasswordMsg, ResetPasswordSuccessMsg, ResetSSHKeyMsg, + ResetPublicKeySuccessMsg, +) from common.permissions import ( IsCurrentUserOrReadOnly ) @@ -87,4 +90,4 @@ class UserPublicKeyApi(generics.RetrieveUpdateAPIView): def perform_update(self, serializer): super().perform_update(serializer) - ResetPasswordSuccessMsg(self.get_object(), self.request).publish_async() + ResetPublicKeySuccessMsg(self.get_object(), self.request).publish_async() diff --git a/apps/users/notifications.py b/apps/users/notifications.py index d1fbad546..c9e5a0521 100644 --- a/apps/users/notifications.py +++ b/apps/users/notifications.py @@ -105,6 +105,38 @@ class ResetPasswordSuccessMsg(UserMessage): return cls(user, request) +class ResetPublicKeySuccessMsg(UserMessage): + def __init__(self, user, request): + super().__init__(user) + self.ip_address = get_request_ip_or_data(request) + self.browser = get_request_user_agent(request) + + def get_html_msg(self) -> dict: + user = self.user + + subject = _('Reset public key success') + context = { + 'name': user.name, + 'ip_address': self.ip_address, + 'browser': self.browser, + } + message = render_to_string('authentication/_msg_rest_public_key_success.html', context) + return { + 'subject': subject, + 'message': message + } + + @classmethod + def gen_test_msg(cls): + from users.models import User + from rest_framework.test import APIRequestFactory + from rest_framework.request import Request + factory = APIRequestFactory() + request = Request(factory.get('/notes/')) + user = User.objects.first() + return cls(user, request) + + class PasswordExpirationReminderMsg(UserMessage): def get_html_msg(self) -> dict: user = self.user