From c8aa9d006fffa355dbbcac90d766f0bae12b5b20 Mon Sep 17 00:00:00 2001 From: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Date: Fri, 22 Mar 2019 09:42:39 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[Update]=20=E6=9B=B4=E6=96=B0=E7=BF=BB?= =?UTF-8?q?=E8=AF=91(=E6=94=B9=E5=AF=86=E8=AE=A1=E5=88=92)=20(#2525)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Update] 更新翻译(添加改密计划) * [Update] 更新翻译(改密计划) * [Update] 更新翻译 * [Update] 更新翻译 --- apps/locale/zh/LC_MESSAGES/django.mo | Bin 65797 -> 68283 bytes apps/locale/zh/LC_MESSAGES/django.po | 309 ++++++++++++++++++++++++--- 2 files changed, 285 insertions(+), 24 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 9a76261e5fb57336baa515524c191fac18d915ed..d7aec5ea3a1fe486ea147cfa3b862e18c9560189 100644 GIT binary patch delta 22076 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 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 95166b087..5d3ecafdb 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Jumpserver 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-19 14:59+0800\n" +"POT-Creation-Date: 2019-03-22 00:30+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: Jumpserver team\n" @@ -33,6 +33,7 @@ msgstr "测试节点下资产是否可连接: {}" #: assets/templates/assets/asset_detail.html:194 #: assets/templates/assets/asset_detail.html:202 #: assets/templates/assets/system_user_asset.html:95 perms/models.py:31 +#: xpack/plugins/change_auth_plan/models.py:67 msgid "Nodes" msgstr "节点管理" @@ -72,6 +73,9 @@ msgstr "网域" #: perms/templates/perms/asset_permission_list.html:57 #: perms/templates/perms/asset_permission_list.html:78 #: perms/templates/perms/asset_permission_list.html:128 +#: xpack/plugins/change_auth_plan/forms.py:36 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:55 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:15 #: xpack/plugins/cloud/models.py:123 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:63 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:66 @@ -98,6 +102,8 @@ msgstr "如果有多个的互相隔离的网络,设置资产属于的网域, #: assets/forms/asset.py:92 assets/forms/asset.py:96 assets/forms/domain.py:17 #: assets/forms/label.py:15 #: perms/templates/perms/asset_permission_asset.html:88 +#: xpack/plugins/change_auth_plan/forms.py:32 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:84 msgid "Select assets" msgstr "选择资产" @@ -119,6 +125,13 @@ msgstr "选择资产" #: terminal/templates/terminal/command_list.html:73 #: terminal/templates/terminal/session_list.html:41 #: terminal/templates/terminal/session_list.html:72 +#: xpack/plugins/change_auth_plan/forms.py:30 +#: xpack/plugins/change_auth_plan/models.py:63 +#: xpack/plugins/change_auth_plan/models.py:417 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:40 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:54 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:13 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14 #: xpack/plugins/cloud/models.py:187 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:65 #: xpack/plugins/orgs/templates/orgs/org_list.html:16 @@ -157,7 +170,7 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC" #: settings/templates/settings/replay_storage_create.html:44 #: settings/templates/settings/terminal_setting.html:80 #: settings/templates/settings/terminal_setting.html:102 terminal/models.py:22 -#: terminal/models.py:233 terminal/templates/terminal/terminal_detail.html:43 +#: terminal/models.py:241 terminal/templates/terminal/terminal_detail.html:43 #: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14 #: users/models/user.py:54 users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_detail.html:63 @@ -166,6 +179,10 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC" #: users/templates/users/user_list.html:23 #: users/templates/users/user_profile.html:51 #: users/templates/users/user_pubkey_update.html:53 +#: xpack/plugins/change_auth_plan/forms.py:102 +#: xpack/plugins/change_auth_plan/models.py:56 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:61 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:12 #: xpack/plugins/cloud/models.py:49 xpack/plugins/cloud/models.py:119 #: xpack/plugins/cloud/templates/cloud/account_detail.html:52 #: xpack/plugins/cloud/templates/cloud/account_list.html:12 @@ -193,6 +210,8 @@ msgstr "名称" #: users/templates/users/user_detail.html:67 #: users/templates/users/user_list.html:24 #: users/templates/users/user_profile.html:47 +#: xpack/plugins/change_auth_plan/forms.py:103 +#: xpack/plugins/change_auth_plan/models.py:414 msgid "Username" msgstr "用户名" @@ -213,11 +232,15 @@ msgstr "密码或密钥密码" #: users/templates/users/user_profile_update.html:40 #: users/templates/users/user_pubkey_update.html:40 #: users/templates/users/user_update.html:20 +#: xpack/plugins/change_auth_plan/forms.py:23 +#: xpack/plugins/change_auth_plan/models.py:86 +#: xpack/plugins/change_auth_plan/models.py:326 +#: xpack/plugins/change_auth_plan/serializers.py:19 msgid "Password" msgstr "密码" #: assets/forms/user.py:29 assets/serializers/asset_user.py:27 -#: users/models/user.py:81 +#: users/models/user.py:81 xpack/plugins/change_auth_plan/serializers.py:27 msgid "Private key" msgstr "ssh私钥" @@ -274,6 +297,7 @@ msgstr "使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig" #: perms/templates/perms/asset_permission_asset.html:55 settings/forms.py:133 #: users/templates/users/user_granted_asset.html:45 #: users/templates/users/user_group_granted_asset.html:45 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:51 msgid "IP" msgstr "IP" @@ -289,6 +313,7 @@ msgstr "IP" #: perms/templates/perms/asset_permission_list.html:77 settings/forms.py:132 #: users/templates/users/user_granted_asset.html:44 #: users/templates/users/user_group_granted_asset.html:44 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:50 msgid "Hostname" msgstr "主机名" @@ -407,6 +432,8 @@ msgstr "标签管理" #: ops/templates/ops/adhoc_detail.html:86 orgs/models.py:15 perms/models.py:36 #: perms/models.py:89 perms/templates/perms/asset_permission_detail.html:98 #: users/models/user.py:95 users/templates/users/user_detail.html:111 +#: xpack/plugins/change_auth_plan/models.py:99 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:113 #: xpack/plugins/cloud/models.py:55 xpack/plugins/cloud/models.py:127 msgid "Created by" msgstr "创建者" @@ -422,6 +449,7 @@ msgstr "创建者" #: perms/templates/perms/asset_permission_detail.html:94 #: terminal/templates/terminal/terminal_detail.html:59 users/models/group.py:17 #: users/templates/users/user_group_detail.html:63 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:105 #: xpack/plugins/cloud/models.py:56 xpack/plugins/cloud/models.py:128 #: xpack/plugins/cloud/templates/cloud/account_detail.html:68 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:79 @@ -452,8 +480,11 @@ msgstr "创建日期" #: users/templates/users/user_detail.html:127 #: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_list.html:14 -#: users/templates/users/user_profile.html:134 xpack/plugins/cloud/models.py:54 -#: xpack/plugins/cloud/models.py:125 +#: users/templates/users/user_profile.html:134 +#: xpack/plugins/change_auth_plan/models.py:95 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:117 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:19 +#: xpack/plugins/cloud/models.py:54 xpack/plugins/cloud/models.py:125 #: xpack/plugins/cloud/templates/cloud/account_detail.html:72 #: xpack/plugins/cloud/templates/cloud/account_list.html:15 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:71 @@ -501,11 +532,13 @@ msgstr "版本" msgid "AuthBook" msgstr "" -#: assets/models/base.py:29 +#: assets/models/base.py:29 xpack/plugins/change_auth_plan/models.py:90 +#: xpack/plugins/change_auth_plan/models.py:330 msgid "SSH private key" msgstr "ssh密钥" -#: assets/models/base.py:30 +#: assets/models/base.py:30 xpack/plugins/change_auth_plan/models.py:93 +#: xpack/plugins/change_auth_plan/models.py:333 msgid "SSH public key" msgstr "ssh公钥" @@ -645,6 +678,9 @@ msgstr "每行一个命令" #: terminal/templates/terminal/terminal_list.html:36 #: users/templates/users/user_group_list.html:15 #: users/templates/users/user_list.html:29 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:60 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:18 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:20 #: xpack/plugins/cloud/templates/cloud/account_list.html:16 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:18 #: xpack/plugins/orgs/templates/orgs/org_list.html:23 @@ -792,6 +828,7 @@ msgstr "%(value)s is not an even number" #: users/templates/users/user_profile.html:68 #: users/templates/users/user_profile_update.html:43 #: users/templates/users/user_pubkey_update.html:43 +#: xpack/plugins/change_auth_plan/serializers.py:23 msgid "Public key" msgstr "ssh公钥" @@ -944,6 +981,7 @@ msgstr "如果使用了nat端口映射,请设置为ssh真实监听的端口" #: assets/templates/assets/asset_update.html:21 #: assets/templates/assets/gateway_create_update.html:37 #: perms/templates/perms/asset_permission_create_update.html:38 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:37 msgid "Basic" msgstr "基本" @@ -965,6 +1003,7 @@ msgstr "自动生成密钥" #: assets/templates/assets/gateway_create_update.html:53 #: perms/templates/perms/asset_permission_create_update.html:50 #: terminal/templates/terminal/terminal_update.html:40 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:61 msgid "Other" msgstr "其它" @@ -995,6 +1034,7 @@ msgstr "其它" #: users/templates/users/user_profile_update.html:63 #: users/templates/users/user_pubkey_update.html:70 #: users/templates/users/user_pubkey_update.html:76 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:65 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:33 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:35 #: xpack/plugins/interface/templates/interface/interface.html:88 @@ -1021,7 +1061,7 @@ msgstr "重置" #: settings/templates/settings/security_setting.html:71 #: settings/templates/settings/terminal_setting.html:70 #: terminal/templates/terminal/command_list.html:103 -#: terminal/templates/terminal/session_list.html:127 +#: terminal/templates/terminal/session_list.html:126 #: terminal/templates/terminal/terminal_update.html:46 #: users/templates/users/_user.html:51 #: users/templates/users/forgot_password.html:49 @@ -1030,6 +1070,7 @@ msgstr "重置" #: users/templates/users/user_password_update.html:72 #: users/templates/users/user_profile_update.html:64 #: users/templates/users/user_pubkey_update.html:77 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:66 #: xpack/plugins/interface/templates/interface/interface.html:89 msgid "Submit" msgstr "提交" @@ -1059,6 +1100,7 @@ msgstr "关闭" #: perms/templates/perms/asset_permission_asset.html:18 #: perms/templates/perms/asset_permission_detail.html:18 #: perms/templates/perms/asset_permission_user.html:18 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:106 msgid "Detail" msgstr "详情" @@ -1069,6 +1111,7 @@ msgstr "资产列表" #: assets/templates/assets/admin_user_assets.html:29 #: perms/templates/perms/asset_permission_asset.html:35 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:31 msgid "Asset list of " msgstr "资产列表" @@ -1143,6 +1186,8 @@ msgstr "更新失败" #: users/templates/users/user_profile.html:177 #: users/templates/users/user_profile.html:187 #: users/templates/users/user_profile.html:196 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:29 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:54 #: xpack/plugins/cloud/templates/cloud/account_detail.html:25 #: xpack/plugins/cloud/templates/cloud/account_list.html:38 #: xpack/plugins/orgs/templates/orgs/org_detail.html:25 @@ -1175,6 +1220,8 @@ msgstr "更新" #: users/templates/users/user_group_list.html:45 #: users/templates/users/user_list.html:84 #: users/templates/users/user_list.html:88 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:33 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:56 #: xpack/plugins/cloud/templates/cloud/account_detail.html:29 #: xpack/plugins/cloud/templates/cloud/account_list.html:40 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:32 @@ -1190,6 +1237,8 @@ msgstr "替换资产的管理员" #: assets/templates/assets/admin_user_detail.html:91 #: perms/templates/perms/asset_permission_asset.html:116 +#: xpack/plugins/change_auth_plan/forms.py:38 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:112 msgid "Select nodes" msgstr "选择节点" @@ -1256,6 +1305,7 @@ msgstr "资产用户" #: assets/templates/assets/asset_asset_user_list.html:51 #: assets/templates/assets/cmd_filter_detail.html:73 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:109 msgid "Date updated" msgstr "更新日期" @@ -1264,6 +1314,7 @@ msgstr "更新日期" #: terminal/templates/terminal/session_detail.html:81 #: users/templates/users/user_detail.html:138 #: users/templates/users/user_profile.html:146 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:128 #: xpack/plugins/license/templates/license/license_detail.html:93 msgid "Quick modify" msgstr "快速修改" @@ -1797,7 +1848,9 @@ msgstr "文件名" #: audits/templates/audits/ftp_log_list.html:76 #: ops/templates/ops/command_execution_list.html:64 #: ops/templates/ops/task_list.html:31 -#: users/templates/users/user_detail.html:458 xpack/plugins/cloud/api.py:62 +#: users/templates/users/user_detail.html:458 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:14 +#: xpack/plugins/cloud/api.py:62 msgid "Success" msgstr "成功" @@ -1875,6 +1928,8 @@ msgid "MFA" msgstr "MFA" #: audits/models.py:99 audits/templates/audits/login_log_list.html:55 +#: xpack/plugins/change_auth_plan/models.py:421 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:15 #: xpack/plugins/cloud/models.py:172 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:69 msgid "Reason" @@ -1898,6 +1953,10 @@ msgstr "登录日期" #: ops/templates/ops/task_history.html:58 perms/models.py:34 #: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:165 #: terminal/templates/terminal/session_list.html:78 +#: xpack/plugins/change_auth_plan/models.py:312 +#: xpack/plugins/change_auth_plan/models.py:424 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:59 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:17 msgid "Date start" msgstr "开始日期" @@ -2160,7 +2219,7 @@ msgstr "Crontab" #: ops/models/adhoc.py:39 msgid "5 * * * *" -msgstr "" +msgstr "5 * * * *" #: ops/models/adhoc.py:41 msgid "Callback" @@ -2225,6 +2284,10 @@ msgstr "完成时间" #: ops/models/adhoc.py:326 ops/templates/ops/adhoc_history.html:57 #: ops/templates/ops/task_history.html:63 ops/templates/ops/task_list.html:33 +#: xpack/plugins/change_auth_plan/models.py:315 +#: xpack/plugins/change_auth_plan/models.py:427 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:58 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:16 msgid "Time" msgstr "时间" @@ -2248,7 +2311,9 @@ msgstr "结果" msgid "Adhoc result summary" msgstr "汇总" -#: ops/models/command.py:22 xpack/plugins/cloud/models.py:170 +#: ops/models/command.py:22 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:56 +#: xpack/plugins/cloud/models.py:170 msgid "Result" msgstr "结果" @@ -2282,6 +2347,7 @@ msgid "Run as" msgstr "运行用户" #: ops/templates/ops/adhoc_detail.html:94 ops/templates/ops/task_list.html:28 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:18 msgid "Run times" msgstr "执行次数" @@ -2440,6 +2506,7 @@ msgid "Versions" msgstr "版本" #: ops/templates/ops/task_list.html:63 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:52 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:52 msgid "Run" msgstr "执行" @@ -2515,6 +2582,9 @@ msgstr "用户或用户组" #: perms/templates/perms/asset_permission_asset.html:27 #: perms/templates/perms/asset_permission_detail.html:27 #: perms/templates/perms/asset_permission_user.html:27 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:20 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:23 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:20 msgid "Assets and node" msgstr "资产或节点" @@ -2529,6 +2599,7 @@ msgstr "添加资产" #: settings/templates/settings/terminal_setting.html:95 #: settings/templates/settings/terminal_setting.html:117 #: users/templates/users/user_group_detail.html:95 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:93 #: xpack/plugins/orgs/templates/orgs/org_detail.html:93 #: xpack/plugins/orgs/templates/orgs/org_detail.html:130 msgid "Add" @@ -2540,6 +2611,7 @@ msgstr "添加节点" #: perms/templates/perms/asset_permission_asset.html:125 #: users/templates/users/user_detail.html:230 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:121 msgid "Join" msgstr "加入" @@ -3491,7 +3563,7 @@ msgstr "最后活跃日期" msgid "Date end" msgstr "结束日期" -#: terminal/models.py:234 +#: terminal/models.py:242 msgid "Args" msgstr "参数" @@ -3537,28 +3609,24 @@ msgstr "登录来源" msgid "Duration" msgstr "时长" -#: terminal/templates/terminal/session_list.html:106 -msgid "Monitor" -msgstr "监控" - -#: terminal/templates/terminal/session_list.html:108 -#: terminal/templates/terminal/session_list.html:110 +#: terminal/templates/terminal/session_list.html:107 +#: terminal/templates/terminal/session_list.html:109 msgid "Terminate" msgstr "终断" -#: terminal/templates/terminal/session_list.html:122 +#: terminal/templates/terminal/session_list.html:121 msgid "Terminate selected" msgstr "终断所选" -#: terminal/templates/terminal/session_list.html:123 +#: terminal/templates/terminal/session_list.html:122 msgid "Confirm finished" msgstr "确认已完成" -#: terminal/templates/terminal/session_list.html:143 +#: terminal/templates/terminal/session_list.html:142 msgid "Terminate task send, waiting ..." msgstr "终断任务已发送,请等待" -#: terminal/templates/terminal/session_list.html:156 +#: terminal/templates/terminal/session_list.html:155 msgid "Finish session success" msgstr "标记会话完成成功" @@ -4604,6 +4672,192 @@ msgstr "MFA 解绑成功" msgid "MFA disable success, return login page" msgstr "MFA 解绑成功,返回登录页面" +#: xpack/plugins/change_auth_plan/forms.py:19 +#: xpack/plugins/change_auth_plan/models.py:71 +#: xpack/plugins/change_auth_plan/models.py:148 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:100 +msgid "Cycle perform" +msgstr "周期执行" + +#: xpack/plugins/change_auth_plan/forms.py:19 +msgid "Tips: (Units: hour)" +msgstr "提示:(单位: 时)" + +#: xpack/plugins/change_auth_plan/forms.py:27 +msgid "Password length" +msgstr "密码长度" + +#: xpack/plugins/change_auth_plan/forms.py:59 +msgid "* Please enter custom password" +msgstr "* 请输入自定义密码" + +#: xpack/plugins/change_auth_plan/forms.py:69 +msgid "* Please enter a valid crontab expression" +msgstr "* 请输入有效的 crontab 表达式" + +#: xpack/plugins/change_auth_plan/forms.py:107 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:54 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:81 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:17 +msgid "Timing perform" +msgstr "定时执行" + +#: xpack/plugins/change_auth_plan/forms.py:110 +msgid "" +"eg: Every Sunday 03:05 run (5 3 * * 0)
Tips: Using 5 digits linux " +"crontab expressions (Online tools)
Note: If both Regularly perform and " +"Cycle perform are set, give priority to Regularly perform" +msgstr "" +"eg:每周日 03:05 执行(5 3 * * 0)
提示: 使用5位 Linux crontab 表达式" +"(在线工具
注" +"意: 如果同时设置了定期执行和周期执行,优先使用定期执行" + +#: xpack/plugins/change_auth_plan/meta.py:9 +#: xpack/plugins/change_auth_plan/models.py:106 +#: xpack/plugins/change_auth_plan/models.py:319 +#: xpack/plugins/change_auth_plan/views.py:32 +#: xpack/plugins/change_auth_plan/views.py:48 +#: xpack/plugins/change_auth_plan/views.py:69 +#: xpack/plugins/change_auth_plan/views.py:83 +#: xpack/plugins/change_auth_plan/views.py:110 +#: xpack/plugins/change_auth_plan/views.py:126 +#: xpack/plugins/change_auth_plan/views.py:140 +msgid "Change auth plan" +msgstr "改密计划" + +#: xpack/plugins/change_auth_plan/models.py:50 +msgid "Custom password" +msgstr "自定义密码" + +#: xpack/plugins/change_auth_plan/models.py:51 +msgid "All assets use the same random password" +msgstr "所有资产使用相同的随机密码" + +#: xpack/plugins/change_auth_plan/models.py:52 +msgid "All assets use different random password" +msgstr "所有资产使用不同的随机密码" + +#: xpack/plugins/change_auth_plan/models.py:58 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:65 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:53 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:12 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:13 +msgid "Asset username" +msgstr "资产用户名" + +#: xpack/plugins/change_auth_plan/models.py:75 +#: xpack/plugins/change_auth_plan/models.py:146 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:92 +msgid "Regularly perform" +msgstr "定期执行" + +#: xpack/plugins/change_auth_plan/models.py:79 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:45 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:69 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:57 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:16 +msgid "Password strategy" +msgstr "密码策略" + +#: xpack/plugins/change_auth_plan/models.py:83 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:74 +msgid "Password rules" +msgstr "密码规则" + +#: xpack/plugins/change_auth_plan/models.py:323 +msgid "Change auth plan snapshot" +msgstr "改密计划快照" + +#: xpack/plugins/change_auth_plan/models.py:338 +#: xpack/plugins/change_auth_plan/models.py:431 +msgid "Change auth plan history" +msgstr "改密计划历史" + +#: xpack/plugins/change_auth_plan/models.py:440 +msgid "Change auth plan task" +msgstr "改密计划任务" + +#: xpack/plugins/change_auth_plan/models.py:458 +msgid "Authentication failed" +msgstr "认证失败" + +#: xpack/plugins/change_auth_plan/models.py:460 +msgid "Connection timeout" +msgstr "连接超时" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:17 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:20 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:17 +#: xpack/plugins/change_auth_plan/views.py:84 +msgid "Plan detail" +msgstr "计划详情" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:23 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:26 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:23 +#: xpack/plugins/change_auth_plan/views.py:127 +msgid "Run history list" +msgstr "执行历史列表" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:76 +msgid "Add asset to this plan" +msgstr "添加资产" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:104 +msgid "Add node to this plan" +msgstr "添加节点" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:76 +msgid "Length" +msgstr "长度" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:84 +msgid "Yes" +msgstr "是" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:86 +msgid "No" +msgstr "否" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:31 +msgid "History of plan" +msgstr "执行历史" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_list.html:104 +msgid "Log" +msgstr "日志" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:61 +msgid "Retry" +msgstr "重试" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_history_task_list.html:96 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:101 +msgid "Run failed" +msgstr "执行失败" + +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:5 +#: xpack/plugins/change_auth_plan/views.py:49 +msgid "Create plan" +msgstr "创建计划" + +#: xpack/plugins/change_auth_plan/views.py:33 +msgid "Plan list" +msgstr "计划列表" + +#: xpack/plugins/change_auth_plan/views.py:70 +msgid "Update plan" +msgstr "更新计划" + +#: xpack/plugins/change_auth_plan/views.py:111 +msgid "plan asset list" +msgstr "计划资产列表" + +#: xpack/plugins/change_auth_plan/views.py:141 +msgid "Run history task list" +msgstr "执行历史任务列表" + #: xpack/plugins/cloud/api.py:61 xpack/plugins/cloud/providers/base.py:84 msgid "Account unavailable" msgstr "账户无效" @@ -4640,7 +4894,7 @@ msgstr "选择管理员" #: xpack/plugins/cloud/views.py:41 xpack/plugins/cloud/views.py:57 #: xpack/plugins/cloud/views.py:71 xpack/plugins/cloud/views.py:84 #: xpack/plugins/cloud/views.py:100 xpack/plugins/cloud/views.py:121 -#: xpack/plugins/cloud/views.py:136 xpack/plugins/cloud/views.py:187 +#: xpack/plugins/cloud/views.py:136 xpack/plugins/cloud/views.py:179 msgid "Cloud center" msgstr "云管中心" @@ -4771,7 +5025,7 @@ msgstr "同步历史列表" #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:28 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:31 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:29 -#: xpack/plugins/cloud/views.py:188 +#: xpack/plugins/cloud/views.py:180 msgid "Sync instance list" msgstr "同步实例列表" @@ -5011,6 +5265,13 @@ msgstr "创建组织" msgid "Update org" msgstr "更新组织" +#~ msgid "" +#~ "* When selecting a custom password strategy, please enter the password" +#~ msgstr "* 选择自定义密码策略时,请输入密码" + +#~ msgid "Monitor" +#~ msgstr "监控" + #~ msgid "Invalid private key" #~ msgstr "ssh密钥不合法" From e4e6f59589d38b998f256fec4f42cf0a9fb71d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AB=E5=8D=83=E6=B5=81?= <40739051+jym503558564@users.noreply.github.com> Date: Fri, 22 Mar 2019 15:17:22 +0800 Subject: [PATCH 2/2] Export login log (#2511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Add]增加登录日志导出功能 * [Update]优化导出登录日志代码 * [Update]优化导出登录日志代码 * [Update]更改导出登录日志按钮 --- apps/audits/models.py | 18 +++ .../templates/audits/login_log_list.html | 106 ++++++++++++------ apps/audits/urls/view_urls.py | 1 + apps/audits/utils.py | 22 ++++ apps/audits/views.py | 50 +++++++++ 5 files changed, 165 insertions(+), 32 deletions(-) create mode 100644 apps/audits/utils.py diff --git a/apps/audits/models.py b/apps/audits/models.py index 7e2302bb4..04177d6b4 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -1,6 +1,7 @@ import uuid from django.db import models +from django.db.models import Q from django.utils.translation import ugettext_lazy as _ from django.utils import timezone @@ -100,5 +101,22 @@ class UserLoginLog(models.Model): status = models.BooleanField(max_length=2, default=True, choices=STATUS_CHOICE, verbose_name=_('Status')) datetime = models.DateTimeField(default=timezone.now, verbose_name=_('Date login')) + @classmethod + def get_login_logs(cls, date_form=None, date_to=None, user=None, keyword=None): + login_logs = cls.objects.all() + if date_form and date_to: + login_logs = login_logs.filter( + datetime__gt=date_form, datetime__lt=date_to + ) + if user: + login_logs = login_logs.filter(username=user) + if keyword: + login_logs = login_logs.filter( + Q(ip__contains=keyword) | + Q(city__contains=keyword) | + Q(username__contains=keyword) + ) + return login_logs + class Meta: ordering = ['-datetime', 'username'] diff --git a/apps/audits/templates/audits/login_log_list.html b/apps/audits/templates/audits/login_log_list.html index 8b50d4d9a..53cb05560 100644 --- a/apps/audits/templates/audits/login_log_list.html +++ b/apps/audits/templates/audits/login_log_list.html @@ -17,10 +17,10 @@
- + {# #} to - +
@@ -32,7 +32,7 @@
- +
@@ -43,38 +43,57 @@
{% endblock %} +{% block table_container %} + + + + + + + + + + + + + + + + + + {% for login_log in object_list %} + + + + + + + + + + + + + {% endfor %} + +
{% trans 'ID' %}{% trans 'Username' %}{% trans 'Type' %}{% trans 'UA' %}{% trans 'IP' %}{% trans 'City' %}{% trans 'MFA' %}{% trans 'Reason' %}{% trans 'Status' %}{% trans 'Date' %}
{{ forloop.counter }}{{ login_log.username }}{{ login_log.get_type_display }} + {{ login_log.user_agent | truncatechars:20 }} + {{ login_log.ip }}{{ login_log.city }}{{ login_log.get_mfa_display }}{{ login_log.get_reason_display }}{{ login_log.get_status_display }}{{ login_log.datetime }}
+
+
+ +
+ +
+
+
-{% block table_head %} - {% trans 'ID' %} - {% trans 'Username' %} - {% trans 'Type' %} - {% trans 'UA' %} - {% trans 'IP' %} - {% trans 'City' %} - {% trans 'MFA' %} - {% trans 'Reason' %} - {% trans 'Status' %} - {% trans 'Date' %} {% endblock %} -{% block table_body %} - {% for login_log in object_list %} - - {{ forloop.counter }} - {{ login_log.username }} - {{ login_log.get_type_display }} - - {{ login_log.user_agent | truncatechars:20 }} - - {{ login_log.ip }} - {{ login_log.city }} - {{ login_log.get_mfa_display }} - {{ login_log.get_reason_display }} - {{ login_log.get_status_display }} - {{ login_log.datetime }} - - {% endfor %} -{% endblock %} {% block custom_foot_js %} @@ -95,6 +114,29 @@ width: 'auto' }); }) + .on('click', '.btn_export', function () { + var date_form = $('#id_date_from').val(); + var date_to = $('#id_date_to').val(); + var user = $('.select2 option:selected').val(); + var keyword = $('#search').val(); + $.ajax({ + url: "{% url "audits:login-log-export" %}", + method: 'POST', + data: JSON.stringify({ + 'date_form':date_form, + 'date_to':date_to, + 'user':user, + 'keyword':keyword + }), + dataType: "json", + success: function (data, textStatus) { + window.open(data.redirect) + }, + error: function () { + toastr.error('Export failed'); + } + }) + }) {% endblock %} diff --git a/apps/audits/urls/view_urls.py b/apps/audits/urls/view_urls.py index 473a2d83f..ef400cb99 100644 --- a/apps/audits/urls/view_urls.py +++ b/apps/audits/urls/view_urls.py @@ -14,4 +14,5 @@ urlpatterns = [ path('operate-log/', views.OperateLogListView.as_view(), name='operate-log-list'), path('password-change-log/', views.PasswordChangeLogList.as_view(), name='password-change-log-list'), path('command-execution-log/', views.CommandExecutionListView.as_view(), name='command-execution-log-list'), + path('login-log/export/', views.LoginLogExportView.as_view(), name='login-log-export'), ] diff --git a/apps/audits/utils.py b/apps/audits/utils.py new file mode 100644 index 000000000..36c54e81b --- /dev/null +++ b/apps/audits/utils.py @@ -0,0 +1,22 @@ +import csv +import codecs +from django.http import HttpResponse + + +def get_excel_response(filename): + excel_response = HttpResponse(content_type='text/csv') + excel_response[ + 'Content-Disposition'] = 'attachment; filename="%s"' % filename + excel_response.write(codecs.BOM_UTF8) + return excel_response + + +def write_content_to_excel(response, header=None, login_logs=None, fields=None): + writer = csv.writer(response, dialect='excel', quoting=csv.QUOTE_MINIMAL) + if header: + writer.writerow(header) + if login_logs: + for log in login_logs: + data = [getattr(log, field.name) for field in fields] + writer.writerow(data) + return response \ No newline at end of file diff --git a/apps/audits/views.py b/apps/audits/views.py index a862ca066..3e2cc3473 100644 --- a/apps/audits/views.py +++ b/apps/audits/views.py @@ -1,8 +1,23 @@ +import csv +import json +import uuid +import codecs + + from django.conf import settings +from django.urls import reverse +from django.utils import timezone +from django.core.cache import cache +from django.http import HttpResponse, JsonResponse +from django.utils.decorators import method_decorator +from django.views import View +from django.views.decorators.csrf import csrf_exempt from django.views.generic import ListView from django.utils.translation import ugettext as _ +from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Q +from audits.utils import get_excel_response, write_content_to_excel from common.mixins import DatetimeSearchMixin from common.permissions import AdminUserRequiredMixin @@ -232,3 +247,38 @@ class CommandExecutionListView(UserCommandExecutionListView): } kwargs.update(context) return super().get_context_data(**kwargs) + + +@method_decorator(csrf_exempt, name='dispatch') +class LoginLogExportView(LoginRequiredMixin, View): + + def get(self, request): + fields = [ + field for field in UserLoginLog._meta.fields + ] + filename = 'login-logs-{}.csv'.format( + timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S') + ) + excel_response = get_excel_response(filename) + header = [field.verbose_name for field in fields] + login_logs = cache.get(request.GET.get('spm', ''), []) + + response = write_content_to_excel(excel_response, login_logs=login_logs, + header=header, fields=fields) + return response + + def post(self, request): + try: + date_form = json.loads(request.body).get('date_form', []) + date_to = json.loads(request.body).get('date_to', []) + user = json.loads(request.body).get('user', []) + keyword = json.loads(request.body).get('keyword', []) + + login_logs = UserLoginLog.get_login_logs( + date_form=date_form, date_to=date_to, user=user, keyword=keyword) + except ValueError: + return HttpResponse('Json object not valid', status=400) + spm = uuid.uuid4().hex + cache.set(spm, login_logs, 300) + url = reverse('audits:login-log-export') + '?spm=%s' % spm + return JsonResponse({'redirect': url}) \ No newline at end of file