[Update] 添加用户过期邮件提醒

pull/3059/head
BaiJiangJie 2019-07-31 16:57:21 +08:00
parent 9ab6c58676
commit 586d6e6abb
6 changed files with 217 additions and 107 deletions

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-30 18:48+0800\n" "POT-Creation-Date: 2019-07-31 16:35+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
@ -167,7 +167,7 @@ msgstr "系统用户"
#: settings/templates/settings/terminal_setting.html:105 terminal/models.py:22 #: settings/templates/settings/terminal_setting.html:105 terminal/models.py:22
#: terminal/models.py:258 terminal/templates/terminal/terminal_detail.html:43 #: terminal/models.py:258 terminal/templates/terminal/terminal_detail.html:43
#: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14 #: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14
#: users/models/user.py:330 users/templates/users/_select_user_modal.html:13 #: users/models/user.py:331 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_detail.html:63 #: users/templates/users/user_detail.html:63
#: users/templates/users/user_group_detail.html:55 #: users/templates/users/user_group_detail.html:55
#: users/templates/users/user_group_list.html:35 #: users/templates/users/user_group_list.html:35
@ -218,7 +218,7 @@ msgstr "参数"
#: perms/models/asset_permission.py:117 perms/models/base.py:41 #: perms/models/asset_permission.py:117 perms/models/base.py:41
#: perms/templates/perms/asset_permission_detail.html:98 #: perms/templates/perms/asset_permission_detail.html:98
#: perms/templates/perms/remote_app_permission_detail.html:90 #: perms/templates/perms/remote_app_permission_detail.html:90
#: users/models/user.py:371 users/serializers/v1.py:120 #: users/models/user.py:372 users/serializers/v1.py:120
#: users/templates/users/user_detail.html:111 #: users/templates/users/user_detail.html:111
#: xpack/plugins/change_auth_plan/models.py:106 #: xpack/plugins/change_auth_plan/models.py:106
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:113 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:113
@ -279,7 +279,7 @@ msgstr "创建日期"
#: perms/templates/perms/remote_app_permission_detail.html:94 #: perms/templates/perms/remote_app_permission_detail.html:94
#: settings/models.py:34 terminal/models.py:32 #: settings/models.py:34 terminal/models.py:32
#: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15 #: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15
#: users/models/user.py:363 users/templates/users/user_detail.html:129 #: users/models/user.py:364 users/templates/users/user_detail.html:129
#: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_detail.html:67
#: users/templates/users/user_group_list.html:37 #: users/templates/users/user_group_list.html:37
#: users/templates/users/user_profile.html:138 #: users/templates/users/user_profile.html:138
@ -721,12 +721,12 @@ msgstr "SSH网关支持代理SSH,RDP和VNC"
#: assets/templates/assets/system_user_list.html:52 audits/models.py:94 #: assets/templates/assets/system_user_list.html:52 audits/models.py:94
#: audits/templates/audits/login_log_list.html:51 authentication/forms.py:13 #: audits/templates/audits/login_log_list.html:51 authentication/forms.py:13
#: authentication/templates/authentication/login.html:65 #: authentication/templates/authentication/login.html:65
#: authentication/templates/authentication/new_login.html:91 #: authentication/templates/authentication/new_login.html:92
#: ops/models/adhoc.py:164 perms/templates/perms/asset_permission_list.html:70 #: ops/models/adhoc.py:164 perms/templates/perms/asset_permission_list.html:70
#: perms/templates/perms/asset_permission_user.html:55 #: perms/templates/perms/asset_permission_user.html:55
#: perms/templates/perms/remote_app_permission_user.html:54 #: perms/templates/perms/remote_app_permission_user.html:54
#: settings/templates/settings/_ldap_list_users_modal.html:37 users/forms.py:14 #: settings/templates/settings/_ldap_list_users_modal.html:37 users/forms.py:14
#: users/models/user.py:328 users/templates/users/_select_user_modal.html:14 #: users/models/user.py:329 users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:67 #: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:36 #: users/templates/users/user_list.html:36
#: users/templates/users/user_profile.html:47 #: users/templates/users/user_profile.html:47
@ -750,7 +750,7 @@ msgstr "密码或密钥密码"
#: assets/templates/assets/_asset_user_auth_view_modal.html:27 #: assets/templates/assets/_asset_user_auth_view_modal.html:27
#: authentication/forms.py:15 #: authentication/forms.py:15
#: authentication/templates/authentication/login.html:68 #: authentication/templates/authentication/login.html:68
#: authentication/templates/authentication/new_login.html:94 #: authentication/templates/authentication/new_login.html:95
#: settings/forms.py:110 users/forms.py:16 users/forms.py:28 #: settings/forms.py:110 users/forms.py:16 users/forms.py:28
#: users/templates/users/reset_password.html:53 #: users/templates/users/reset_password.html:53
#: users/templates/users/user_password_authentication.html:18 #: users/templates/users/user_password_authentication.html:18
@ -765,7 +765,7 @@ msgstr "密码"
#: assets/forms/user.py:29 assets/serializers/asset_user.py:70 #: assets/forms/user.py:29 assets/serializers/asset_user.py:70
#: assets/templates/assets/_asset_user_auth_update_modal.html:27 #: assets/templates/assets/_asset_user_auth_update_modal.html:27
#: users/models/user.py:357 #: users/models/user.py:358
msgid "Private key" msgid "Private key"
msgstr "ssh私钥" msgstr "ssh私钥"
@ -971,7 +971,7 @@ msgstr "带宽"
msgid "Contact" msgid "Contact"
msgstr "联系人" msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:349 #: assets/models/cluster.py:22 users/models/user.py:350
#: users/templates/users/user_detail.html:76 #: users/templates/users/user_detail.html:76
msgid "Phone" msgid "Phone"
msgstr "手机" msgstr "手机"
@ -997,7 +997,7 @@ msgid "Default"
msgstr "默认" msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14 #: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:457 #: users/models/user.py:470
msgid "System" msgid "System"
msgstr "系统" msgstr "系统"
@ -1116,7 +1116,7 @@ msgstr "默认资产组"
#: terminal/templates/terminal/command_list.html:65 #: terminal/templates/terminal/command_list.html:65
#: terminal/templates/terminal/session_list.html:27 #: terminal/templates/terminal/session_list.html:27
#: terminal/templates/terminal/session_list.html:71 users/forms.py:316 #: terminal/templates/terminal/session_list.html:71 users/forms.py:316
#: users/models/user.py:127 users/models/user.py:445 #: users/models/user.py:128 users/models/user.py:458
#: users/serializers/v1.py:109 users/templates/users/user_group_detail.html:78 #: users/serializers/v1.py:109 users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:36 users/views/user.py:243 #: users/templates/users/user_group_list.html:36 users/views/user.py:243
#: xpack/plugins/orgs/forms.py:26 #: xpack/plugins/orgs/forms.py:26
@ -1223,7 +1223,7 @@ msgid "Backend"
msgstr "后端" msgstr "后端"
#: assets/serializers/asset_user.py:66 users/forms.py:263 #: assets/serializers/asset_user.py:66 users/forms.py:263
#: users/models/user.py:360 users/templates/users/first_login.html:42 #: users/models/user.py:361 users/templates/users/first_login.html:42
#: users/templates/users/user_password_update.html:49 #: users/templates/users/user_password_update.html:49
#: users/templates/users/user_profile.html:69 #: users/templates/users/user_profile.html:69
#: users/templates/users/user_profile_update.html:46 #: users/templates/users/user_profile_update.html:46
@ -1312,30 +1312,30 @@ msgstr "测试系统用户可连接性: {} => {}"
msgid "Test system user connectivity period: {}" msgid "Test system user connectivity period: {}"
msgstr "定期测试系统用户可连接性: {}" msgstr "定期测试系统用户可连接性: {}"
#: assets/tasks.py:471 assets/tasks.py:557 #: assets/tasks.py:479 assets/tasks.py:565
#: xpack/plugins/change_auth_plan/models.py:522 #: xpack/plugins/change_auth_plan/models.py:522
msgid "The asset {} system platform {} does not support run Ansible tasks" msgid "The asset {} system platform {} does not support run Ansible tasks"
msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务" msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务"
#: assets/tasks.py:483 #: assets/tasks.py:491
msgid "" msgid ""
"Push system user task skip, auto push not enable or protocol is not ssh or " "Push system user task skip, auto push not enable or protocol is not ssh or "
"rdp: {}" "rdp: {}"
msgstr "推送系统用户任务跳过自动推送没有打开或协议不是ssh或rdp: {}" msgstr "推送系统用户任务跳过自动推送没有打开或协议不是ssh或rdp: {}"
#: assets/tasks.py:490 #: assets/tasks.py:498
msgid "For security, do not push user {}" msgid "For security, do not push user {}"
msgstr "为了安全,禁止推送用户 {}" msgstr "为了安全,禁止推送用户 {}"
#: assets/tasks.py:518 assets/tasks.py:532 #: assets/tasks.py:526 assets/tasks.py:540
msgid "Push system users to assets: {}" msgid "Push system users to assets: {}"
msgstr "推送系统用户到入资产: {}" msgstr "推送系统用户到入资产: {}"
#: assets/tasks.py:524 #: assets/tasks.py:532
msgid "Push system users to asset: {} => {}" msgid "Push system users to asset: {} => {}"
msgstr "推送系统用户到入资产: {} => {}" msgstr "推送系统用户到入资产: {} => {}"
#: assets/tasks.py:604 #: assets/tasks.py:612
msgid "Test asset user connectivity: {}" msgid "Test asset user connectivity: {}"
msgstr "测试资产用户可连接性: {}" msgstr "测试资产用户可连接性: {}"
@ -2212,7 +2212,7 @@ msgstr "Agent"
#: audits/models.py:99 audits/templates/audits/login_log_list.html:56 #: audits/models.py:99 audits/templates/audits/login_log_list.html:56
#: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms.py:175 users/models/user.py:352 #: users/forms.py:175 users/models/user.py:353
#: users/templates/users/first_login.html:45 #: users/templates/users/first_login.html:45
msgid "MFA" msgid "MFA"
msgstr "MFA" msgstr "MFA"
@ -2479,23 +2479,23 @@ msgstr "改变世界,从一点点开始。"
#: authentication/templates/authentication/login.html:46 #: authentication/templates/authentication/login.html:46
#: authentication/templates/authentication/login.html:73 #: authentication/templates/authentication/login.html:73
#: authentication/templates/authentication/new_login.html:100 #: authentication/templates/authentication/new_login.html:101
#: templates/_header_bar.html:101 #: templates/_header_bar.html:101
msgid "Login" msgid "Login"
msgstr "登录" msgstr "登录"
#: authentication/templates/authentication/login.html:54 #: authentication/templates/authentication/login.html:54
#: authentication/templates/authentication/new_login.html:79 #: authentication/templates/authentication/new_login.html:80
msgid "The user password has expired" msgid "The user password has expired"
msgstr "用户密码已过期" msgstr "用户密码已过期"
#: authentication/templates/authentication/login.html:57 #: authentication/templates/authentication/login.html:57
#: authentication/templates/authentication/new_login.html:82 #: authentication/templates/authentication/new_login.html:83
msgid "Captcha invalid" msgid "Captcha invalid"
msgstr "验证码错误" msgstr "验证码错误"
#: authentication/templates/authentication/login.html:84 #: authentication/templates/authentication/login.html:84
#: authentication/templates/authentication/new_login.html:104 #: authentication/templates/authentication/new_login.html:105
#: users/templates/users/forgot_password.html:10 #: users/templates/users/forgot_password.html:10
#: users/templates/users/forgot_password.html:25 #: users/templates/users/forgot_password.html:25
msgid "Forgot password" msgid "Forgot password"
@ -3022,7 +3022,7 @@ msgstr "空"
#: perms/templates/perms/asset_permission_list.html:118 #: perms/templates/perms/asset_permission_list.html:118
#: perms/templates/perms/remote_app_permission_list.html:16 #: perms/templates/perms/remote_app_permission_list.html:16
#: templates/_nav.html:14 users/forms.py:286 users/models/group.py:26 #: templates/_nav.html:14 users/forms.py:286 users/models/group.py:26
#: users/models/user.py:336 users/templates/users/_select_user_modal.html:16 #: users/models/user.py:337 users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_detail.html:217 #: users/templates/users/user_detail.html:217
#: users/templates/users/user_list.html:38 #: users/templates/users/user_list.html:38
#: xpack/plugins/orgs/templates/orgs/org_list.html:15 #: xpack/plugins/orgs/templates/orgs/org_list.html:15
@ -3071,7 +3071,7 @@ msgstr "资产授权"
#: perms/models/asset_permission.py:116 perms/models/base.py:40 #: perms/models/asset_permission.py:116 perms/models/base.py:40
#: perms/templates/perms/asset_permission_detail.html:90 #: perms/templates/perms/asset_permission_detail.html:90
#: perms/templates/perms/remote_app_permission_detail.html:82 #: perms/templates/perms/remote_app_permission_detail.html:82
#: users/models/user.py:368 users/templates/users/user_detail.html:107 #: users/models/user.py:369 users/templates/users/user_detail.html:107
#: users/templates/users/user_profile.html:120 #: users/templates/users/user_profile.html:120
msgid "Date expired" msgid "Date expired"
msgstr "失效日期" msgstr "失效日期"
@ -3625,7 +3625,7 @@ msgid "Please submit the LDAP configuration before import"
msgstr "请先提交LDAP配置再进行导入" msgstr "请先提交LDAP配置再进行导入"
#: settings/templates/settings/_ldap_list_users_modal.html:39 #: settings/templates/settings/_ldap_list_users_modal.html:39
#: users/models/user.py:332 users/templates/users/user_detail.html:71 #: users/models/user.py:333 users/templates/users/user_detail.html:71
#: users/templates/users/user_profile.html:59 #: users/templates/users/user_profile.html:59
msgid "Email" msgid "Email"
msgstr "邮件" msgstr "邮件"
@ -3893,7 +3893,24 @@ msgstr "下载导入模版"
msgid "Select the CSV file to import" msgid "Select the CSV file to import"
msgstr "请选择csv文件导入" msgstr "请选择csv文件导入"
#: templates/_message.html:7 #: templates/_message.html:6
msgid ""
"\n"
" Your account has expired, please contact the administrator.\n"
" "
msgstr ""
"\n"
" 您的账户已经过期,请联系管理员。 "
#: templates/_message.html:13
msgid "Your account will at"
msgstr "您的账户将于"
#: templates/_message.html:13 templates/_message.html:30
msgid "expired. "
msgstr "过期。"
#: templates/_message.html:23
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
@ -3906,15 +3923,11 @@ msgstr ""
"\"%(user_password_update_url)s\"> 链接 </a> 更新密码\n" "\"%(user_password_update_url)s\"> 链接 </a> 更新密码\n"
" " " "
#: templates/_message.html:14 #: templates/_message.html:30
msgid "Your password will at" msgid "Your password will at"
msgstr "您的密码将于" msgstr "您的密码将于"
#: templates/_message.html:14 #: templates/_message.html:31
msgid "expired. "
msgstr "过期。"
#: templates/_message.html:15
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
@ -3927,7 +3940,7 @@ msgstr ""
"新密码\n" "新密码\n"
" " " "
#: templates/_message.html:27 #: templates/_message.html:43
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
@ -3940,7 +3953,7 @@ msgstr ""
"</a> 补充完整\n" "</a> 补充完整\n"
" " " "
#: templates/_message.html:40 #: templates/_message.html:56
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
@ -4408,7 +4421,7 @@ msgstr "你没有权限"
msgid "Could not reset self otp, use profile reset instead" msgid "Could not reset self otp, use profile reset instead"
msgstr "不能再该页面重置MFA, 请去个人信息页面重置" msgstr "不能再该页面重置MFA, 请去个人信息页面重置"
#: users/forms.py:33 users/models/user.py:340 #: users/forms.py:33 users/models/user.py:341
#: users/templates/users/_select_user_modal.html:15 #: users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:87 #: users/templates/users/user_detail.html:87
#: users/templates/users/user_list.html:37 #: users/templates/users/user_list.html:37
@ -4527,52 +4540,52 @@ msgstr "选择用户"
msgid "User auth from {}, go there change password" msgid "User auth from {}, go there change password"
msgstr "用户认证源来自 {}, 请去相应系统修改密码" msgstr "用户认证源来自 {}, 请去相应系统修改密码"
#: users/models/user.py:126 users/models/user.py:453 #: users/models/user.py:127 users/models/user.py:466
msgid "Administrator" msgid "Administrator"
msgstr "管理员" msgstr "管理员"
#: users/models/user.py:128 #: users/models/user.py:129
msgid "Application" msgid "Application"
msgstr "应用程序" msgstr "应用程序"
#: users/models/user.py:129 #: users/models/user.py:130
msgid "Auditor" msgid "Auditor"
msgstr "审计员" msgstr "审计员"
#: users/models/user.py:287 users/templates/users/user_profile.html:94 #: users/models/user.py:288 users/templates/users/user_profile.html:94
#: users/templates/users/user_profile.html:163 #: users/templates/users/user_profile.html:163
#: users/templates/users/user_profile.html:166 #: users/templates/users/user_profile.html:166
msgid "Disable" msgid "Disable"
msgstr "禁用" msgstr "禁用"
#: users/models/user.py:288 users/templates/users/user_profile.html:92 #: users/models/user.py:289 users/templates/users/user_profile.html:92
#: users/templates/users/user_profile.html:170 #: users/templates/users/user_profile.html:170
msgid "Enable" msgid "Enable"
msgstr "启用" msgstr "启用"
#: users/models/user.py:289 users/templates/users/user_profile.html:90 #: users/models/user.py:290 users/templates/users/user_profile.html:90
msgid "Force enable" msgid "Force enable"
msgstr "强制启用" msgstr "强制启用"
#: users/models/user.py:343 #: users/models/user.py:344
msgid "Avatar" msgid "Avatar"
msgstr "头像" msgstr "头像"
#: users/models/user.py:346 users/templates/users/user_detail.html:82 #: users/models/user.py:347 users/templates/users/user_detail.html:82
msgid "Wechat" msgid "Wechat"
msgstr "微信" msgstr "微信"
#: users/models/user.py:375 users/templates/users/user_detail.html:103 #: users/models/user.py:376 users/templates/users/user_detail.html:103
#: users/templates/users/user_list.html:39 #: users/templates/users/user_list.html:39
#: users/templates/users/user_profile.html:102 #: users/templates/users/user_profile.html:102
msgid "Source" msgid "Source"
msgstr "用户来源" msgstr "用户来源"
#: users/models/user.py:379 #: users/models/user.py:380
msgid "Date password last updated" msgid "Date password last updated"
msgstr "最后更新密码日期" msgstr "最后更新密码日期"
#: users/models/user.py:456 #: users/models/user.py:469
msgid "Administrator is the super user of system" msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员" msgstr "Administrator是初始的超级管理员"
@ -5115,43 +5128,43 @@ msgstr "您好 %(name)s"
msgid "" msgid ""
"\n" "\n"
" Hello %(name)s:\n" " Hello %(name)s:\n"
" </br>\n" " <br>\n"
" Please click the link below to reset your password, if not your request, " " Please click the link below to reset your password, if not your request, "
"concern your account security\n" "concern your account security\n"
" </br>\n" " <br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click " " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
"here reset password</a>\n" "here reset password</a>\n"
" </br>\n" " <br>\n"
" This link is valid for 1 hour. After it expires, <a href=" " This link is valid for 1 hour. After it expires, <a href="
"\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n" "\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" ---\n" " ---\n"
"\n" "\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n" " <a href=\"%(login_url)s\">Login direct</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
msgstr "" msgstr ""
"\n" "\n"
" 您好 %(name)s:\n" " 您好 %(name)s:\n"
" </br>\n" " <br>\n"
" 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n" " 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n"
" </br>\n" " <br>\n"
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这" " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这"
"里设置密码 </a>\n" "里设置密码 </a>\n"
" </br>\n" " <br>\n"
" 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?" " 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?"
"email=%(email)s\">重新申请</a>\n" "email=%(email)s\">重新申请</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" ---\n" " ---\n"
"\n" "\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">直接登录</a>\n" " <a href=\"%(login_url)s\">直接登录</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
#: users/utils.py:121 #: users/utils.py:121
@ -5163,88 +5176,114 @@ msgstr "安全通知"
msgid "" msgid ""
"\n" "\n"
" Hello %(name)s:\n" " Hello %(name)s:\n"
" </br>\n" " <br>\n"
" Your password will expire in %(date_password_expired)s,\n" " Your password will expire in %(date_password_expired)s,\n"
" </br>\n" " <br>\n"
" For your account security, please click on the link below to update your " " For your account security, please click on the link below to update your "
"password in time\n" "password in time\n"
" </br>\n" " <br>\n"
" <a href=\"%(update_password_url)s\">Click here update password</a>\n" " <a href=\"%(update_password_url)s\">Click here update password</a>\n"
" </br>\n" " <br>\n"
" If your password has expired, please click \n" " If your password has expired, please click \n"
" <a href=\"%(forget_password_url)s?email=%(email)s\">Password expired</" " <a href=\"%(forget_password_url)s?email=%(email)s\">Password expired</"
"a> \n" "a> \n"
" to apply for a password reset email.\n" " to apply for a password reset email.\n"
"\n" "\n"
" </br>\n" " <br>\n"
" ---\n" " ---\n"
"\n" "\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n" " <a href=\"%(login_url)s\">Login direct</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
msgstr "" msgstr ""
"\n" "\n"
" 您好 %(name)s:\n" " 您好 %(name)s:\n"
" </br>\n" " <br>\n"
" 您的密码会在 %(date_password_expired)s 过期,\n" " 您的密码会在 %(date_password_expired)s 过期,\n"
" </br>\n" " <br>\n"
" 为了您的账号安全,请点击下面的链接及时更新密码\n" " 为了您的账号安全,请点击下面的链接及时更新密码\n"
" </br>\n" " <br>\n"
" <a href=\"%(update_password_url)s\">请点击这里更新密码</a>\n" " <a href=\"%(update_password_url)s\">请点击这里更新密码</a>\n"
" </br>\n" " <br>\n"
" 如果您的密码已经过期,请点击 \n" " 如果您的密码已经过期,请点击 \n"
" <a href=\"%(forget_password_url)s?email=%(email)s\">密码过期</a> \n" " <a href=\"%(forget_password_url)s?email=%(email)s\">密码过期</a> \n"
" 申请一份重置密码邮件。\n" " 申请一份重置密码邮件。\n"
"\n" "\n"
" </br>\n" " <br>\n"
" ---\n" " ---\n"
"\n" "\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">直接登录</a>\n" " <a href=\"%(login_url)s\">直接登录</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
#: users/utils.py:159 #: users/utils.py:159
msgid "SSH Key Reset" msgid "Expiration notice"
msgstr "重置ssh密钥" msgstr "过期通知"
#: users/utils.py:161 #: users/utils.py:161
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
" Hello %(name)s:\n" " Hello %(name)s:\n"
" </br>\n" " <br>\n"
" Your account will expire in %(date_expired)s,\n"
" <br>\n"
" In order not to affect your normal work, please contact the "
"administrator for confirmation.\n"
" <br>\n"
" "
msgstr ""
"\n"
" 您好 %(name)s:\n"
" <br>\n"
" 您的账户会在 %(date_expired)s 过期,\n"
" <br>\n"
" 为了不影响您正常工作,请联系管理员确认。\n"
" <br>\n"
" "
#: users/utils.py:180
msgid "SSH Key Reset"
msgstr "重置ssh密钥"
#: users/utils.py:182
#, python-format
msgid ""
"\n"
" Hello %(name)s:\n"
" <br>\n"
" Your ssh public key has been reset by site administrator.\n" " Your ssh public key has been reset by site administrator.\n"
" Please login and reset your ssh public key.\n" " Please login and reset your ssh public key.\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n" " <a href=\"%(login_url)s\">Login direct</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
msgstr "" msgstr ""
"\n" "\n"
" 你好 %(name)s:\n" " 你好 %(name)s:\n"
" </br>\n" " <br>\n"
" 您的密钥已被管理员重置,\n" " 您的密钥已被管理员重置,\n"
" 请登录并重新设置您的密钥.\n" " 请登录并重新设置您的密钥.\n"
" </br>\n" " <br>\n"
" <a href=\"%(login_url)s\">Login direct</a>\n" " <a href=\"%(login_url)s\">Login direct</a>\n"
"\n" "\n"
" </br>\n" " <br>\n"
" " " "
#: users/utils.py:194 #: users/utils.py:215
msgid "User not exist" msgid "User not exist"
msgstr "用户不存在" msgstr "用户不存在"
#: users/utils.py:196 #: users/utils.py:217
msgid "Disabled or expired" msgid "Disabled or expired"
msgstr "禁用或失效" msgstr "禁用或失效"
#: users/utils.py:209 #: users/utils.py:230
msgid "Password or SSH public key invalid" msgid "Password or SSH public key invalid"
msgstr "密码或密钥不合法" msgstr "密码或密钥不合法"

View File

@ -1,5 +1,21 @@
{% load i18n %} {% load i18n %}
{% block user_expired_message %}
{% if request.user.is_expired %}
<div class="alert alert-danger help-message alert-dismissable">
{% blocktrans %}
Your account has expired, please contact the administrator.
{% endblocktrans %}
<button aria-hidden="true" data-dismiss="alert" class="close" type="button" style="outline: none;">×</button>
</div>
{% elif request.user.will_expired %}
<div class="alert alert-danger help-message alert-dismissable">
{% trans 'Your account will at' %} {{ request.user.date_expired }} {% trans 'expired. ' %}
<button aria-hidden="true" data-dismiss="alert" class="close" type="button" style="outline: none;">×</button>
</div>
{% endif %}
{% endblock %}
{% block password_expired_message %} {% block password_expired_message %}
{% url 'users:user-password-update' as user_password_update_url %} {% url 'users:user-password-update' as user_password_update_url %}
{% if request.user.password_has_expired %} {% if request.user.password_has_expired %}

View File

@ -402,6 +402,18 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
else: else:
return False return False
@property
def expired_remain_days(self):
date_remain = self.date_expired - timezone.now()
return date_remain.days
@property
def will_expired(self):
if 0 <= self.expired_remain_days < 5:
return True
else:
return False
@property @property
def is_valid(self): def is_valid(self):
if self.is_active and not self.is_expired: if self.is_active and not self.is_expired:

View File

@ -1,16 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import datetime
from django.utils import timezone
from django.conf import settings
from celery import shared_task from celery import shared_task
from ops.celery.utils import create_or_update_celery_periodic_tasks from ops.celery.utils import create_or_update_celery_periodic_tasks
from ops.celery.decorator import after_app_ready_start, register_as_period_task from ops.celery.decorator import after_app_ready_start
from common.utils import get_logger from common.utils import get_logger
from .models import User from .models import User
from .utils import send_password_expiration_reminder_mail from .utils import (
send_password_expiration_reminder_mail, send_user_expiration_reminder_mail
)
logger = get_logger(__file__) logger = get_logger(__file__)
@ -43,4 +42,27 @@ def check_password_expired_periodic():
create_or_update_celery_periodic_tasks(tasks) create_or_update_celery_periodic_tasks(tasks)
@shared_task
def check_user_expired():
users = User.objects.exclude(role=User.ROLE_APP)
for user in users:
if not user.is_valid:
continue
if not user.will_expired:
continue
send_user_expiration_reminder_mail(user)
@shared_task
@after_app_ready_start
def check_user_expired_periodic():
tasks = {
'check_user_expired_periodic': {
'task': check_user_expired.name,
'interval': None,
'crontab': '0 14 * * *',
'enabled': True,
}
}
create_or_update_celery_periodic_tasks(tasks)

View File

@ -89,20 +89,20 @@ def send_reset_password_mail(user):
recipient_list = [user.email] recipient_list = [user.email]
message = _(""" message = _("""
Hello %(name)s: Hello %(name)s:
</br> <br>
Please click the link below to reset your password, if not your request, concern your account security Please click the link below to reset your password, if not your request, concern your account security
</br> <br>
<a href="%(rest_password_url)s?token=%(rest_password_token)s">Click here reset password</a> <a href="%(rest_password_url)s?token=%(rest_password_token)s">Click here reset password</a>
</br> <br>
This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one</a> This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one</a>
</br> <br>
--- ---
</br> <br>
<a href="%(login_url)s">Login direct</a> <a href="%(login_url)s">Login direct</a>
</br> <br>
""") % { """) % {
'name': user.name, 'name': user.name,
'rest_password_url': reverse('users:reset-password', external=True), 'rest_password_url': reverse('users:reset-password', external=True),
@ -122,24 +122,24 @@ def send_password_expiration_reminder_mail(user):
recipient_list = [user.email] recipient_list = [user.email]
message = _(""" message = _("""
Hello %(name)s: Hello %(name)s:
</br> <br>
Your password will expire in %(date_password_expired)s, Your password will expire in %(date_password_expired)s,
</br> <br>
For your account security, please click on the link below to update your password in time For your account security, please click on the link below to update your password in time
</br> <br>
<a href="%(update_password_url)s">Click here update password</a> <a href="%(update_password_url)s">Click here update password</a>
</br> <br>
If your password has expired, please click If your password has expired, please click
<a href="%(forget_password_url)s?email=%(email)s">Password expired</a> <a href="%(forget_password_url)s?email=%(email)s">Password expired</a>
to apply for a password reset email. to apply for a password reset email.
</br> <br>
--- ---
</br> <br>
<a href="%(login_url)s">Login direct</a> <a href="%(login_url)s">Login direct</a>
</br> <br>
""") % { """) % {
'name': user.name, 'name': user.name,
'date_password_expired': datetime.fromtimestamp(datetime.timestamp( 'date_password_expired': datetime.fromtimestamp(datetime.timestamp(
@ -155,18 +155,39 @@ def send_password_expiration_reminder_mail(user):
send_mail_async.delay(subject, message, recipient_list, html_message=message) send_mail_async.delay(subject, message, recipient_list, html_message=message)
def send_user_expiration_reminder_mail(user):
subject = _('Expiration notice')
recipient_list = [user.email]
message = _("""
Hello %(name)s:
<br>
Your account will expire in %(date_expired)s,
<br>
In order not to affect your normal work, please contact the administrator for confirmation.
<br>
""") % {
'name': user.name,
'date_expired': datetime.fromtimestamp(datetime.timestamp(
user.date_expired)).strftime('%Y-%m-%d %H:%M'),
}
if settings.DEBUG:
logger.debug(message)
send_mail_async.delay(subject, message, recipient_list, html_message=message)
def send_reset_ssh_key_mail(user): def send_reset_ssh_key_mail(user):
subject = _('SSH Key Reset') subject = _('SSH Key Reset')
recipient_list = [user.email] recipient_list = [user.email]
message = _(""" message = _("""
Hello %(name)s: Hello %(name)s:
</br> <br>
Your ssh public key has been reset by site administrator. Your ssh public key has been reset by site administrator.
Please login and reset your ssh public key. Please login and reset your ssh public key.
</br> <br>
<a href="%(login_url)s">Login direct</a> <a href="%(login_url)s">Login direct</a>
</br> <br>
""") % { """) % {
'name': user.name, 'name': user.name,
'login_url': reverse('authentication:login', external=True), 'login_url': reverse('authentication:login', external=True),