Email reset password (#2547)

* [Update]更改英文登录界面标题,可两行

* [Update] 更改用户通过邮箱修改密码后,该链接就失效

* [Update]更改页面左上角logo_text图片

* [Update] 优化发送邮箱改密连接失效代码

* [Update] 优化发送邮箱改密连接失效代码(2)

* [Update] 优化发送邮箱改密连接失效代码(3)

* [Update] 更新interface一键恢复默认的翻译

* [Update] 更改登录失败 用户名密码错误信息的翻译

* [Update] 优化生成token并设置缓存的代码
pull/2599/head
八千流 2019-04-15 14:37:45 +08:00 committed by 老广
parent 78e4e13fb9
commit 56519354b6
6 changed files with 140 additions and 73 deletions

View File

@ -14,6 +14,14 @@ class UserLoginForm(AuthenticationForm):
max_length=128, strip=False max_length=128, strip=False
) )
error_messages = {
'invalid_login': _(
"Please enter a correct username and password. Note that both "
"fields may be case-sensitive."
),
'inactive': _("This account is inactive."),
}
def confirm_login_allowed(self, user): def confirm_login_allowed(self, user):
if not user.is_staff: if not user.is_staff:
raise forms.ValidationError( raise forms.ValidationError(

View File

@ -52,7 +52,7 @@
</style> </style>
</head> </head>
<body style="height: 100%"> <body style="height: 100%;font-size: 13px">
<div> <div>
<div class="box-1"> <div class="box-1">
<div class="box-2"> <div class="box-2">
@ -60,19 +60,19 @@
</div> </div>
<div class="box-3"> <div class="box-3">
<div style="background-color: white"> <div style="background-color: white">
<div style="margin-top: 40px;padding-top: 50px;"> <div style="margin-top: 30px;padding-top: 40px;padding-left: 20px;padding-right: 20px;height: 80px">
<span style="font-size: 24px;font-weight:400;color: #151515;letter-spacing: 0;">{{ JMS_TITLE }}</span> <span style="font-size: 21px;font-weight:400;color: #151515;letter-spacing: 0;">{{ JMS_TITLE }}</span>
</div> </div>
<div style="font-size: 12px;color: #999999;letter-spacing: 0;line-height: 18px;margin-top: 10px"> <div style="font-size: 12px;color: #999999;letter-spacing: 0;line-height: 18px;margin-top: 18px">
{% trans 'Welcome back, please enter username and password to login' %} {% trans 'Welcome back, please enter username and password to login' %}
</div> </div>
<div style="margin-bottom: 10px"> <div style="margin-bottom: 10px">
<div> <div>
<div class="col-md-1"></div> <div class="col-md-1"></div>
<div class="contact-form col-md-10" style="margin-top: 20px;height: 35px"> <div class="contact-form col-md-10" style="margin-top: 10px;height: 35px">
<form id="contact-form" action="" method="post" role="form" novalidate="novalidate"> <form id="contact-form" action="" method="post" role="form" novalidate="novalidate">
{% csrf_token %} {% csrf_token %}
<div style="height: 48px;color: red"> <div style="height: 45px;color: red;line-height: 17px;">
{% if block_login %} {% if block_login %}
<p class="red-fonts">{% trans 'Log in frequently and try again later' %}</p> <p class="red-fonts">{% trans 'Log in frequently and try again later' %}</p>
{% elif password_expired %} {% elif password_expired %}
@ -92,7 +92,7 @@
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" name="{{ form.password.html_name }}" placeholder="{% trans 'Password' %}" required=""> <input type="password" class="form-control" name="{{ form.password.html_name }}" placeholder="{% trans 'Password' %}" required="">
</div> </div>
<div class="form-group" style="height: 50px;margin-bottom: 0"> <div class="form-group" style="height: 50px;margin-bottom: 0;font-size: 13px">
{{ form.captcha }} {{ form.captcha }}
</div> </div>
<div class="form-group" style="margin-top: 10px"> <div class="form-group" style="margin-top: 10px">

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-03-27 17:33+0800\n" "POT-Creation-Date: 2019-03-29 17:11+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"
@ -172,7 +172,7 @@ msgstr "SSH网关支持代理SSH,RDP和VNC"
#: settings/templates/settings/terminal_setting.html:102 terminal/models.py:22 #: settings/templates/settings/terminal_setting.html:102 terminal/models.py:22
#: terminal/models.py:241 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 #: 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/models/user.py:61 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:12 #: users/templates/users/user_group_list.html:12
@ -208,7 +208,7 @@ msgstr "名称"
#: ops/models/adhoc.py:164 perms/templates/perms/asset_permission_list.html:74 #: ops/models/adhoc.py:164 perms/templates/perms/asset_permission_list.html:74
#: perms/templates/perms/asset_permission_user.html:55 #: perms/templates/perms/asset_permission_user.html:55
#: settings/templates/settings/_ldap_list_users_modal.html:37 users/forms.py:13 #: settings/templates/settings/_ldap_list_users_modal.html:37 users/forms.py:13
#: users/models/user.py:52 users/templates/users/_select_user_modal.html:14 #: users/models/user.py:59 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:24 #: users/templates/users/user_list.html:24
#: users/templates/users/user_profile.html:47 #: users/templates/users/user_profile.html:47
@ -246,7 +246,7 @@ msgid "Password"
msgstr "密码" msgstr "密码"
#: assets/forms/user.py:29 assets/serializers/asset_user.py:27 #: assets/forms/user.py:29 assets/serializers/asset_user.py:27
#: users/models/user.py:81 #: users/models/user.py:88
msgid "Private key" msgid "Private key"
msgstr "ssh私钥" msgstr "ssh私钥"
@ -437,7 +437,7 @@ msgstr "标签管理"
#: assets/templates/assets/system_user_detail.html:100 #: assets/templates/assets/system_user_detail.html:100
#: ops/templates/ops/adhoc_detail.html:86 orgs/models.py:15 perms/models.py:36 #: 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 #: perms/models.py:89 perms/templates/perms/asset_permission_detail.html:98
#: users/models/user.py:95 users/templates/users/user_detail.html:111 #: users/models/user.py:102 users/templates/users/user_detail.html:111
#: xpack/plugins/change_auth_plan/models.py:103 #: xpack/plugins/change_auth_plan/models.py:103
#: 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
#: xpack/plugins/cloud/models.py:55 xpack/plugins/cloud/models.py:127 #: xpack/plugins/cloud/models.py:55 xpack/plugins/cloud/models.py:127
@ -482,7 +482,7 @@ msgstr "创建日期"
#: orgs/models.py:17 perms/models.py:38 perms/models.py:91 #: orgs/models.py:17 perms/models.py:38 perms/models.py:91
#: perms/templates/perms/asset_permission_detail.html:102 settings/models.py:34 #: perms/templates/perms/asset_permission_detail.html:102 settings/models.py:34
#: terminal/models.py:32 terminal/templates/terminal/terminal_detail.html:63 #: terminal/models.py:32 terminal/templates/terminal/terminal_detail.html:63
#: users/models/group.py:15 users/models/user.py:87 #: users/models/group.py:15 users/models/user.py:94
#: users/templates/users/user_detail.html:127 #: users/templates/users/user_detail.html:127
#: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_detail.html:67
#: users/templates/users/user_group_list.html:14 #: users/templates/users/user_group_list.html:14
@ -554,7 +554,7 @@ msgstr "带宽"
msgid "Contact" msgid "Contact"
msgstr "联系人" msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:73 #: assets/models/cluster.py:22 users/models/user.py:80
#: users/templates/users/user_detail.html:76 #: users/templates/users/user_detail.html:76
msgid "Phone" msgid "Phone"
msgstr "手机" msgstr "手机"
@ -580,7 +580,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:473
msgid "System" msgid "System"
msgstr "系统" msgstr "系统"
@ -728,7 +728,7 @@ msgstr "默认资产组"
#: terminal/templates/terminal/command_list.html:72 #: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33 #: terminal/templates/terminal/session_list.html:33
#: terminal/templates/terminal/session_list.html:71 users/forms.py:283 #: terminal/templates/terminal/session_list.html:71 users/forms.py:283
#: users/models/user.py:32 users/models/user.py:445 #: users/models/user.py:36 users/models/user.py:461
#: users/templates/users/user_group_detail.html:78 #: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:386 #: users/templates/users/user_group_list.html:13 users/views/user.py:386
#: xpack/plugins/orgs/forms.py:26 #: xpack/plugins/orgs/forms.py:26
@ -827,7 +827,7 @@ msgid "%(value)s is not an even number"
msgstr "%(value)s is not an even number" msgstr "%(value)s is not an even number"
#: assets/serializers/asset_user.py:23 users/forms.py:230 #: assets/serializers/asset_user.py:23 users/forms.py:230
#: users/models/user.py:84 users/templates/users/first_login.html:42 #: users/models/user.py:91 users/templates/users/first_login.html:42
#: users/templates/users/user_password_update.html:46 #: users/templates/users/user_password_update.html:46
#: users/templates/users/user_profile.html:68 #: users/templates/users/user_profile.html:68
#: users/templates/users/user_profile_update.html:43 #: users/templates/users/user_profile_update.html:43
@ -1026,7 +1026,7 @@ msgstr "其它"
#: settings/templates/settings/command_storage_create.html:79 #: settings/templates/settings/command_storage_create.html:79
#: settings/templates/settings/email_setting.html:62 #: settings/templates/settings/email_setting.html:62
#: settings/templates/settings/ldap_setting.html:61 #: settings/templates/settings/ldap_setting.html:61
#: settings/templates/settings/replay_storage_create.html:151 #: settings/templates/settings/replay_storage_create.html:152
#: settings/templates/settings/security_setting.html:70 #: settings/templates/settings/security_setting.html:70
#: settings/templates/settings/terminal_setting.html:68 #: settings/templates/settings/terminal_setting.html:68
#: terminal/templates/terminal/terminal_update.html:45 #: terminal/templates/terminal/terminal_update.html:45
@ -1062,7 +1062,7 @@ msgstr "重置"
#: settings/templates/settings/command_storage_create.html:80 #: settings/templates/settings/command_storage_create.html:80
#: settings/templates/settings/email_setting.html:63 #: settings/templates/settings/email_setting.html:63
#: settings/templates/settings/ldap_setting.html:64 #: settings/templates/settings/ldap_setting.html:64
#: settings/templates/settings/replay_storage_create.html:152 #: settings/templates/settings/replay_storage_create.html:153
#: settings/templates/settings/security_setting.html:71 #: settings/templates/settings/security_setting.html:71
#: settings/templates/settings/terminal_setting.html:70 #: settings/templates/settings/terminal_setting.html:70
#: terminal/templates/terminal/command_list.html:103 #: terminal/templates/terminal/command_list.html:103
@ -1076,7 +1076,7 @@ msgstr "重置"
#: users/templates/users/user_profile_update.html:64 #: users/templates/users/user_profile_update.html:64
#: users/templates/users/user_pubkey_update.html:77 #: users/templates/users/user_pubkey_update.html:77
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:72 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:72
#: xpack/plugins/interface/templates/interface/interface.html:73 #: xpack/plugins/interface/templates/interface/interface.html:74
msgid "Submit" msgid "Submit"
msgstr "提交" msgstr "提交"
@ -1161,7 +1161,7 @@ msgstr "更新认证"
#: assets/templates/assets/system_user_asset.html:350 #: assets/templates/assets/system_user_asset.html:350
#: users/templates/users/user_detail.html:307 #: users/templates/users/user_detail.html:307
#: users/templates/users/user_detail.html:334 #: users/templates/users/user_detail.html:334
#: xpack/plugins/interface/views.py:31 #: xpack/plugins/interface/views.py:34
msgid "Update successfully!" msgid "Update successfully!"
msgstr "更新成功" msgstr "更新成功"
@ -1271,6 +1271,7 @@ msgstr "选择节点"
#: users/templates/users/user_profile.html:238 #: users/templates/users/user_profile.html:238
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:34 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:34
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:36 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:36
#: xpack/plugins/interface/templates/interface/interface.html:103
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:33 #: xpack/plugins/orgs/templates/orgs/org_create_update.html:33
msgid "Confirm" msgid "Confirm"
msgstr "确认" msgstr "确认"
@ -1500,6 +1501,7 @@ msgstr "重命名失败不能更改root节点的名称"
#: users/templates/users/user_detail.html:476 #: users/templates/users/user_detail.html:476
#: users/templates/users/user_group_list.html:82 #: users/templates/users/user_group_list.html:82
#: users/templates/users/user_list.html:202 #: users/templates/users/user_list.html:202
#: xpack/plugins/interface/templates/interface/interface.html:97
msgid "Are you sure?" msgid "Are you sure?"
msgstr "你确认吗?" msgstr "你确认吗?"
@ -1516,6 +1518,7 @@ msgstr "删除选择资产"
#: users/templates/users/user_group_create_update.html:31 #: users/templates/users/user_group_create_update.html:31
#: users/templates/users/user_group_list.html:86 #: users/templates/users/user_group_list.html:86
#: users/templates/users/user_list.html:206 #: users/templates/users/user_list.html:206
#: xpack/plugins/interface/templates/interface/interface.html:101
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:32 #: xpack/plugins/orgs/templates/orgs/org_create_update.html:32
msgid "Cancel" msgid "Cancel"
msgstr "取消" msgstr "取消"
@ -1938,7 +1941,7 @@ msgid "User agent"
msgstr "Agent" 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
#: users/forms.py:142 users/models/user.py:76 #: users/forms.py:142 users/models/user.py:83
#: users/templates/users/first_login.html:45 #: users/templates/users/first_login.html:45
msgid "MFA" msgid "MFA"
msgstr "MFA" msgstr "MFA"
@ -2125,7 +2128,17 @@ msgstr ""
msgid "Invalid token or cache refreshed." msgid "Invalid token or cache refreshed."
msgstr "" msgstr ""
#: authentication/forms.py:29 users/forms.py:21 #: authentication/forms.py:19
msgid ""
"Please enter a correct username and password. Note that both fields may be "
"case-sensitive."
msgstr "请输入正确的用户名和密码. 注意它们是区分大小写."
#: authentication/forms.py:22
msgid "This account is inactive."
msgstr "此账户无效"
#: authentication/forms.py:37 users/forms.py:21
msgid "MFA code" msgid "MFA code"
msgstr "MFA 验证码" msgstr "MFA 验证码"
@ -2687,7 +2700,7 @@ msgstr "组织管理"
#: perms/templates/perms/asset_permission_list.html:55 #: perms/templates/perms/asset_permission_list.html:55
#: perms/templates/perms/asset_permission_list.html:75 #: perms/templates/perms/asset_permission_list.html:75
#: perms/templates/perms/asset_permission_list.html:122 templates/_nav.html:14 #: perms/templates/perms/asset_permission_list.html:122 templates/_nav.html:14
#: users/forms.py:253 users/models/group.py:26 users/models/user.py:60 #: users/forms.py:253 users/models/group.py:26 users/models/user.py:67
#: users/templates/users/_select_user_modal.html:16 #: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_detail.html:213 #: users/templates/users/user_detail.html:213
#: users/templates/users/user_list.html:26 #: users/templates/users/user_list.html:26
@ -2705,7 +2718,7 @@ msgstr "资产和节点至少选一个"
#: perms/models.py:35 perms/models.py:88 #: perms/models.py:35 perms/models.py:88
#: perms/templates/perms/asset_permission_detail.html:90 #: perms/templates/perms/asset_permission_detail.html:90
#: users/models/user.py:92 users/templates/users/user_detail.html:107 #: users/models/user.py:99 users/templates/users/user_detail.html:107
#: users/templates/users/user_profile.html:116 #: users/templates/users/user_profile.html:116
msgid "Date expired" msgid "Date expired"
msgstr "失效日期" msgstr "失效日期"
@ -3123,7 +3136,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:56 users/templates/users/user_detail.html:71 #: users/models/user.py:63 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 "邮件"
@ -3431,7 +3444,7 @@ msgstr ""
#: templates/_nav.html:10 users/views/group.py:27 users/views/group.py:43 #: templates/_nav.html:10 users/views/group.py:27 users/views/group.py:43
#: users/views/group.py:59 users/views/group.py:75 users/views/group.py:91 #: users/views/group.py:59 users/views/group.py:75 users/views/group.py:91
#: users/views/login.py:151 users/views/user.py:68 users/views/user.py:83 #: users/views/login.py:153 users/views/user.py:68 users/views/user.py:83
#: users/views/user.py:113 users/views/user.py:194 users/views/user.py:355 #: users/views/user.py:113 users/views/user.py:194 users/views/user.py:355
#: users/views/user.py:405 users/views/user.py:445 #: users/views/user.py:405 users/views/user.py:445
msgid "Users" msgid "Users"
@ -3871,7 +3884,7 @@ msgstr "你可以使用ssh客户端工具连接终端"
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:32 users/models/user.py:64 #: users/forms.py:32 users/models/user.py:71
#: 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:25 #: users/templates/users/user_list.html:25
@ -3964,53 +3977,53 @@ msgstr "复制你的公钥到这里"
msgid "Select users" msgid "Select users"
msgstr "选择用户" msgstr "选择用户"
#: users/models/user.py:31 users/models/user.py:453 #: users/models/user.py:35 users/models/user.py:469
msgid "Administrator" msgid "Administrator"
msgstr "管理员" msgstr "管理员"
#: users/models/user.py:33 #: users/models/user.py:37
msgid "Application" msgid "Application"
msgstr "应用程序" msgstr "应用程序"
#: users/models/user.py:36 users/templates/users/user_profile.html:92 #: users/models/user.py:40 users/templates/users/user_profile.html:92
#: users/templates/users/user_profile.html:159 #: users/templates/users/user_profile.html:159
#: users/templates/users/user_profile.html:162 #: users/templates/users/user_profile.html:162
msgid "Disable" msgid "Disable"
msgstr "禁用" msgstr "禁用"
#: users/models/user.py:37 users/templates/users/user_profile.html:90 #: users/models/user.py:41 users/templates/users/user_profile.html:90
#: users/templates/users/user_profile.html:166 #: users/templates/users/user_profile.html:166
msgid "Enable" msgid "Enable"
msgstr "启用" msgstr "启用"
#: users/models/user.py:38 users/templates/users/user_profile.html:88 #: users/models/user.py:42 users/templates/users/user_profile.html:88
msgid "Force enable" msgid "Force enable"
msgstr "强制启用" msgstr "强制启用"
#: users/models/user.py:67 #: users/models/user.py:74
msgid "Avatar" msgid "Avatar"
msgstr "头像" msgstr "头像"
#: users/models/user.py:70 users/templates/users/user_detail.html:82 #: users/models/user.py:77 users/templates/users/user_detail.html:82
msgid "Wechat" msgid "Wechat"
msgstr "微信" msgstr "微信"
#: users/models/user.py:99 users/templates/users/user_detail.html:103 #: users/models/user.py:106 users/templates/users/user_detail.html:103
#: users/templates/users/user_list.html:27 #: users/templates/users/user_list.html:27
#: users/templates/users/user_profile.html:100 #: users/templates/users/user_profile.html:100
msgid "Source" msgid "Source"
msgstr "用户来源" msgstr "用户来源"
#: users/models/user.py:103 #: users/models/user.py:110
msgid "Date password last updated" msgid "Date password last updated"
msgstr "最后更新密码日期" msgstr "最后更新密码日期"
#: users/models/user.py:129 users/templates/users/user_update.html:22 #: users/models/user.py:136 users/templates/users/user_update.html:22
#: users/views/login.py:45 users/views/login.py:104 users/views/user.py:418 #: users/views/login.py:46 users/views/login.py:107 users/views/user.py:418
msgid "User auth from {}, go there change password" msgid "User auth from {}, go there change password"
msgstr "用户认证源来自 {}, 请去相应系统修改密码" msgstr "用户认证源来自 {}, 请去相应系统修改密码"
#: users/models/user.py:456 #: users/models/user.py:472
msgid "Administrator is the super user of system" msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员" msgstr "Administrator是初始的超级管理员"
@ -4658,40 +4671,40 @@ msgstr "更新用户组"
msgid "User group granted asset" msgid "User group granted asset"
msgstr "用户组授权资产" msgstr "用户组授权资产"
#: users/views/login.py:42 #: users/views/login.py:43
msgid "Email address invalid, please input again" msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入" msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:58 #: users/views/login.py:59
msgid "Send reset password message" msgid "Send reset password message"
msgstr "发送重置密码邮件" msgstr "发送重置密码邮件"
#: users/views/login.py:59 #: users/views/login.py:60
msgid "Send reset password mail success, login your mail box and follow it " msgid "Send reset password mail success, login your mail box and follow it "
msgstr "" msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:72 #: users/views/login.py:73
msgid "Reset password success" msgid "Reset password success"
msgstr "重置密码成功" msgstr "重置密码成功"
#: users/views/login.py:73 #: users/views/login.py:74
msgid "Reset password success, return to login page" msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面" msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:88 users/views/login.py:107 #: users/views/login.py:89 users/views/login.py:105
msgid "Token invalid or expired" msgid "Token invalid or expired"
msgstr "Token错误或失效" msgstr "Token错误或失效"
#: users/views/login.py:100 #: users/views/login.py:101
msgid "Password not same" msgid "Password not same"
msgstr "密码不一致" msgstr "密码不一致"
#: users/views/login.py:113 users/views/user.py:128 users/views/user.py:428 #: users/views/login.py:114 users/views/user.py:128 users/views/user.py:428
msgid "* Your password does not meet the requirements" msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求" msgstr "* 您的密码不符合要求"
#: users/views/login.py:151 #: users/views/login.py:153
msgid "First login" msgid "First login"
msgstr "首次登录" msgstr "首次登录"
@ -5217,14 +5230,40 @@ msgid "Interface settings"
msgstr "界面设置" msgstr "界面设置"
#: xpack/plugins/interface/templates/interface/interface.html:15 #: xpack/plugins/interface/templates/interface/interface.html:15
#: xpack/plugins/interface/views.py:21 #: xpack/plugins/interface/views.py:24
msgid "Interface setting" msgid "Interface setting"
msgstr "界面设置" msgstr "界面设置"
#: xpack/plugins/interface/views.py:20 #: xpack/plugins/interface/templates/interface/interface.html:73
#: xpack/plugins/interface/templates/interface/interface.html:108
#: xpack/plugins/interface/templates/interface/interface.html:115
msgid "Restore Default"
msgstr "恢复默认"
#: xpack/plugins/interface/templates/interface/interface.html:98
msgid "This will restore default Settings of the interface !!!"
msgstr "您确定要恢复默认初始化吗?"
#: xpack/plugins/interface/templates/interface/interface.html:107
msgid "Restore default successfully."
msgstr "恢复默认成功!"
#: xpack/plugins/interface/templates/interface/interface.html:114
msgid "Restore default failed."
msgstr "恢复默认失败!"
#: xpack/plugins/interface/views.py:23
msgid "Interface" msgid "Interface"
msgstr "界面" msgstr "界面"
#: xpack/plugins/interface/views.py:49
msgid "It is already in the default setting state"
msgstr "当前已经是初始化状态!"
#: xpack/plugins/interface/views.py:53
msgid "Restore default successfully"
msgstr "恢复默认成功!"
#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:94 #: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:94
#: xpack/plugins/license/templates/license/license_detail.html:50 #: xpack/plugins/license/templates/license/license_detail.html:50
#: xpack/plugins/license/views.py:31 #: xpack/plugins/license/views.py:31
@ -5233,7 +5272,7 @@ msgstr "许可证"
#: xpack/plugins/license/models.py:74 #: xpack/plugins/license/models.py:74
msgid "Standard edition" msgid "Standard edition"
msgstr "" msgstr "标准版"
#: xpack/plugins/license/models.py:76 #: xpack/plugins/license/models.py:76
msgid "Enterprise edition" msgid "Enterprise edition"

View File

@ -3,24 +3,28 @@
# #
import uuid import uuid
import base64 import base64
import string
import random
from collections import OrderedDict from collections import OrderedDict
from django.conf import settings from django.conf import settings
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.core import signing
from django.core.cache import cache from django.core.cache import cache
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.shortcuts import reverse from django.shortcuts import reverse
from common.utils import get_signer, date_expired_default from common.utils import get_signer, date_expired_default, get_logger
__all__ = ['User'] __all__ = ['User']
signer = get_signer() signer = get_signer()
logger = get_logger(__file__)
class User(AbstractUser): class User(AbstractUser):
ROLE_ADMIN = 'Admin' ROLE_ADMIN = 'Admin'
@ -47,6 +51,9 @@ class User(AbstractUser):
(SOURCE_OPENID, 'OpenID'), (SOURCE_OPENID, 'OpenID'),
(SOURCE_RADIUS, 'Radius'), (SOURCE_RADIUS, 'Radius'),
) )
CACHE_KEY_USER_RESET_PASSWORD_PREFIX = "_KEY_USER_RESET_PASSWORD_{}"
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
username = models.CharField( username = models.CharField(
max_length=128, unique=True, verbose_name=_('Username') max_length=128, unique=True, verbose_name=_('Username')
@ -346,9 +353,32 @@ class User(AbstractUser):
return user_default return user_default
def generate_reset_token(self): def generate_reset_token(self):
return signer.sign_t( letter = string.ascii_letters + string.digits
{'reset': str(self.id), 'email': self.email}, expires_in=3600 token =''.join([random.choice(letter) for _ in range(50)])
) self.set_cache(token)
return token
def set_cache(self, token):
key = self.CACHE_KEY_USER_RESET_PASSWORD_PREFIX.format(token)
cache.set(key, {'id': self.id, 'email': self.email}, 3600)
@classmethod
def validate_reset_password_token(cls, token):
try:
key = cls.CACHE_KEY_USER_RESET_PASSWORD_PREFIX.format(token)
value = cache.get(key)
user_id = value.get('id', '')
email = value.get('email', '')
user = cls.objects.get(id=user_id, email=email)
except (AttributeError, cls.DoesNotExist) as e:
logger.error(e, exc_info=True)
user = None
return user
@classmethod
def expired_reset_password_token(cls, token):
key = cls.CACHE_KEY_USER_RESET_PASSWORD_PREFIX.format(token)
cache.delete(key)
@property @property
def otp_enabled(self): def otp_enabled(self):
@ -400,18 +430,6 @@ class User(AbstractUser):
access_key = app.create_access_key() access_key = app.create_access_key()
return app, access_key return app, access_key
@classmethod
def validate_reset_token(cls, token):
try:
data = signer.unsign_t(token)
user_id = data.get('reset', None)
user_email = data.get('email', '')
user = cls.objects.get(id=user_id, email=user_email)
except (signing.BadSignature, cls.DoesNotExist):
user = None
return user
def reset_password(self, new_password): def reset_password(self, new_password):
self.set_password(new_password) self.set_password(new_password)
self.date_password_last_updated = timezone.now() self.date_password_last_updated = timezone.now()

View File

@ -1,6 +1,7 @@
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.cache import cache
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import RedirectView from django.views.generic import RedirectView
@ -84,7 +85,7 @@ class UserResetPasswordView(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
token = request.GET.get('token', '') token = request.GET.get('token', '')
user = User.validate_reset_token(token) user = User.validate_reset_password_token(token)
if not user: if not user:
kwargs.update({'errors': _('Token invalid or expired')}) kwargs.update({'errors': _('Token invalid or expired')})
else: else:
@ -100,12 +101,12 @@ class UserResetPasswordView(TemplateView):
if password != password_confirm: if password != password_confirm:
return self.get(request, errors=_('Password not same')) return self.get(request, errors=_('Password not same'))
user = User.validate_reset_token(token) user = User.validate_reset_password_token(token)
if not user:
return self.get(request, errors=_('Token invalid or expired'))
if not user.can_update_password(): if not user.can_update_password():
error = _('User auth from {}, go there change password'.format(user.source)) error = _('User auth from {}, go there change password'.format(user.source))
return self.get(request, errors=error) return self.get(request, errors=error)
if not user:
return self.get(request, errors=_('Token invalid or expired'))
is_ok = check_password_rules(password) is_ok = check_password_rules(password)
if not is_ok: if not is_ok:
@ -115,6 +116,7 @@ class UserResetPasswordView(TemplateView):
) )
user.reset_password(password) user.reset_password(password)
User.expired_reset_password_token(token)
return HttpResponseRedirect(reverse('users:reset-password-success')) return HttpResponseRedirect(reverse('users:reset-password-success'))