mirror of https://github.com/jumpserver/jumpserver
Merge remote-tracking branch 'github/dev' into dev
commit
28e8f204ec
|
@ -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 解绑成功,返回登录页面"
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.shortcuts import get_object_or_404
|
||||||
from rest_framework.views import APIView, Response
|
from rest_framework.views import APIView, Response
|
||||||
from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView
|
from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.pagination import LimitOffsetPagination
|
||||||
|
|
||||||
from common.utils import set_or_append_attr_bulk, get_object_or_none
|
from common.utils import set_or_append_attr_bulk, get_object_or_none
|
||||||
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
|
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
|
||||||
|
|
|
@ -4,6 +4,7 @@ from collections import OrderedDict
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
import copy
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
|
@ -310,6 +311,7 @@ class SessionReplayViewSet(viewsets.ViewSet):
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
session_id = kwargs.get('pk')
|
session_id = kwargs.get('pk')
|
||||||
self.session = get_object_or_404(Session, id=session_id)
|
self.session = get_object_or_404(Session, id=session_id)
|
||||||
|
|
||||||
# 新版本和老版本的文件后缀不同
|
# 新版本和老版本的文件后缀不同
|
||||||
session_path = self.get_session_path() # 存在外部存储上的路径
|
session_path = self.get_session_path() # 存在外部存储上的路径
|
||||||
local_path = self.get_local_path()
|
local_path = self.get_local_path()
|
||||||
|
|
|
@ -92,6 +92,19 @@
|
||||||
{% 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 %}
|
||||||
|
@ -112,6 +125,18 @@
|
||||||
calendarWeeks: true,
|
calendarWeeks: true,
|
||||||
autoclose: 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
|
||||||
|
|
|
@ -59,7 +59,7 @@ function initTable() {
|
||||||
ele: $('#user_list_table'),
|
ele: $('#user_list_table'),
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
var detail_btn = '<a href="{% url "users:user-detail" pk=DEFAULT_PK %}">' + escape(cellData) + '</a>';
|
var detail_btn = '<a href="{% url "users:user-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace("{{ DEFAULT_PK }}", rowData.id));
|
$(td).html(detail_btn.replace("{{ DEFAULT_PK }}", rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -228,7 +228,7 @@ Luna 已改为纯前端,需要 Nginx 来运行访问
|
||||||
-p 8081:8080 -v /opt/guacamole/key:/config/guacamole/key \
|
-p 8081:8080 -v /opt/guacamole/key:/config/guacamole/key \
|
||||||
-e JUMPSERVER_KEY_DIR=/config/guacamole/key \
|
-e JUMPSERVER_KEY_DIR=/config/guacamole/key \
|
||||||
-e JUMPSERVER_SERVER=http://<填写本机的IP地址>:8080 \
|
-e JUMPSERVER_SERVER=http://<填写本机的IP地址>:8080 \
|
||||||
registry.jumpserver.org/public/guacamole:1.0.0
|
registry.jumpserver.org/public/guacamole:latest
|
||||||
|
|
||||||
这里所需要注意的是 guacamole 暴露出来的端口是 8081,若与主机上其他端口冲突请自定义一下。
|
这里所需要注意的是 guacamole 暴露出来的端口是 8081,若与主机上其他端口冲突请自定义一下。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue