From b5fc76d6a5795a5727531c08099980f9e1989171 Mon Sep 17 00:00:00 2001 From: BaiJiangjie Date: Mon, 23 Apr 2018 21:04:46 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E9=A6=96=E6=AC=A1=E7=99=BB=E5=BD=95=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/i18n/zh/LC_MESSAGES/django.mo | Bin 31818 -> 32826 bytes apps/i18n/zh/LC_MESSAGES/django.po | 148 +++++++++++------- .../static/css/plugins/steps/jquery.steps.css | 1 - apps/templates/_message.html | 3 + apps/users/forms.py | 39 ++++- apps/users/models/user.py | 59 +++++-- apps/users/templates/users/_base_otp.html | 12 +- apps/users/templates/users/first_login.html | 141 ++++++++++++----- .../templates/users/first_login_done.html | 5 +- .../users/user_otp_authentication.html | 1 - apps/users/views/login.py | 15 +- 11 files changed, 297 insertions(+), 127 deletions(-) diff --git a/apps/i18n/zh/LC_MESSAGES/django.mo b/apps/i18n/zh/LC_MESSAGES/django.mo index 02cc25cf756d7e0244116a72bc1dc136cee13795..ebfffbfe748496f4dfd19f8c4ebf42f48a27d9ce 100644 GIT binary patch delta 12322 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 eky$EvTfTXCR@VL2`;xz2>kIufO{%e&^(7L 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 diff --git a/apps/i18n/zh/LC_MESSAGES/django.po b/apps/i18n/zh/LC_MESSAGES/django.po index 867fb4e55..627e44ed6 100644 --- a/apps/i18n/zh/LC_MESSAGES/django.po +++ b/apps/i18n/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: 2018-04-20 16:08+0800\n" +"POT-Creation-Date: 2018-04-23 19:51+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: Jumpserver team\n" @@ -137,7 +137,7 @@ msgstr "资产" #: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:16 #: terminal/models.py:149 terminal/templates/terminal/terminal_detail.html:43 #: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14 -#: users/models/user.py:40 users/templates/users/_select_user_modal.html:13 +#: users/models/user.py:42 users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_detail.html:63 #: users/templates/users/user_group_detail.html:55 #: users/templates/users/user_group_list.html:12 @@ -154,7 +154,7 @@ msgstr "名称" #: assets/templates/assets/system_user_detail.html:62 #: assets/templates/assets/system_user_list.html:27 #: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13 -#: users/forms.py:22 users/models/authentication.py:45 users/models/user.py:39 +#: users/forms.py:22 users/models/authentication.py:45 users/models/user.py:40 #: users/templates/users/_select_user_modal.html:14 #: users/templates/users/login.html:56 #: users/templates/users/login_log_list.html:49 @@ -180,7 +180,7 @@ msgstr "密码或密钥密码" msgid "Password" msgstr "密码" -#: assets/forms/user.py:28 users/models/user.py:50 +#: assets/forms/user.py:28 users/models/user.py:69 msgid "Private key" msgstr "ssh私钥" @@ -312,7 +312,7 @@ msgstr "标签管理" #: assets/templates/assets/system_user_detail.html:96 #: ops/templates/ops/adhoc_detail.html:86 perms/models.py:28 perms/models.py:72 #: perms/templates/perms/asset_permission_detail.html:98 -#: users/models/user.py:55 users/templates/users/user_detail.html:107 +#: users/models/user.py:83 users/templates/users/user_detail.html:107 msgid "Created by" msgstr "创建者" @@ -343,7 +343,7 @@ msgstr "创建日期" #: ops/models/adhoc.py:42 perms/models.py:30 perms/models.py:74 #: perms/templates/perms/asset_permission_detail.html:102 terminal/models.py:26 #: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15 -#: users/models/user.py:52 users/templates/users/user_detail.html:119 +#: users/models/user.py:75 users/templates/users/user_detail.html:119 #: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_list.html:14 #: users/templates/users/user_profile.html:123 @@ -366,7 +366,7 @@ msgstr "带宽" msgid "Contact" msgstr "联系人" -#: assets/models/cluster.py:22 users/models/user.py:46 +#: assets/models/cluster.py:22 users/models/user.py:61 #: users/templates/users/user_detail.html:76 msgid "Phone" msgstr "手机" @@ -392,7 +392,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:13 -#: users/models/user.py:299 +#: users/models/user.py:330 msgid "System" msgstr "系统" @@ -430,8 +430,8 @@ msgstr "默认资产组" #: terminal/templates/terminal/command_list.html:32 #: terminal/templates/terminal/command_list.html:72 #: terminal/templates/terminal/session_list.html:33 -#: terminal/templates/terminal/session_list.html:71 users/forms.py:237 -#: users/models/user.py:30 users/models/user.py:287 +#: terminal/templates/terminal/session_list.html:71 users/forms.py:273 +#: users/models/user.py:30 users/models/user.py:318 #: users/templates/users/user_group_detail.html:78 #: users/templates/users/user_group_list.html:13 users/views/user.py:339 msgid "User" @@ -663,7 +663,6 @@ msgstr "重置" #: terminal/templates/terminal/session_list.html:120 #: terminal/templates/terminal/terminal_update.html:48 #: users/templates/users/_user.html:47 -#: users/templates/users/first_login.html:62 #: users/templates/users/forgot_password.html:44 #: users/templates/users/user_bulk_update.html:24 #: users/templates/users/user_list.html:44 @@ -1704,15 +1703,15 @@ msgstr "任务列表" msgid "Task run history" msgstr "执行历史" -#: perms/forms.py:18 users/forms.py:194 users/forms.py:199 users/forms.py:211 -#: users/forms.py:241 +#: perms/forms.py:18 users/forms.py:230 users/forms.py:235 users/forms.py:247 +#: users/forms.py:277 msgid "Select users" msgstr "选择用户" #: perms/forms.py:34 perms/models.py:21 perms/models.py:68 #: perms/templates/perms/asset_permission_list.html:55 #: perms/templates/perms/asset_permission_list.html:136 templates/_nav.html:14 -#: users/models/group.py:25 users/models/user.py:42 +#: users/models/group.py:25 users/models/user.py:48 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_detail.html:188 #: users/templates/users/user_list.html:26 @@ -1729,7 +1728,7 @@ msgstr "" #: perms/models.py:27 perms/models.py:71 #: perms/templates/perms/asset_permission_detail.html:90 -#: users/models/user.py:54 users/templates/users/user_detail.html:103 +#: users/models/user.py:80 users/templates/users/user_detail.html:103 #: users/templates/users/user_profile.html:105 msgid "Date expired" msgstr "失效日期" @@ -1853,8 +1852,9 @@ msgstr "商业支持" msgid "Docs" msgstr "文档" -#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:111 +#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:113 #: users/templates/users/_user.html:39 +#: users/templates/users/first_login.html:39 #: users/templates/users/user_password_update.html:37 #: users/templates/users/user_profile.html:17 #: users/templates/users/user_profile_update.html:37 @@ -1897,7 +1897,7 @@ msgstr "" " 补充完整\n" " " -#: templates/_message.html:17 +#: templates/_message.html:20 #, python-format msgid "" "\n" @@ -1916,7 +1916,7 @@ msgstr "关闭" #: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44 #: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95 -#: users/views/login.py:241 users/views/login.py:290 users/views/user.py:64 +#: users/views/login.py:241 users/views/login.py:289 users/views/user.py:64 #: users/views/user.py:79 users/views/user.py:99 users/views/user.py:155 #: users/views/user.py:310 users/views/user.py:357 users/views/user.py:379 msgid "Users" @@ -2232,7 +2232,7 @@ msgstr "" msgid "MFA code" msgstr "MFA 验证码" -#: users/forms.py:40 users/models/user.py:43 +#: users/forms.py:41 users/models/user.py:52 #: users/templates/users/_select_user_modal.html:15 #: users/templates/users/user_detail.html:87 #: users/templates/users/user_list.html:25 @@ -2240,55 +2240,92 @@ msgstr "MFA 验证码" msgid "Role" msgstr "角色" -#: users/forms.py:42 users/forms.py:157 +#: users/forms.py:44 users/forms.py:193 msgid "ssh public key" msgstr "ssh公钥" -#: users/forms.py:43 users/forms.py:158 +#: users/forms.py:45 users/forms.py:194 msgid "ssh-rsa AAAA..." msgstr "" -#: users/forms.py:44 +#: users/forms.py:46 msgid "Paste user id_rsa.pub here." msgstr "复制用户公钥到这里" -#: users/forms.py:62 users/templates/users/user_detail.html:196 +#: users/forms.py:64 users/templates/users/user_detail.html:196 msgid "Join user groups" msgstr "添加到用户组" -#: users/forms.py:73 users/forms.py:172 +#: users/forms.py:75 users/forms.py:208 msgid "Public key should not be the same as your old one." msgstr "不能和原来的密钥相同" -#: users/forms.py:77 users/forms.py:176 users/serializers.py:45 +#: users/forms.py:79 users/forms.py:212 users/serializers.py:45 msgid "Not a valid ssh public key" msgstr "ssh密钥不合法" -#: users/forms.py:117 +#: users/forms.py:119 +msgid "" +"Tip: when enabled, you will enter the MFA binding process the next time you " +"log in. you can also directly bind in \"personal information -> quick " +"modification -> change MFA Settings\"!" +msgstr "" +"提示:启用之后您将会在下次登录时进入MFA绑定流程;您也可以在(个人信息->快速修" +"改->更改MFA设置)中直接绑定!" + +#: users/forms.py:129 +msgid "* Enable MFA authentication to make the account more secure." +msgstr "* 启用MFA认证,使账号更加安全." + +#: users/forms.py:134 users/models/user.py:64 +#: users/templates/users/first_login.html:45 +msgid "MFA" +msgstr "MFA" + +#: users/forms.py:139 +msgid "" +"In order to protect you and your company, please keep your account, password " +"and key sensitive information properly. (for example: setting complex " +"password, enabling MFA authentication)" +msgstr "" +"为了保护您和公司的安全,请妥善保管您的账户、密码和密钥等重要敏感信息;(如:" +"设置复杂密码,启用MFA认证)" + +#: users/forms.py:146 users/templates/users/first_login.html:48 +#: users/templates/users/first_login.html:110 +msgid "Finish" +msgstr "完成" + +#: users/forms.py:152 msgid "Old password" msgstr "原来密码" -#: users/forms.py:122 +#: users/forms.py:157 msgid "New password" msgstr "新密码" -#: users/forms.py:127 +#: users/forms.py:162 msgid "Confirm password" msgstr "确认密码" -#: users/forms.py:137 +#: users/forms.py:172 msgid "Old password error" msgstr "原来密码错误" -#: users/forms.py:145 +#: users/forms.py:180 msgid "Password does not match" msgstr "密码不一致" -#: users/forms.py:159 +#: users/forms.py:191 +msgid "Automatically configure and download the SSH key" +msgstr "自动配置并下载SSH密钥" + +#: users/forms.py:195 msgid "Paste your id_rsa.pub here." msgstr "复制你的公钥到这里" -#: users/forms.py:187 users/models/user.py:51 +#: users/forms.py:223 users/models/user.py:72 +#: users/templates/users/first_login.html:42 #: users/templates/users/user_password_update.html:43 #: users/templates/users/user_profile.html:68 #: users/templates/users/user_profile_update.html:43 @@ -2320,7 +2357,7 @@ msgstr "Agent" msgid "Date login" msgstr "登录日期" -#: users/models/user.py:29 users/models/user.py:295 +#: users/models/user.py:29 users/models/user.py:326 msgid "Administrator" msgstr "管理员" @@ -2343,24 +2380,20 @@ msgstr "启用" msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:41 users/templates/users/user_detail.html:71 +#: users/models/user.py:44 users/templates/users/user_detail.html:71 #: users/templates/users/user_profile.html:59 msgid "Email" msgstr "邮件" -#: users/models/user.py:44 +#: users/models/user.py:55 msgid "Avatar" msgstr "头像" -#: users/models/user.py:45 users/templates/users/user_detail.html:82 +#: users/models/user.py:58 users/templates/users/user_detail.html:82 msgid "Wechat" msgstr "微信" -#: users/models/user.py:47 -msgid "MFA" -msgstr "MFA" - -#: users/models/user.py:298 +#: users/models/user.py:329 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" @@ -2401,20 +2434,20 @@ msgstr "如果设置了id,则会使用该行信息更新该id的用户" msgid "Update User SSH Public Key" msgstr "更新ssh密钥" -#: users/templates/users/first_login.html:18 -#: users/templates/users/first_login_done.html:18 +#: users/templates/users/first_login.html:19 +#: users/templates/users/first_login_done.html:19 msgid "First Login" msgstr "首次登陆" -#: users/templates/users/first_login.html:35 -msgid "Step" -msgstr "Step" +#: users/templates/users/first_login.html:72 +msgid "I agree with the terms and conditions." +msgstr "我同意条款和条件" -#: users/templates/users/first_login.html:57 +#: users/templates/users/first_login.html:100 msgid "Previous" msgstr "上一步" -#: users/templates/users/first_login.html:60 +#: users/templates/users/first_login.html:108 #: users/templates/users/login_otp.html:66 #: users/templates/users/user_otp_authentication.html:22 #: users/templates/users/user_otp_enable_bind.html:19 @@ -2423,15 +2456,15 @@ msgstr "上一步" msgid "Next" msgstr "下一步" -#: users/templates/users/first_login_done.html:30 +#: users/templates/users/first_login_done.html:31 msgid "Welcome to use jumpserver, visit " msgstr "欢迎使用Jumpserver开源跳板机系统" -#: users/templates/users/first_login_done.html:31 +#: users/templates/users/first_login_done.html:32 msgid "Use guide" msgstr "向导" -#: users/templates/users/first_login_done.html:31 +#: users/templates/users/first_login_done.html:32 msgid " for more information" msgstr "获取更多信息" @@ -2843,19 +2876,19 @@ msgid "Send reset password mail success, login your mail box and follow it " msgstr "" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" -#: users/views/login.py:178 +#: users/views/login.py:177 msgid "Reset password success" msgstr "重置密码成功" -#: users/views/login.py:179 +#: users/views/login.py:178 msgid "Reset password success, return to login page" msgstr "重置密码成功,返回到登录页面" -#: users/views/login.py:196 users/views/login.py:209 +#: users/views/login.py:195 users/views/login.py:208 msgid "Token invalid or expired" msgstr "Token错误或失效" -#: users/views/login.py:205 +#: users/views/login.py:204 msgid "Password not same" msgstr "密码不一致" @@ -2863,7 +2896,7 @@ msgstr "密码不一致" msgid "First login" msgstr "首次登陆" -#: users/views/login.py:291 +#: users/views/login.py:290 msgid "Login log list" msgstr "登录日志" @@ -2911,5 +2944,8 @@ msgstr "MFA 解绑成功" msgid "MFA disable success, return login page" msgstr "MFA 解绑成功,返回登录页面" +#~ msgid "Step" +#~ msgstr "Step" + #~ msgid "Add asset" #~ msgstr "添加资产到节点" diff --git a/apps/static/css/plugins/steps/jquery.steps.css b/apps/static/css/plugins/steps/jquery.steps.css index 95634b32d..534a06c3a 100644 --- a/apps/static/css/plugins/steps/jquery.steps.css +++ b/apps/static/css/plugins/steps/jquery.steps.css @@ -220,7 +220,6 @@ position: relative; display: block; text-align: right; - width: 100%; } .wizard.vertical > .actions diff --git a/apps/templates/_message.html b/apps/templates/_message.html index 54754536a..9c64a441f 100644 --- a/apps/templates/_message.html +++ b/apps/templates/_message.html @@ -6,9 +6,12 @@ {% blocktrans %} Your information was incomplete. Please click this link to complete your information. {% endblocktrans %} + + {% endif %} {% endblock %} + {% block update_public_key_message %} {% if request.user.is_authenticated and not request.user.is_public_key_valid and not request.COOKIE.close_public_key_msg != '1' %}
diff --git a/apps/users/forms.py b/apps/users/forms.py index 8af750eae..f6c02ff23 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -36,7 +36,10 @@ class UserCreateUpdateForm(forms.ModelForm): label=_('Password'), widget=forms.PasswordInput, max_length=128, strip=False, required=False, ) - role = forms.ChoiceField(choices=role_choices, required=True, initial=User.ROLE_USER, label=_("Role")) + role = forms.ChoiceField( + choices=role_choices, required=True, + initial=User.ROLE_USER, label=_("Role") + ) public_key = forms.CharField( label=_('ssh public key'), max_length=5000, required=False, widget=forms.Textarea(attrs={'placeholder': _('ssh-rsa AAAA...')}), @@ -110,6 +113,39 @@ class UserProfileForm(forms.ModelForm): UserProfileForm.verbose_name = _("Profile") +class UserMFAForm(forms.ModelForm): + + mfa_description = _( + 'Tip: when enabled, ' + 'you will enter the MFA binding process the next time you log in. ' + 'you can also directly bind in ' + '"personal information -> quick modification -> change MFA Settings"!') + + class Meta: + model = User + fields = ['otp_level'] + widgets = {'otp_level': forms.RadioSelect()} + help_texts = { + 'otp_level': _('* Enable MFA authentication ' + 'to make the account more secure.'), + } + + +UserMFAForm.verbose_name = _("MFA") + + +class UserFirstLoginFinishForm(forms.Form): + finish_description = _( + 'In order to protect you and your company, ' + 'please keep your account, ' + 'password and key sensitive information properly. ' + '(for example: setting complex password, enabling MFA authentication)' + ) + + +UserFirstLoginFinishForm.verbose_name = _("Finish") + + class UserPasswordForm(forms.Form): old_password = forms.CharField( max_length=128, widget=forms.PasswordInput, @@ -152,6 +188,7 @@ class UserPasswordForm(forms.Form): class UserPublicKeyForm(forms.Form): + pubkey_description = _('Automatically configure and download the SSH key') public_key = forms.CharField( label=_('ssh public key'), max_length=5000, required=False, widget=forms.Textarea(attrs={'placeholder': _('ssh-rsa AAAA...')}), diff --git a/apps/users/models/user.py b/apps/users/models/user.py index f68483907..23c30cf77 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -36,23 +36,52 @@ class User(AbstractUser): (2, _("Force enable")), ) id = models.UUIDField(default=uuid.uuid4, primary_key=True) - username = models.CharField(max_length=128, unique=True, verbose_name=_('Username')) + username = models.CharField( + max_length=128, unique=True, verbose_name=_('Username') + ) name = models.CharField(max_length=128, verbose_name=_('Name')) - email = models.EmailField(max_length=128, unique=True, verbose_name=_('Email')) - groups = models.ManyToManyField('users.UserGroup', related_name='users', blank=True, verbose_name=_('User group')) - role = models.CharField(choices=ROLE_CHOICES, default='User', max_length=10, blank=True, verbose_name=_('Role')) - avatar = models.ImageField(upload_to="avatar", null=True, verbose_name=_('Avatar')) - wechat = models.CharField(max_length=128, blank=True, verbose_name=_('Wechat')) - phone = models.CharField(max_length=20, blank=True, null=True, verbose_name=_('Phone')) - otp_level = models.SmallIntegerField(default=0, choices=OTP_LEVEL_CHOICES, verbose_name=_('MFA')) + email = models.EmailField( + max_length=128, unique=True, verbose_name=_('Email') + ) + groups = models.ManyToManyField( + 'users.UserGroup', related_name='users', + blank=True, verbose_name=_('User group') + ) + role = models.CharField( + choices=ROLE_CHOICES, default='User', max_length=10, + blank=True, verbose_name=_('Role') + ) + avatar = models.ImageField( + upload_to="avatar", null=True, verbose_name=_('Avatar') + ) + wechat = models.CharField( + max_length=128, blank=True, verbose_name=_('Wechat') + ) + phone = models.CharField( + max_length=20, blank=True, null=True, verbose_name=_('Phone') + ) + otp_level = models.SmallIntegerField( + default=0, choices=OTP_LEVEL_CHOICES, verbose_name=_('MFA') + ) _otp_secret_key = models.CharField(max_length=128, blank=True, null=True) # Todo: Auto generate key, let user download - _private_key = models.CharField(max_length=5000, blank=True, verbose_name=_('Private key')) - _public_key = models.CharField(max_length=5000, blank=True, verbose_name=_('Public key')) - comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment')) + _private_key = models.CharField( + max_length=5000, blank=True, verbose_name=_('Private key') + ) + _public_key = models.CharField( + max_length=5000, blank=True, verbose_name=_('Public key') + ) + comment = models.TextField( + max_length=200, blank=True, verbose_name=_('Comment') + ) is_first_login = models.BooleanField(default=True) - date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name=_('Date expired')) - created_by = models.CharField(max_length=30, default='', verbose_name=_('Created by')) + date_expired = models.DateTimeField( + default=date_expired_default, blank=True, null=True, + verbose_name=_('Date expired') + ) + created_by = models.CharField( + max_length=30, default='', verbose_name=_('Created by') + ) def __str__(self): return '{0.name}({0.username})'.format(self) @@ -213,7 +242,9 @@ class User(AbstractUser): return user_default def generate_reset_token(self): - return signer.sign_t({'reset': str(self.id), 'email': self.email}, expires_in=3600) + return signer.sign_t( + {'reset': str(self.id), 'email': self.email}, expires_in=3600 + ) @property def otp_enabled(self): diff --git a/apps/users/templates/users/_base_otp.html b/apps/users/templates/users/_base_otp.html index a6eca32d9..755f5d5c9 100644 --- a/apps/users/templates/users/_base_otp.html +++ b/apps/users/templates/users/_base_otp.html @@ -74,13 +74,11 @@ -
- -
- {% include '_copyright.html' %} -
- -
+
+
+ {% include '_copyright.html' %} +
+
diff --git a/apps/users/templates/users/first_login.html b/apps/users/templates/users/first_login.html index b670caf60..7138199a3 100644 --- a/apps/users/templates/users/first_login.html +++ b/apps/users/templates/users/first_login.html @@ -9,6 +9,7 @@ {% endblock %} {% block first_login_message %}{% endblock %} + {% block content %}
@@ -27,58 +28,116 @@
-
- -
-
-
- {% csrf_token %} - {{ wizard.management_form }} - {% if wizard.form.forms %} - {{ wizard.form.management_form }} - {% for form in wizard.form.forms %} - {% bootstrap_form form %} - {% endfor %} - {% else %} - {% bootstrap_form wizard.form %} - {% endif %} -
-
+ +
+
+
+ {% csrf_token %} + {{ wizard.management_form }} + {#{% if wizard.form.forms %}#} + {#{{ wizard.form.management_form }}#} + {#{% for form in wizard.form %}#} + {#{% bootstrap_form form %}#} + {#{% endfor %}#} + {#{% else %}#} + {#{% endif %}#} + {% if form.finish_description %} + {{ form.finish_description }} +
+ + + {% endif %} + + {% bootstrap_form wizard.form %} + + {% if form.mfa_description %} + {{ form.mfa_description }} + {% endif %} + + {% if form.pubkey_description %} + 或者: + {{ form.pubkey_description }} + {% endif %} + +
+
+
+
+ +
+
+
+
+
+
- +
+
+
+
{% endblock %} + {% block custom_foot_js %} {% endblock %} diff --git a/apps/users/templates/users/first_login_done.html b/apps/users/templates/users/first_login_done.html index b75c91a99..5639d2c5d 100644 --- a/apps/users/templates/users/first_login_done.html +++ b/apps/users/templates/users/first_login_done.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% load static %} {% load i18n %} -{% load bootstrap3 %} +{% load bootstrap3 %} {% block custom_head_css_js %} @@ -9,6 +9,7 @@ {% endblock %} {% block first_login_message %}{% endblock %} + {% block content %}
@@ -36,6 +37,8 @@
{% endblock %} + + {% block custom_foot_js %}