Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
5c17b1a7
Unverified
Commit
5c17b1a7
authored
Apr 25, 2018
by
老广
Committed by
GitHub
Apr 25, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1240 from jumpserver/dev
首次登陆免验证码,首次登录信息变更
parents
e865484a
ea2863a5
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
394 additions
and
116 deletions
+394
-116
__init__.py
apps/__init__.py
+1
-1
asset_create.html
apps/assets/templates/assets/asset_create.html
+13
-1
asset.py
apps/assets/views/asset.py
+4
-1
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+101
-66
jquery.steps.css
apps/static/css/plugins/steps/jquery.steps.css
+0
-1
_footer.html
apps/templates/_footer.html
+1
-1
_message.html
apps/templates/_message.html
+5
-0
api.py
apps/users/api.py
+2
-2
forms.py
apps/users/forms.py
+53
-3
user.py
apps/users/models/user.py
+45
-14
_base_otp.html
apps/users/templates/users/_base_otp.html
+0
-2
_user.html
apps/users/templates/users/_user.html
+4
-1
first_login.html
apps/users/templates/users/first_login.html
+72
-13
first_login_done.html
apps/users/templates/users/first_login_done.html
+3
-0
login.html
apps/users/templates/users/login.html
+1
-1
user_create.html
apps/users/templates/users/user_create.html
+2
-2
user_list.html
apps/users/templates/users/user_list.html
+3
-0
user_otp_authentication.html
apps/users/templates/users/user_otp_authentication.html
+0
-1
user_update.html
apps/users/templates/users/user_update.html
+0
-1
login.py
apps/users/views/login.py
+29
-5
upgrade.sh
utils/upgrade.sh
+55
-0
No files found.
apps/__init__.py
View file @
5c17b1a7
...
...
@@ -2,4 +2,4 @@
# -*- coding: utf-8 -*-
#
__version__
=
"1.2.
0
"
__version__
=
"1.2.
1
"
apps/assets/templates/assets/asset_create.html
View file @
5c17b1a7
...
...
@@ -15,9 +15,9 @@
{% csrf_token %}
<h3>
{% trans 'Basic' %}
</h3>
{% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
{% bootstrap_field form.domain layout="horizontal" %}
...
...
@@ -85,6 +85,17 @@ $(document).ready(function () {
allowClear
:
true
,
templateSelection
:
format
});
$
(
"#id_platform"
).
change
(
function
(){
var
platform
=
$
(
"#id_platform option:selected"
).
text
();
var
port
=
22
;
if
(
platform
===
'Windows'
){
port
=
3389
;
}
if
(
platform
===
'Other'
){
port
=
null
;
}
$
(
"#id_port"
).
val
(
port
);
});
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/views/asset.py
View file @
5c17b1a7
...
...
@@ -304,7 +304,10 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
if
v
!=
''
:
asset_dict
[
k
]
=
v
asset
=
get_object_or_none
(
Asset
,
id
=
asset_dict
.
pop
(
'id'
,
0
))
asset
=
None
asset_id
=
asset_dict
.
pop
(
'id'
,
None
)
if
asset_id
:
asset
=
get_object_or_none
(
Asset
,
id
=
asset_id
)
if
not
asset
:
try
:
if
len
(
Asset
.
objects
.
filter
(
hostname
=
asset_dict
.
get
(
'hostname'
))):
...
...
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
5c17b1a7
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
5c17b1a7
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-2
0 11:17
+0800\n"
"POT-Creation-Date: 2018-04-2
3 19:51
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\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:4
0
users/templates/users/_select_user_modal.html:13
#: users/models/user.py:4
2
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
...
...
@@ -172,7 +172,7 @@ msgstr "密码或密钥密码"
#: users/forms.py:15 users/forms.py:24 users/forms.py:36
#: users/templates/users/login.html:59
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:1
1
#: users/templates/users/user_create.html:1
0
#: users/templates/users/user_password_authentication.html:14
#: users/templates/users/user_password_update.html:40
#: users/templates/users/user_profile_update.html:40
...
...
@@ -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:2
31
#: users/models/user.py:30 users/models/user.py:
287
#: terminal/templates/terminal/session_list.html:71 users/forms.py:2
73
#: 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"
...
...
@@ -605,8 +605,7 @@ msgstr "基本"
#: assets/templates/assets/asset_update.html:30
#: assets/templates/assets/gateway_create_update.html:45
#: assets/templates/assets/system_user_update.html:7
#: users/templates/users/user_create.html:9
#: users/templates/users/user_update.html:6
#: users/templates/users/_user.html:21
msgid "Auth"
msgstr "认证"
...
...
@@ -637,7 +636,7 @@ msgstr "其它"
#: common/templates/common/terminal_setting.html:101
#: perms/templates/perms/asset_permission_create_update.html:69
#: terminal/templates/terminal/terminal_update.html:47
#: users/templates/users/_user.html:4
3
#: users/templates/users/_user.html:4
6
#: users/templates/users/user_bulk_update.html:23
#: users/templates/users/user_password_update.html:58
#: users/templates/users/user_profile.html:181
...
...
@@ -663,8 +662,7 @@ msgstr "重置"
#: perms/templates/perms/asset_permission_create_update.html:70
#: terminal/templates/terminal/session_list.html:120
#: terminal/templates/terminal/terminal_update.html:48
#: users/templates/users/_user.html:44
#: users/templates/users/first_login.html:62
#: users/templates/users/_user.html:47
#: users/templates/users/forgot_password.html:44
#: users/templates/users/user_bulk_update.html:24
#: users/templates/users/user_list.html:44
...
...
@@ -1705,15 +1703,15 @@ msgstr "任务列表"
msgid "Task run history"
msgstr "执行历史"
#: perms/forms.py:18 users/forms.py:
188 users/forms.py:193 users/forms.py:205
#: users/forms.py:2
35
#: perms/forms.py:18 users/forms.py:
230 users/forms.py:235 users/forms.py:247
#: users/forms.py:2
77
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:4
2
#: users/models/group.py:25 users/models/user.py:4
8
#: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_detail.html:188
#: users/templates/users/user_list.html:26
...
...
@@ -1730,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 "失效日期"
...
...
@@ -1854,8 +1852,9 @@ msgstr "商业支持"
msgid "Docs"
msgstr "文档"
#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:105
#: users/templates/users/_user.html:36
#: 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
...
...
@@ -1898,7 +1897,7 @@ msgstr ""
"</a> 补充完整\n"
" "
#: templates/_message.html:
17
#: templates/_message.html:
20
#, python-format
msgid ""
"\n"
...
...
@@ -1917,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:2
90
users/views/user.py:64
#: users/views/login.py:241 users/views/login.py:2
89
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"
...
...
@@ -2230,10 +2229,10 @@ msgid "Invalid token or cache refreshed."
msgstr ""
#: users/forms.py:30
msgid "MFA
_
code"
msgstr ""
msgid "MFA
code"
msgstr "
MFA 验证码
"
#: users/forms.py:
39 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
...
...
@@ -2241,55 +2240,92 @@ msgstr ""
msgid "Role"
msgstr "角色"
#: users/forms.py:4
1 users/forms.py:151
#: users/forms.py:4
4 users/forms.py:193
msgid "ssh public key"
msgstr "ssh公钥"
#: users/forms.py:4
2 users/forms.py:152
#: users/forms.py:4
5 users/forms.py:194
msgid "ssh-rsa AAAA..."
msgstr ""
#: users/forms.py:4
3
#: users/forms.py:4
6
msgid "Paste user id_rsa.pub here."
msgstr "复制用户公钥到这里"
#: users/forms.py:6
1
users/templates/users/user_detail.html:196
#: users/forms.py:6
4
users/templates/users/user_detail.html:196
msgid "Join user groups"
msgstr "添加到用户组"
#: users/forms.py:7
1 users/forms.py:166
#: users/forms.py:7
5 users/forms.py:208
msgid "Public key should not be the same as your old one."
msgstr "不能和原来的密钥相同"
#: users/forms.py:7
5 users/forms.py:170
users/serializers.py:45
#: users/forms.py:7
9 users/forms.py:212
users/serializers.py:45
msgid "Not a valid ssh public key"
msgstr "ssh密钥不合法"
#: users/forms.py:111
#: 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:1
16
#: users/forms.py:1
57
msgid "New password"
msgstr "新密码"
#: users/forms.py:1
21
#: users/forms.py:1
62
msgid "Confirm password"
msgstr "确认密码"
#: users/forms.py:1
31
#: users/forms.py:1
72
msgid "Old password error"
msgstr "原来密码错误"
#: users/forms.py:1
39
#: users/forms.py:1
80
msgid "Password does not match"
msgstr "密码不一致"
#: users/forms.py:153
#: 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:181 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
...
...
@@ -2321,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 "管理员"
...
...
@@ -2344,24 +2380,20 @@ msgstr "启用"
msgid "Force enable"
msgstr "强制启用"
#: users/models/user.py:4
1
users/templates/users/user_detail.html:71
#: users/models/user.py:4
4
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 "Enable OTP"
msgstr "二次验证"
#: users/models/user.py:298
#: users/models/user.py:329
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
...
...
@@ -2378,7 +2410,7 @@ msgstr "资产数量"
msgid "Account"
msgstr "账户"
#: users/templates/users/_user.html:2
3
#: users/templates/users/_user.html:2
6
msgid "Security and Role"
msgstr "角色安全"
...
...
@@ -2402,20 +2434,20 @@ msgstr "如果设置了id,则会使用该行信息更新该id的用户"
msgid "Update User SSH Public Key"
msgstr "更新ssh密钥"
#: users/templates/users/first_login.html:1
8
#: users/templates/users/first_login_done.html:1
8
#: users/templates/users/first_login.html:1
9
#: users/templates/users/first_login_done.html:1
9
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
...
...
@@ -2424,15 +2456,15 @@ msgstr "上一步"
msgid "Next"
msgstr "下一步"
#: users/templates/users/first_login_done.html:3
0
#: users/templates/users/first_login_done.html:3
1
msgid "Welcome to use jumpserver, visit "
msgstr "欢迎使用Jumpserver开源跳板机系统"
#: users/templates/users/first_login_done.html:3
1
#: users/templates/users/first_login_done.html:3
2
msgid "Use guide"
msgstr "向导"
#: users/templates/users/first_login_done.html:3
1
#: users/templates/users/first_login_done.html:3
2
msgid " for more information"
msgstr "获取更多信息"
...
...
@@ -2492,7 +2524,7 @@ msgstr "设置"
msgid "Create user"
msgstr "创建用户"
#: users/templates/users/user_create.html:1
3
#: users/templates/users/user_create.html:1
2
msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户"
...
...
@@ -2844,19 +2876,19 @@ msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:17
8
#: users/views/login.py:17
7
msgid "Reset password success"
msgstr "重置密码成功"
#: users/views/login.py:17
9
#: users/views/login.py:17
8
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:19
6 users/views/login.py:209
#: users/views/login.py:19
5 users/views/login.py:208
msgid "Token invalid or expired"
msgstr "Token错误或失效"
#: users/views/login.py:20
5
#: users/views/login.py:20
4
msgid "Password not same"
msgstr "密码不一致"
...
...
@@ -2864,7 +2896,7 @@ msgstr "密码不一致"
msgid "First login"
msgstr "首次登陆"
#: users/views/login.py:29
1
#: users/views/login.py:29
0
msgid "Login log list"
msgstr "登录日志"
...
...
@@ -2912,5 +2944,8 @@ msgstr "MFA 解绑成功"
msgid "MFA disable success, return login page"
msgstr "MFA 解绑成功,返回登录页面"
#~ msgid "Step"
#~ msgstr "Step"
#~ msgid "Add asset"
#~ msgstr "添加资产到节点"
apps/static/css/plugins/steps/jquery.steps.css
View file @
5c17b1a7
...
...
@@ -220,7 +220,6 @@
position
:
relative
;
display
:
block
;
text-align
:
right
;
width
:
100%
;
}
.wizard.vertical
>
.actions
...
...
apps/templates/_footer.html
View file @
5c17b1a7
<div
class=
"footer fixed"
>
<div
class=
"pull-right"
>
Version
<strong>
1.2.
0
-{% include '_build.html' %}
</strong>
GPLv2.
Version
<strong>
1.2.
1
-{% include '_build.html' %}
</strong>
GPLv2.
<img
style=
"display: none"
src=
"http://www.jumpserver.org/img/evaluate_avatar1.jpg"
>
</div>
<div>
...
...
apps/templates/_message.html
View file @
5c17b1a7
...
...
@@ -6,9 +6,12 @@
{% blocktrans %}
Your information was incomplete. Please click
<a
href=
"{{ first_login_url }}"
>
this link
</a>
to complete your information.
{% endblocktrans %}
<button
aria-hidden=
"true"
data-dismiss=
"alert"
class=
"close"
type=
"button"
style=
"outline: none;"
>
×
</button>
</div>
{% 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' %}
<div
class=
"alert alert-danger help-message alert-dismissable"
>
...
...
@@ -25,7 +28,9 @@
{% for message in messages %}
<div
class=
"alert alert-{{ message.tags }} help-message"
>
{{ message|safe }}
<button
aria-hidden=
"true"
data-dismiss=
"alert"
class=
"close"
type=
"button"
style=
"outline: none;"
>
×
</button>
</div>
{% endfor %}
{% endif %}
...
...
apps/users/api.py
View file @
5c17b1a7
...
...
@@ -153,7 +153,7 @@ class UserOtpAuthApi(APIView):
return
Response
({
'msg'
:
'请先进行用户名和密码验证'
},
status
=
401
)
if
not
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
return
Response
({
'msg'
:
'
otp
认证失败'
},
status
=
401
)
return
Response
({
'msg'
:
'
MFA
认证失败'
},
status
=
401
)
token
=
generate_token
(
request
,
user
)
self
.
write_login_log
(
request
,
user
)
...
...
@@ -204,7 +204,7 @@ class UserAuthApi(APIView):
return
Response
(
{
'code'
:
101
,
'msg'
:
'请携带seed值,进行
OTP
二次认证'
,
'msg'
:
'请携带seed值,进行
MFA
二次认证'
,
'otp_url'
:
reverse
(
'api-users:user-otp-auth'
),
'seed'
:
seed
,
'user'
:
self
.
serializer_class
(
user
)
.
data
...
...
apps/users/forms.py
View file @
5c17b1a7
...
...
@@ -15,6 +15,14 @@ class UserLoginForm(AuthenticationForm):
label
=
_
(
'Password'
),
widget
=
forms
.
PasswordInput
,
max_length
=
128
,
strip
=
False
)
class
UserLoginCaptchaForm
(
AuthenticationForm
):
username
=
forms
.
CharField
(
label
=
_
(
'Username'
),
max_length
=
100
)
password
=
forms
.
CharField
(
label
=
_
(
'Password'
),
widget
=
forms
.
PasswordInput
,
max_length
=
128
,
strip
=
False
)
captcha
=
CaptchaField
()
...
...
@@ -27,7 +35,7 @@ class UserCheckPasswordForm(forms.Form):
class
UserCheckOtpCodeForm
(
forms
.
Form
):
otp_code
=
forms
.
CharField
(
label
=
_
(
'MFA
_
code'
),
max_length
=
6
)
otp_code
=
forms
.
CharField
(
label
=
_
(
'MFA
code'
),
max_length
=
6
)
class
UserCreateUpdateForm
(
forms
.
ModelForm
):
...
...
@@ -36,7 +44,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...'
)}),
...
...
@@ -47,7 +58,7 @@ class UserCreateUpdateForm(forms.ModelForm):
model
=
User
fields
=
[
'username'
,
'name'
,
'email'
,
'groups'
,
'wechat'
,
'phone'
,
'role'
,
'date_expired'
,
'comment'
,
'phone'
,
'role'
,
'date_expired'
,
'comment'
,
'otp_level'
]
help_texts
=
{
'username'
:
'* required'
,
...
...
@@ -61,6 +72,7 @@ class UserCreateUpdateForm(forms.ModelForm):
'data-placeholder'
:
_
(
'Join user groups'
)
}
),
'otp_level'
:
forms
.
RadioSelect
()
}
def
clean_public_key
(
self
):
...
...
@@ -77,11 +89,15 @@ class UserCreateUpdateForm(forms.ModelForm):
def
save
(
self
,
commit
=
True
):
password
=
self
.
cleaned_data
.
get
(
'password'
)
otp_level
=
self
.
cleaned_data
.
get
(
'otp_level'
)
public_key
=
self
.
cleaned_data
.
get
(
'public_key'
)
user
=
super
()
.
save
(
commit
=
commit
)
if
password
:
user
.
set_password
(
password
)
user
.
save
()
if
otp_level
:
user
.
otp_level
=
otp_level
user
.
save
()
if
public_key
:
user
.
public_key
=
public_key
user
.
save
()
...
...
@@ -105,6 +121,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
,
...
...
@@ -147,6 +196,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...'
)}),
...
...
apps/users/models/user.py
View file @
5c17b1a7
...
...
@@ -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
=
_
(
'Enable OTP'
))
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
):
...
...
apps/users/templates/users/_base_otp.html
View file @
5c17b1a7
...
...
@@ -75,11 +75,9 @@
<footer>
<div
class=
""
style=
"margin-top: 100px;"
>
{% include '_copyright.html' %}
</div>
</footer>
</body>
...
...
apps/users/templates/users/_user.html
View file @
5c17b1a7
...
...
@@ -17,7 +17,10 @@
{% bootstrap_field form.groups layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
{% block password %} {% endblock %}
<h3>
{% trans 'Auth' %}
</h3>
{% block password %}{% endblock %}
{% bootstrap_field form.otp_level layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Security and Role' %}
</h3>
...
...
apps/users/templates/users/first_login.html
View file @
5c17b1a7
...
...
@@ -9,6 +9,7 @@
<link
href=
"{% static 'css/plugins/steps/jquery.steps.css' %}"
rel=
"stylesheet"
>
{% endblock %}
{% block first_login_message %}{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
...
...
@@ -32,53 +33,111 @@
{% for step in wizard.steps.all %}
<li
role=
"tab"
class=
"{% ifequal step wizard.steps.first %}first{% endifequal %} {% ifequal step wizard.steps.current %}current{% else %}disabled{% endifequal %} {% ifequal step wizard.steps.last %}last{% endifequal %}"
aria-disabled=
"false"
aria-selected=
"true"
>
<a
href=
"javascript:void(0)"
><span
class=
"number"
>
{% trans 'Step' %} {{ step }}
</span></a>
<a
class=
"fl_goto"
name=
"wizard_goto_step"
data-goto=
"{{ step }}"
>
<span
class=
"number"
>
{% ifequal step '0' %}
1. {% trans "Profile" %}
{% endifequal %}
{% ifequal step '1' %}
2. {% trans "Public key" %}
{% endifequal %}
{% ifequal step '2' %}
3. {% trans "MFA" %}
{% endifequal %}
{% ifequal step '3' %}
4. {% trans "Finish" %}
{% endifequal %}
</span>
</a>
</li>
{% endfor >%}
</ul>
</div>
<div
class=
"content clearfix"
>
<form
action=
""
method=
"post"
class=
"form col-lg-8 p-m"
id=
"fl_form"
>
<div
class=
"content clearfix"
style=
"background-color: #eee; border-radius:5px;"
>
<div
class=
"row"
>
<form
action=
""
method=
"post"
class=
"form col-lg-8 p-m"
id=
"fl_form"
style=
"padding-left: 40px;"
>
{% csrf_token %}
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{% bootstrap_form form %}
{% endfor %}
{% else %}
{#{% if wizard.form.forms %}#}
{#{{ wizard.form.management_form }}#}
{#{% for form in wizard.form %}#}
{#{% bootstrap_form form %}#}
{#{% endfor %}#}
{#{% else %}#}
{#{% endif %}#}
{% if form.finish_description %}
<b>
{{ form.finish_description }}
</b>
<br>
<input
type=
"checkbox"
id=
"acceptTerms"
>
<label
for=
"acceptTerms"
style=
"margin-top:20px"
>
{% trans "I agree with the terms and conditions." %}
</label>
{% endif %}
{% bootstrap_form wizard.form %}
{% if form.mfa_description %}
<b>
{{ form.mfa_description }}
</b>
{% endif %}
{% if form.pubkey_description %}
<span>
或者:
</span>
<a
type=
"button"
id=
"btn-reset-pubkey"
>
{{ form.pubkey_description }}
</a>
{% endif %}
</form>
<div
class=
"col-lg-4"
>
<div
class=
"text-center"
>
<div
style=
"margin-top: 20px"
>
<i
class=
"fa fa-sign-in"
style=
"font-size: 180px;color: #e5e5e5 "
></i>
</div>
</div>
</div>
</div>
</div>
<div
class=
"actions clearfix"
>
<ul>
{% if wizard.steps.prev %}
<li><a
class=
"fl_goto"
name=
"wizard_goto_step"
data-goto=
"{{ wizard.steps.prev }}"
>
{% trans "Previous" %}
</a></li>
{% endif %}
{#{% if wizard.steps.next %}#}
{#
<li><a
class=
"fl_goto"
name=
"wizard_goto_step"
data-goto=
"{{ wizard.steps.next }}"
>
{% trans "Next" %}
</a></li>
#}
{#{% endif %}#}
{#
<li><a
id=
"fl_submit"
>
{% trans "Submit" %}
</a></li>
#}
{#将原来的下一页-替换为提交;修复 每页都提交,最后才能成功问题#}
{% if wizard.steps.next %}
<li><a
class=
"fl_goto"
name=
"wizard_goto_step"
data-goto=
"{{ wizard.steps.next }}"
>
{% trans "Next" %}
</a></li>
<li><a
id=
"fl_submit"
>
{% trans "Next" %}
</a></li>
{% else %}
<li><a
id=
"fl_submit"
style=
"width:66px;text-align: center;"
>
{% trans "Finish" %}
</a></li>
{% endif %}
<li><a
id=
"fl_submit"
>
{% trans "Submit" %}
</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
on
(
'click'
,
".fl_goto"
,
function
(){
$
(
'#id_2-otp_level div'
).
eq
(
2
).
css
(
'display'
,
'none'
);
$
(
document
).
on
(
'click'
,
".fl_goto"
,
function
(){
var
$form
=
$
(
'#fl_form'
);
$
(
'<input />'
,
{
'name'
:
'wizard_goto_step'
,
'value'
:
$
(
this
).
data
(
'goto'
),
'type'
:
'hidden'
}).
appendTo
(
$form
);
$form
.
submit
();
return
false
;
}).
on
(
'click'
,
'#fl_submit'
,
function
(){
}).
on
(
'click'
,
'#fl_submit'
,
function
(){
$
(
'#fl_form'
).
submit
();
return
false
;
}).
on
(
'click'
,
'#btn-reset-pubkey'
,
function
()
{
var
the_url
=
'{% url "users:user-pubkey-generate" %}'
;
window
.
open
(
the_url
,
"_blank"
)
})
</script>
{% endblock %}
apps/users/templates/users/first_login_done.html
View file @
5c17b1a7
...
...
@@ -9,6 +9,7 @@
<link
href=
"{% static 'css/plugins/steps/jquery.steps.css' %}"
rel=
"stylesheet"
>
{% endblock %}
{% block first_login_message %}{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
...
...
@@ -36,6 +37,8 @@
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
on
(
'click'
,
".fl_goto"
,
function
(){
...
...
apps/users/templates/users/login.html
View file @
5c17b1a7
...
...
@@ -53,7 +53,7 @@
{% endif %}
{% endif %}
<div
class=
"form-group"
>
<input
type=
"text"
class=
"form-control"
name=
"{{ form.username.html_name }}"
placeholder=
"{% trans 'Username' %}"
required=
""
>
<input
type=
"text"
class=
"form-control"
name=
"{{ form.username.html_name }}"
placeholder=
"{% trans 'Username' %}"
required=
""
value=
"{% if form.username.value %}{{ form.username.value }}{% endif %}"
>
</div>
<div
class=
"form-group"
>
<input
type=
"password"
class=
"form-control"
name=
"{{ form.password.html_name }}"
placeholder=
"{% trans 'Password' %}"
required=
""
>
...
...
apps/users/templates/users/user_create.html
View file @
5c17b1a7
...
...
@@ -6,11 +6,11 @@
{# {% bootstrap_field form.username layout="horizontal" %}#}
{#{% endblock %}#}
{% block password %}
<h3>
{% trans 'Auth' %}
</h3>
<div
class=
"form-group"
>
<label
class=
"col-sm-2 control-label"
>
{% trans 'Password' %}
</label>
<div
class=
"col-sm-8 controls"
>
<div
class=
"col-sm-8 controls"
style=
"margin-top: 8px;"
>
{% trans 'Reset link will be generated and sent to the user. ' %}
</div>
</div>
{% endblock %}
apps/users/templates/users/user_list.html
View file @
5c17b1a7
...
...
@@ -107,6 +107,9 @@ $(document).ready(function(){
$
(
'.btn_export'
).
click
(
function
()
{
var
users
=
[];
var
rows
=
table
.
rows
(
'.selected'
).
data
();
if
(
rows
.
length
===
0
){
rows
=
table
.
rows
().
data
();
}
$
.
each
(
rows
,
function
(
index
,
obj
)
{
users
.
push
(
obj
.
id
)
});
...
...
apps/users/templates/users/user_otp_authentication.html
View file @
5c17b1a7
...
...
@@ -27,7 +27,6 @@
$
(
function
(){
$
(
'.change-color li'
).
eq
(
2
).
remove
();
$
(
'.change-color li:eq(1) div'
).
eq
(
1
).
html
(
'解绑MFA'
)
})
...
...
apps/users/templates/users/user_update.html
View file @
5c17b1a7
...
...
@@ -3,7 +3,6 @@
{% load bootstrap3 %}
{% block user_template_title %}{% trans "Update user" %}{% endblock %}
{% block password %}
<h3>
{% trans 'Auth' %}
</h3>
{% bootstrap_field form.password layout="horizontal" %}
{% bootstrap_field form.public_key layout="horizontal" %}
{% endblock %}
apps/users/views/login.py
View file @
5c17b1a7
...
...
@@ -2,6 +2,7 @@
from
__future__
import
unicode_literals
import
os
from
django.core.cache
import
cache
from
django.shortcuts
import
render
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
from
django.contrib.auth.mixins
import
LoginRequiredMixin
...
...
@@ -43,7 +44,9 @@ __all__ = [
class
UserLoginView
(
FormView
):
template_name
=
'users/login.html'
form_class
=
forms
.
UserLoginForm
form_class_captcha
=
forms
.
UserLoginCaptchaForm
redirect_field_name
=
'next'
key_prefix
=
"_LOGIN_INVALID_{}"
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_staff
:
...
...
@@ -58,6 +61,21 @@ class UserLoginView(FormView):
set_tmp_user_to_cache
(
self
.
request
,
form
.
get_user
())
return
redirect
(
self
.
get_success_url
())
def
form_invalid
(
self
,
form
):
ip
=
get_login_ip
(
self
.
request
)
cache
.
set
(
self
.
key_prefix
.
format
(
ip
),
1
,
3600
)
old_form
=
form
form
=
self
.
form_class_captcha
(
data
=
form
.
data
)
form
.
_errors
=
old_form
.
errors
return
super
()
.
form_invalid
(
form
)
def
get_form_class
(
self
):
ip
=
get_login_ip
(
self
.
request
)
if
cache
.
get
(
self
.
key_prefix
.
format
(
ip
)):
return
self
.
form_class_captcha
else
:
return
self
.
form_class
def
get_success_url
(
self
):
user
=
get_user_or_tmp_user
(
self
.
request
)
...
...
@@ -166,8 +184,7 @@ class UserForgotPasswordSendmailSuccessView(TemplateView):
'redirect_url'
:
reverse
(
'users:login'
),
}
kwargs
.
update
(
context
)
return
super
()
\
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
UserResetPasswordSuccessView
(
TemplateView
):
...
...
@@ -214,7 +231,12 @@ class UserResetPasswordView(TemplateView):
class
UserFirstLoginView
(
LoginRequiredMixin
,
SessionWizardView
):
template_name
=
'users/first_login.html'
form_list
=
[
forms
.
UserProfileForm
,
forms
.
UserPublicKeyForm
]
form_list
=
[
forms
.
UserProfileForm
,
forms
.
UserPublicKeyForm
,
forms
.
UserMFAForm
,
forms
.
UserFirstLoginFinishForm
]
file_storage
=
default_storage
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
...
...
@@ -255,7 +277,6 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
def
get_form
(
self
,
step
=
None
,
data
=
None
,
files
=
None
):
form
=
super
()
.
get_form
(
step
,
data
,
files
)
form
.
instance
=
self
.
request
.
user
return
form
...
...
@@ -293,7 +314,9 @@ class LoginLogListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
'date_to'
:
self
.
date_to
,
'user'
:
self
.
user
,
'keyword'
:
self
.
keyword
,
'user_list'
:
set
(
LoginLog
.
objects
.
all
()
.
values_list
(
'username'
,
flat
=
True
))
'user_list'
:
set
(
LoginLog
.
objects
.
all
()
.
values_list
(
'username'
,
flat
=
True
)
)
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
\ No newline at end of file
utils/upgrade.sh
0 → 100644
View file @
5c17b1a7
#!/bin/bash
if
[
!
-d
"/opt/py3"
]
;
then
echo
-e
"
\0
33[31m python3虚拟环境不是默认路径
\0
33[0m"
ps
-ef
|
grep
jumpserver/tmp/beat.pid |
grep
-v
grep
if
[
$?
-ne
0
]
then
echo
-e
"
\0
33[31m jumpserver未运行,请到jumpserver目录使用 ./jms start all -d 启动
\0
33[0m"
exit
0
else
echo
-e
"
\0
33[31m 正在计算python3虚拟环境路径
\0
33[0m"
fi
py3pid
=
`
ps
-ef
|
grep
jumpserver/tmp/beat.pid |
grep
-v
grep
|
awk
'{print $2}'
`
py3file
=
`
cat
/proc/
$py3pid
/cmdline
`
py3even
=
`
echo
${
py3file
%/bin/python3*
}
`
echo
-e
"
\0
33[31m python3虚拟环境路径为
$py3even
\0
33[0m"
source
$py3even
/bin/activate
else
source
/opt/py3/bin/activate
fi
cd
`
dirname
$0
`
/
&&
cd
..
&&
./jms stop
jumpserver_backup
=
/tmp/jumpserver_backup
$(
date
-d
"today"
+
"%Y%m%d_%H%M%S"
)
mkdir
-p
$jumpserver_backup
cp
-r
./
*
$jumpserver_backup
echo
-e
"
\0
33[31m 是否需要备份Jumpserver数据库
\0
33[0m"
stty
erase ^H
read
-p
"确认备份请按Y,否则按其他键跳过备份 "
a
if
[
"
$a
"
==
y
-o
"
$a
"
==
Y
]
;
then
echo
-e
"
\0
33[31m 正在备份数据库
\0
33[0m"
echo
-e
"
\0
33[31m 请手动输入数据库信息
\0
33[0m"
read
-p
'请输入Jumpserver数据库ip:'
DB_HOST
read
-p
'请输入Jumpserver数据库端口:'
DB_PORT
read
-p
'请输入Jumpserver数据库名称:'
DB_NAME
read
-p
'请输入有权限导出数据库的用户:'
DB_USER
read
-p
'请输入该用户的密码:'
DB_PASSWORD
mysqldump
-h
$DB_HOST
-P
$DB_PORT
-u
$DB_USER
-p
$DB_PASSWORD
$DB_NAME
>
/
$jumpserver_backup
/
$DB_NAME
$(
date
-d
"today"
+
"%Y%m%d_%H%M%S"
)
.sql
||
{
echo
-e
"
\0
33[31m 备份数据库失败,请检查输入是否有误
\0
33[0m"
exit
1
}
echo
-e
"
\0
33[31m 备份数据库完成
\0
33[0m"
else
echo
-e
"
\0
33[31m 已取消备份数据库操作
\0
33[0m"
fi
git pull
&&
pip
install
-r
requirements/requirements.txt
&&
cd
utils
&&
sh make_migrations.sh
cd
..
&&
./jms start all
-d
echo
-e
"
\0
33[31m 请检查jumpserver是否启动成功
\0
33[0m"
echo
-e
"
\0
33[31m 备份文件存放于
$jumpserver_backup
目录
\0
33[0m"
exit
0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment