mirror of https://github.com/jumpserver/jumpserver
增加命令导出 (#1566)
* [Update] gunicorn不使用eventlet * [Update] 添加eventlet * 替换淘宝IP查询接口 * [Feature] 添加命令记录下载功能 (#1559) * [Feature] 添加命令记录下载功能 * [Update] 文案修改,导出记录、提交,取消全部命令导出 * [Update] 命令导出,修复时间问题 * [Update] paramiko => 2.4.1 * [Update] 修改settings * [Update] 修改权限判断pull/1651/head^2 1.3.3
parent
3d34b06203
commit
16b23a37fe
|
@ -154,7 +154,7 @@ class Asset(models.Model):
|
||||||
return False, warning
|
return False, warning
|
||||||
|
|
||||||
def is_unixlike(self):
|
def is_unixlike(self):
|
||||||
if self.platform not in ("Windows",):
|
if self.platform not in ("Windows", "Windows2016"):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -93,7 +93,7 @@ class DatetimeSearchMixin:
|
||||||
date_format = '%Y-%m-%d'
|
date_format = '%Y-%m-%d'
|
||||||
date_from = date_to = None
|
date_from = date_to = None
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get_date_range(self):
|
||||||
date_from_s = self.request.GET.get('date_from')
|
date_from_s = self.request.GET.get('date_from')
|
||||||
date_to_s = self.request.GET.get('date_to')
|
date_to_s = self.request.GET.get('date_to')
|
||||||
|
|
||||||
|
@ -113,6 +113,9 @@ class DatetimeSearchMixin:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.date_to = timezone.now()
|
self.date_to = timezone.now()
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.get_date_range()
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -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: 2018-07-13 19:20+0800\n"
|
"POT-Creation-Date: 2018-07-19 18:29+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"
|
||||||
|
@ -445,7 +445,7 @@ msgstr "默认资产组"
|
||||||
#: terminal/templates/terminal/session_list.html:71 users/forms.py:282
|
#: terminal/templates/terminal/session_list.html:71 users/forms.py:282
|
||||||
#: users/models/user.py:31 users/models/user.py:333
|
#: users/models/user.py:31 users/models/user.py:333
|
||||||
#: 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:361
|
#: users/templates/users/user_group_list.html:13 users/views/user.py:367
|
||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr "用户"
|
msgstr "用户"
|
||||||
|
|
||||||
|
@ -685,6 +685,7 @@ msgstr "重置"
|
||||||
#: common/templates/common/security_setting.html:71
|
#: common/templates/common/security_setting.html:71
|
||||||
#: common/templates/common/terminal_setting.html:108
|
#: common/templates/common/terminal_setting.html:108
|
||||||
#: perms/templates/perms/asset_permission_create_update.html:70
|
#: perms/templates/perms/asset_permission_create_update.html:70
|
||||||
|
#: terminal/templates/terminal/command_list.html:103
|
||||||
#: terminal/templates/terminal/session_list.html:126
|
#: terminal/templates/terminal/session_list.html:126
|
||||||
#: terminal/templates/terminal/terminal_update.html:48
|
#: terminal/templates/terminal/terminal_update.html:48
|
||||||
#: users/templates/users/_user.html:47
|
#: users/templates/users/_user.html:47
|
||||||
|
@ -814,7 +815,7 @@ msgstr "选择节点"
|
||||||
#: users/templates/users/user_detail.html:374
|
#: users/templates/users/user_detail.html:374
|
||||||
#: users/templates/users/user_detail.html:399
|
#: users/templates/users/user_detail.html:399
|
||||||
#: users/templates/users/user_detail.html:422
|
#: users/templates/users/user_detail.html:422
|
||||||
#: users/templates/users/user_detail.html:458
|
#: users/templates/users/user_detail.html:466
|
||||||
#: users/templates/users/user_group_create_update.html:32
|
#: users/templates/users/user_group_create_update.html:32
|
||||||
#: users/templates/users/user_group_list.html:86
|
#: users/templates/users/user_group_list.html:86
|
||||||
#: users/templates/users/user_list.html:200
|
#: users/templates/users/user_list.html:200
|
||||||
|
@ -1005,7 +1006,7 @@ msgstr "存在资产,不能删除"
|
||||||
#: assets/templates/assets/system_user_list.html:134
|
#: assets/templates/assets/system_user_list.html:134
|
||||||
#: users/templates/users/user_detail.html:369
|
#: users/templates/users/user_detail.html:369
|
||||||
#: users/templates/users/user_detail.html:394
|
#: users/templates/users/user_detail.html:394
|
||||||
#: users/templates/users/user_detail.html:453
|
#: users/templates/users/user_detail.html:461
|
||||||
#: users/templates/users/user_group_list.html:81
|
#: users/templates/users/user_group_list.html:81
|
||||||
#: users/templates/users/user_list.html:195
|
#: users/templates/users/user_list.html:195
|
||||||
msgid "Are you sure?"
|
msgid "Are you sure?"
|
||||||
|
@ -2002,7 +2003,7 @@ msgstr "文档"
|
||||||
#: users/templates/users/user_profile.html:17
|
#: users/templates/users/user_profile.html:17
|
||||||
#: users/templates/users/user_profile_update.html:37
|
#: users/templates/users/user_profile_update.html:37
|
||||||
#: users/templates/users/user_profile_update.html:57
|
#: users/templates/users/user_profile_update.html:57
|
||||||
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:343
|
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:349
|
||||||
msgid "Profile"
|
msgid "Profile"
|
||||||
msgstr "个人信息"
|
msgstr "个人信息"
|
||||||
|
|
||||||
|
@ -2059,13 +2060,13 @@ msgstr "关闭"
|
||||||
|
|
||||||
#: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44
|
#: 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/group.py:62 users/views/group.py:79 users/views/group.py:95
|
||||||
#: users/views/login.py:330 users/views/login.py:388 users/views/user.py:65
|
#: users/views/login.py:332 users/views/login.py:390 users/views/user.py:67
|
||||||
#: users/views/user.py:80 users/views/user.py:102 users/views/user.py:175
|
#: users/views/user.py:82 users/views/user.py:104 users/views/user.py:180
|
||||||
#: users/views/user.py:330 users/views/user.py:380 users/views/user.py:415
|
#: users/views/user.py:336 users/views/user.py:386 users/views/user.py:421
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "用户管理"
|
msgstr "用户管理"
|
||||||
|
|
||||||
#: templates/_nav.html:13 users/views/user.py:66
|
#: templates/_nav.html:13 users/views/user.py:68
|
||||||
msgid "User list"
|
msgid "User list"
|
||||||
msgstr "用户列表"
|
msgstr "用户列表"
|
||||||
|
|
||||||
|
@ -2093,7 +2094,7 @@ msgstr "命令记录"
|
||||||
msgid "Web terminal"
|
msgid "Web terminal"
|
||||||
msgstr "Web终端"
|
msgstr "Web终端"
|
||||||
|
|
||||||
#: templates/_nav.html:51 terminal/views/command.py:47
|
#: templates/_nav.html:51 terminal/views/command.py:49
|
||||||
#: terminal/views/session.py:75 terminal/views/session.py:93
|
#: terminal/views/session.py:75 terminal/views/session.py:93
|
||||||
#: terminal/views/session.py:115 terminal/views/terminal.py:31
|
#: terminal/views/session.py:115 terminal/views/terminal.py:31
|
||||||
#: terminal/views/terminal.py:46 terminal/views/terminal.py:58
|
#: terminal/views/terminal.py:46 terminal/views/terminal.py:58
|
||||||
|
@ -2202,13 +2203,17 @@ msgstr "参数"
|
||||||
msgid "Goto"
|
msgid "Goto"
|
||||||
msgstr "转到"
|
msgstr "转到"
|
||||||
|
|
||||||
|
#: terminal/templates/terminal/command_list.html:99
|
||||||
|
msgid "Export command"
|
||||||
|
msgstr "导出命令"
|
||||||
|
|
||||||
#: terminal/templates/terminal/session_detail.html:17
|
#: terminal/templates/terminal/session_detail.html:17
|
||||||
#: terminal/views/session.py:116
|
#: terminal/views/session.py:116
|
||||||
msgid "Session detail"
|
msgid "Session detail"
|
||||||
msgstr "会话详情"
|
msgstr "会话详情"
|
||||||
|
|
||||||
#: terminal/templates/terminal/session_detail.html:28
|
#: terminal/templates/terminal/session_detail.html:28
|
||||||
#: terminal/views/command.py:48
|
#: terminal/views/command.py:50
|
||||||
msgid "Command list"
|
msgid "Command list"
|
||||||
msgstr "命令记录列表"
|
msgstr "命令记录列表"
|
||||||
|
|
||||||
|
@ -2324,7 +2329,7 @@ msgid ""
|
||||||
"You should use your ssh client tools connect terminal: {} <br /> <br />{}"
|
"You should use your ssh client tools connect terminal: {} <br /> <br />{}"
|
||||||
msgstr "你可以使用ssh客户端工具连接终端"
|
msgstr "你可以使用ssh客户端工具连接终端"
|
||||||
|
|
||||||
#: users/api.py:221 users/templates/users/login.html:50
|
#: users/api.py:226 users/templates/users/login.html:50
|
||||||
msgid "Log in frequently and try again later"
|
msgid "Log in frequently and try again later"
|
||||||
msgstr "登录频繁, 稍后重试"
|
msgstr "登录频繁, 稍后重试"
|
||||||
|
|
||||||
|
@ -2725,7 +2730,7 @@ msgid "Setting"
|
||||||
msgstr "设置"
|
msgstr "设置"
|
||||||
|
|
||||||
#: users/templates/users/user_create.html:4
|
#: users/templates/users/user_create.html:4
|
||||||
#: users/templates/users/user_list.html:16 users/views/user.py:80
|
#: users/templates/users/user_list.html:16 users/views/user.py:82
|
||||||
msgid "Create user"
|
msgid "Create user"
|
||||||
msgstr "创建用户"
|
msgstr "创建用户"
|
||||||
|
|
||||||
|
@ -2734,7 +2739,7 @@ msgid "Reset link will be generated and sent to the user. "
|
||||||
msgstr "生成重置密码连接,通过邮件发送给用户"
|
msgstr "生成重置密码连接,通过邮件发送给用户"
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:19
|
#: users/templates/users/user_detail.html:19
|
||||||
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:176
|
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:181
|
||||||
msgid "User detail"
|
msgid "User detail"
|
||||||
msgstr "用户详情"
|
msgstr "用户详情"
|
||||||
|
|
||||||
|
@ -2772,7 +2777,7 @@ msgid "Send reset ssh key mail"
|
||||||
msgstr "发送重置密钥邮件"
|
msgstr "发送重置密钥邮件"
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:186
|
#: users/templates/users/user_detail.html:186
|
||||||
#: users/templates/users/user_detail.html:444
|
#: users/templates/users/user_detail.html:446
|
||||||
msgid "Unblock user"
|
msgid "Unblock user"
|
||||||
msgstr "解除登录限制"
|
msgstr "解除登录限制"
|
||||||
|
|
||||||
|
@ -2818,7 +2823,7 @@ msgstr "更新ssh密钥成功"
|
||||||
msgid "User SSH public key update"
|
msgid "User SSH public key update"
|
||||||
msgstr "ssh密钥"
|
msgstr "ssh密钥"
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:454
|
#: users/templates/users/user_detail.html:462
|
||||||
msgid "After unlocking the user, the user can log in normally."
|
msgid "After unlocking the user, the user can log in normally."
|
||||||
msgstr "解除用户登录限制后,此用户即可正常登录"
|
msgstr "解除用户登录限制后,此用户即可正常登录"
|
||||||
|
|
||||||
|
@ -2878,8 +2883,8 @@ msgstr "用户删除失败"
|
||||||
msgid "Administrator Settings force MFA login"
|
msgid "Administrator Settings force MFA login"
|
||||||
msgstr "管理员设置强制使用MFA登录"
|
msgstr "管理员设置强制使用MFA登录"
|
||||||
|
|
||||||
#: users/templates/users/user_profile.html:116 users/views/user.py:205
|
#: users/templates/users/user_profile.html:116 users/views/user.py:211
|
||||||
#: users/views/user.py:259
|
#: users/views/user.py:265
|
||||||
msgid "User groups"
|
msgid "User groups"
|
||||||
msgstr "用户组"
|
msgstr "用户组"
|
||||||
|
|
||||||
|
@ -2925,7 +2930,7 @@ msgid ""
|
||||||
"corresponding private key."
|
"corresponding private key."
|
||||||
msgstr "新的公钥已设置成功,请下载对应的私钥"
|
msgstr "新的公钥已设置成功,请下载对应的私钥"
|
||||||
|
|
||||||
#: users/templates/users/user_update.html:4 users/views/user.py:103
|
#: users/templates/users/user_update.html:4 users/views/user.py:105
|
||||||
msgid "Update user"
|
msgid "Update user"
|
||||||
msgstr "更新用户"
|
msgstr "更新用户"
|
||||||
|
|
||||||
|
@ -3079,104 +3084,104 @@ msgstr "更新用户组"
|
||||||
msgid "User group granted asset"
|
msgid "User group granted asset"
|
||||||
msgstr "用户组授权资产"
|
msgstr "用户组授权资产"
|
||||||
|
|
||||||
#: users/views/login.py:75
|
#: users/views/login.py:76
|
||||||
msgid "Please enable cookies and try again."
|
msgid "Please enable cookies and try again."
|
||||||
msgstr "设置你的浏览器支持cookie"
|
msgstr "设置你的浏览器支持cookie"
|
||||||
|
|
||||||
#: users/views/login.py:178 users/views/user.py:500 users/views/user.py:525
|
#: users/views/login.py:180 users/views/user.py:506 users/views/user.py:531
|
||||||
msgid "MFA code invalid"
|
msgid "MFA code invalid"
|
||||||
msgstr "MFA码认证失败"
|
msgstr "MFA码认证失败"
|
||||||
|
|
||||||
#: users/views/login.py:207
|
#: users/views/login.py:209
|
||||||
msgid "Logout success"
|
msgid "Logout success"
|
||||||
msgstr "退出登录成功"
|
msgstr "退出登录成功"
|
||||||
|
|
||||||
#: users/views/login.py:208
|
#: users/views/login.py:210
|
||||||
msgid "Logout success, return login page"
|
msgid "Logout success, return login page"
|
||||||
msgstr "退出登录成功,返回到登录页面"
|
msgstr "退出登录成功,返回到登录页面"
|
||||||
|
|
||||||
#: users/views/login.py:224
|
#: users/views/login.py:226
|
||||||
msgid "Email address invalid, please input again"
|
msgid "Email address invalid, please input again"
|
||||||
msgstr "邮箱地址错误,重新输入"
|
msgstr "邮箱地址错误,重新输入"
|
||||||
|
|
||||||
#: users/views/login.py:237
|
#: users/views/login.py:239
|
||||||
msgid "Send reset password message"
|
msgid "Send reset password message"
|
||||||
msgstr "发送重置密码邮件"
|
msgstr "发送重置密码邮件"
|
||||||
|
|
||||||
#: users/views/login.py:238
|
#: users/views/login.py:240
|
||||||
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:251
|
#: users/views/login.py:253
|
||||||
msgid "Reset password success"
|
msgid "Reset password success"
|
||||||
msgstr "重置密码成功"
|
msgstr "重置密码成功"
|
||||||
|
|
||||||
#: users/views/login.py:252
|
#: users/views/login.py:254
|
||||||
msgid "Reset password success, return to login page"
|
msgid "Reset password success, return to login page"
|
||||||
msgstr "重置密码成功,返回到登录页面"
|
msgstr "重置密码成功,返回到登录页面"
|
||||||
|
|
||||||
#: users/views/login.py:273 users/views/login.py:286
|
#: users/views/login.py:275 users/views/login.py:288
|
||||||
msgid "Token invalid or expired"
|
msgid "Token invalid or expired"
|
||||||
msgstr "Token错误或失效"
|
msgstr "Token错误或失效"
|
||||||
|
|
||||||
#: users/views/login.py:282
|
#: users/views/login.py:284
|
||||||
msgid "Password not same"
|
msgid "Password not same"
|
||||||
msgstr "密码不一致"
|
msgstr "密码不一致"
|
||||||
|
|
||||||
#: users/views/login.py:292 users/views/user.py:118 users/views/user.py:398
|
#: users/views/login.py:294 users/views/user.py:120 users/views/user.py:404
|
||||||
msgid "* Your password does not meet the requirements"
|
msgid "* Your password does not meet the requirements"
|
||||||
msgstr "* 您的密码不符合要求"
|
msgstr "* 您的密码不符合要求"
|
||||||
|
|
||||||
#: users/views/login.py:330
|
#: users/views/login.py:332
|
||||||
msgid "First login"
|
msgid "First login"
|
||||||
msgstr "首次登陆"
|
msgstr "首次登陆"
|
||||||
|
|
||||||
#: users/views/login.py:389
|
#: users/views/login.py:391
|
||||||
msgid "Login log list"
|
msgid "Login log list"
|
||||||
msgstr "登录日志"
|
msgstr "登录日志"
|
||||||
|
|
||||||
#: users/views/user.py:129
|
#: users/views/user.py:131
|
||||||
msgid "Bulk update user success"
|
msgid "Bulk update user success"
|
||||||
msgstr "批量更新用户成功"
|
msgstr "批量更新用户成功"
|
||||||
|
|
||||||
#: users/views/user.py:234
|
#: users/views/user.py:240
|
||||||
msgid "Invalid file."
|
msgid "Invalid file."
|
||||||
msgstr "文件不合法"
|
msgstr "文件不合法"
|
||||||
|
|
||||||
#: users/views/user.py:331
|
#: users/views/user.py:337
|
||||||
msgid "User granted assets"
|
msgid "User granted assets"
|
||||||
msgstr "用户授权资产"
|
msgstr "用户授权资产"
|
||||||
|
|
||||||
#: users/views/user.py:362
|
#: users/views/user.py:368
|
||||||
msgid "Profile setting"
|
msgid "Profile setting"
|
||||||
msgstr "个人信息设置"
|
msgstr "个人信息设置"
|
||||||
|
|
||||||
#: users/views/user.py:381
|
#: users/views/user.py:387
|
||||||
msgid "Password update"
|
msgid "Password update"
|
||||||
msgstr "密码更新"
|
msgstr "密码更新"
|
||||||
|
|
||||||
#: users/views/user.py:416
|
#: users/views/user.py:422
|
||||||
msgid "Public key update"
|
msgid "Public key update"
|
||||||
msgstr "密钥更新"
|
msgstr "密钥更新"
|
||||||
|
|
||||||
#: users/views/user.py:457
|
#: users/views/user.py:463
|
||||||
msgid "Password invalid"
|
msgid "Password invalid"
|
||||||
msgstr "用户名或密码无效"
|
msgstr "用户名或密码无效"
|
||||||
|
|
||||||
#: users/views/user.py:551
|
#: users/views/user.py:557
|
||||||
msgid "MFA enable success"
|
msgid "MFA enable success"
|
||||||
msgstr "MFA 绑定成功"
|
msgstr "MFA 绑定成功"
|
||||||
|
|
||||||
#: users/views/user.py:552
|
#: users/views/user.py:558
|
||||||
msgid "MFA enable success, return login page"
|
msgid "MFA enable success, return login page"
|
||||||
msgstr "MFA 绑定成功,返回到登录页面"
|
msgstr "MFA 绑定成功,返回到登录页面"
|
||||||
|
|
||||||
#: users/views/user.py:554
|
#: users/views/user.py:560
|
||||||
msgid "MFA disable success"
|
msgid "MFA disable success"
|
||||||
msgstr "MFA 解绑成功"
|
msgstr "MFA 解绑成功"
|
||||||
|
|
||||||
#: users/views/user.py:555
|
#: users/views/user.py:561
|
||||||
msgid "MFA disable success, return login page"
|
msgid "MFA disable success, return login page"
|
||||||
msgstr "MFA 解绑成功,返回登录页面"
|
msgstr "MFA 解绑成功,返回登录页面"
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,7 @@ AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
|
||||||
AUTH_LDAP_CONNECTION_OPTIONS = {
|
AUTH_LDAP_CONNECTION_OPTIONS = {
|
||||||
ldap.OPT_TIMEOUT: 5
|
ldap.OPT_TIMEOUT: 5
|
||||||
}
|
}
|
||||||
|
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 1
|
||||||
AUTH_LDAP_ALWAYS_UPDATE_USER = True
|
AUTH_LDAP_ALWAYS_UPDATE_USER = True
|
||||||
AUTH_LDAP_BACKEND = 'django_auth_ldap.backend.LDAPBackend'
|
AUTH_LDAP_BACKEND = 'django_auth_ldap.backend.LDAPBackend'
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,7 @@ class UserGrantedAssetsApi(ListAPIView):
|
||||||
|
|
||||||
util = AssetPermissionUtil(user)
|
util = AssetPermissionUtil(user)
|
||||||
for k, v in util.get_assets().items():
|
for k, v in util.get_assets().items():
|
||||||
if k.is_unixlike():
|
system_users_granted = [s for s in v if s.protocol == k.protocol]
|
||||||
system_users_granted = [s for s in v if s.protocol in ['ssh', 'telnet']]
|
|
||||||
else:
|
|
||||||
system_users_granted = [s for s in v if s.protocol in ['rdp', 'telnet']]
|
|
||||||
k.system_users_granted = system_users_granted
|
k.system_users_granted = system_users_granted
|
||||||
queryset.append(k)
|
queryset.append(k)
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -123,10 +120,7 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
for node, _assets in nodes.items():
|
for node, _assets in nodes.items():
|
||||||
assets = _assets.keys()
|
assets = _assets.keys()
|
||||||
for k, v in _assets.items():
|
for k, v in _assets.items():
|
||||||
if k.is_unixlike():
|
system_users_granted = [s for s in v if s.protocol == k.protocol]
|
||||||
system_users_granted = [s for s in v if s.protocol in ['ssh', 'telnet']]
|
|
||||||
else:
|
|
||||||
system_users_granted = [s for s in v if s.protocol in ['rdp', 'telnet']]
|
|
||||||
k.system_users_granted = system_users_granted
|
k.system_users_granted = system_users_granted
|
||||||
node.assets_granted = assets
|
node.assets_granted = assets
|
||||||
queryset.append(node)
|
queryset.append(node)
|
||||||
|
|
|
@ -92,27 +92,52 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div id="actions" class="">
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||||
|
<option value="export">{% trans 'Export command' %}</option>
|
||||||
|
</select>
|
||||||
|
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
||||||
|
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
||||||
|
{% trans 'Submit' %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
|
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
|
||||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.footable').footable();
|
$('.footable').footable();
|
||||||
$('.select2').select2({
|
$('.select2').select2({
|
||||||
dropdownAutoWidth : true,
|
dropdownAutoWidth : true,
|
||||||
width: 'auto'
|
width: 'auto'
|
||||||
});
|
|
||||||
$('#date .input-daterange').datepicker({
|
|
||||||
format: "yyyy-mm-dd",
|
|
||||||
todayBtn: "linked",
|
|
||||||
keyboardNavigation: false,
|
|
||||||
forceParse: false,
|
|
||||||
calendarWeeks: true,
|
|
||||||
autoclose: true
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
$('#date .input-daterange').datepicker({
|
||||||
|
format: "yyyy-mm-dd",
|
||||||
|
todayBtn: "linked",
|
||||||
|
keyboardNavigation: false,
|
||||||
|
forceParse: false,
|
||||||
|
calendarWeeks: true,
|
||||||
|
autoclose: true
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on('click', '#btn_bulk_update', function(){
|
||||||
|
var action = $('#slct_bulk_update').val();
|
||||||
|
var param_action = '&action=' + action;
|
||||||
|
var local_params = window.location.search;
|
||||||
|
if(!local_params){
|
||||||
|
param_action = '?action=' + action;
|
||||||
|
}
|
||||||
|
var params = local_params + param_action;
|
||||||
|
var pathname = window.location.pathname + 'export/';
|
||||||
|
var url = pathname + params;
|
||||||
|
window.open(url);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
{% load common_tags %}
|
||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Command Report</title>
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.background {
|
||||||
|
background-color: #535659;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper {
|
||||||
|
margin-left: 23%;
|
||||||
|
margin-right: 24%;
|
||||||
|
border: solid;
|
||||||
|
padding: 50px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
width: 200px;
|
||||||
|
margin-left: 450px;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.command {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.command-desc {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.command-desc span {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.command-input {
|
||||||
|
{#font-style: italic;#}
|
||||||
|
font-size: 15px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.command-input span {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hr-line-dashed {
|
||||||
|
border-top: 1px dashed #000;
|
||||||
|
color: #000;
|
||||||
|
background-color: #fff;
|
||||||
|
height: 1px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="background">
|
||||||
|
<div class="paper">
|
||||||
|
<h2>Command Report</h2>
|
||||||
|
<div class="info">
|
||||||
|
<p>total: {{ total_count }}</p>
|
||||||
|
<p>date: {{ now | ts_to_date }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{% for command in queryset %}
|
||||||
|
<div class="command">
|
||||||
|
<p class="command-desc">
|
||||||
|
[{{ command.user}} {{ command.system_user }}@{{ command.asset }} {{ command.timestamp | ts_to_date }}]
|
||||||
|
<span>{{ forloop.counter }}</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="command-input"><span>$ </span>{{ command.input }}</p>
|
||||||
|
|
||||||
|
<pre>{{ command.output }}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -24,5 +24,6 @@ urlpatterns = [
|
||||||
|
|
||||||
# Command view
|
# Command view
|
||||||
url(r'^command/$', views.CommandListView.as_view(), name='command-list'),
|
url(r'^command/$', views.CommandListView.as_view(), name='command-list'),
|
||||||
|
url(r'^command/export/$', views.CommandExportView.as_view(), name='command-export')
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView, View
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.template import loader
|
||||||
|
import time
|
||||||
|
|
||||||
from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
|
from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
|
||||||
from ..models import Command
|
from ..models import Command
|
||||||
from .. import utils
|
from .. import utils
|
||||||
from ..backends import get_multi_command_storage
|
from ..backends import get_multi_command_storage
|
||||||
|
|
||||||
__all__ = ['CommandListView']
|
__all__ = ['CommandListView', 'CommandExportView']
|
||||||
common_storage = get_multi_command_storage()
|
common_storage = get_multi_command_storage()
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +62,43 @@ class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView):
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class CommandExportView(DatetimeSearchMixin, AdminUserRequiredMixin, View):
|
||||||
|
model = Command
|
||||||
|
command = user = asset = system_user = action = ''
|
||||||
|
date_from = date_to = None
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
template = 'terminal/command_report.html'
|
||||||
|
context = {
|
||||||
|
'queryset': queryset,
|
||||||
|
'total_count': len(queryset),
|
||||||
|
'now': time.time(),
|
||||||
|
}
|
||||||
|
content = loader.render_to_string(template, context, request)
|
||||||
|
content_type = 'application/octet-stream'
|
||||||
|
response = HttpResponse(content, content_type)
|
||||||
|
filename = 'command-report-{}.html'.format(int(time.time()))
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
self.get_date_range()
|
||||||
|
self.action = self.request.GET.get('action', '')
|
||||||
|
self.command = self.request.GET.get('command', '')
|
||||||
|
self.user = self.request.GET.get("user", '')
|
||||||
|
self.asset = self.request.GET.get('asset', '')
|
||||||
|
self.system_user = self.request.GET.get('system_user', '')
|
||||||
|
filter_kwargs = dict()
|
||||||
|
filter_kwargs['date_from'] = self.date_from
|
||||||
|
filter_kwargs['date_to'] = self.date_to
|
||||||
|
if self.user:
|
||||||
|
filter_kwargs['user'] = self.user
|
||||||
|
if self.asset:
|
||||||
|
filter_kwargs['asset'] = self.asset
|
||||||
|
if self.system_user:
|
||||||
|
filter_kwargs['system_user'] = self.system_user
|
||||||
|
if self.command:
|
||||||
|
filter_kwargs['input'] = self.command
|
||||||
|
queryset = common_storage.filter(**filter_kwargs)
|
||||||
|
return queryset
|
||||||
|
|
|
@ -212,10 +212,10 @@ def write_login_log(*args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def get_ip_city(ip, timeout=10):
|
def get_ip_city(ip, timeout=10):
|
||||||
# Taobao ip api: http://ip.taobao.com//service/getIpInfo.php?ip=8.8.8.8
|
# Taobao ip api: http://ip.taobao.com/service/getIpInfo.php?ip=8.8.8.8
|
||||||
# Sina ip api: http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=8.8.8.8&format=json
|
# Sina ip api: http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=8.8.8.8&format=json
|
||||||
|
|
||||||
url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=%s&format=json' % ip
|
url = 'http://ip.taobao.com/service/getIpInfo.php?ip=%s' % ip
|
||||||
try:
|
try:
|
||||||
r = requests.get(url, timeout=timeout)
|
r = requests.get(url, timeout=timeout)
|
||||||
except:
|
except:
|
||||||
|
@ -224,8 +224,8 @@ def get_ip_city(ip, timeout=10):
|
||||||
if r and r.status_code == 200:
|
if r and r.status_code == 200:
|
||||||
try:
|
try:
|
||||||
data = r.json()
|
data = r.json()
|
||||||
if not isinstance(data, int) and data['ret'] == 1:
|
if not isinstance(data, int) and data['code'] == 0:
|
||||||
city = data['country'] + ' ' + data['city']
|
city = data['data']['country'] + ' ' + data['data']['city']
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
return city
|
return city
|
||||||
|
|
2
jms
2
jms
|
@ -122,8 +122,8 @@ def start_gunicorn():
|
||||||
cmd = [
|
cmd = [
|
||||||
'gunicorn', 'jumpserver.wsgi',
|
'gunicorn', 'jumpserver.wsgi',
|
||||||
'-b', bind,
|
'-b', bind,
|
||||||
'-w', str(WORKERS),
|
|
||||||
'-k', 'eventlet',
|
'-k', 'eventlet',
|
||||||
|
'-w', str(WORKERS),
|
||||||
'--access-logformat', log_format,
|
'--access-logformat', log_format,
|
||||||
'-p', pid_file,
|
'-p', pid_file,
|
||||||
]
|
]
|
||||||
|
|
|
@ -46,7 +46,7 @@ MarkupSafe==1.0
|
||||||
mysqlclient==1.3.12
|
mysqlclient==1.3.12
|
||||||
olefile==0.44
|
olefile==0.44
|
||||||
openapi-codec==1.3.2
|
openapi-codec==1.3.2
|
||||||
paramiko==2.4.0
|
paramiko==2.4.1
|
||||||
passlib==1.7.1
|
passlib==1.7.1
|
||||||
Pillow==4.3.0
|
Pillow==4.3.0
|
||||||
pyasn1==0.4.2
|
pyasn1==0.4.2
|
||||||
|
|
Loading…
Reference in New Issue