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
dfcbdb0c
Commit
dfcbdb0c
authored
Jul 03, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改command导出和搜索
parent
5f6af8c0
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
145 additions
and
149 deletions
+145
-149
urls.py
apps/jumpserver/urls.py
+6
-2
jumpserver.js
apps/static/js/jumpserver.js
+12
-0
__init__.py
apps/terminal/api/__init__.py
+1
-0
command.py
apps/terminal/api/command.py
+100
-0
session.py
apps/terminal/api/session.py
+6
-74
command_list.html
apps/terminal/templates/terminal/command_list.html
+16
-16
api_urls.py
apps/terminal/urls/api_urls.py
+1
-0
views_urls.py
apps/terminal/urls/views_urls.py
+0
-1
utils.py
apps/terminal/utils.py
+1
-1
command.py
apps/terminal/views/command.py
+1
-44
session.py
apps/terminal/views/session.py
+1
-11
No files found.
apps/jumpserver/urls.py
View file @
dfcbdb0c
...
...
@@ -44,8 +44,12 @@ app_view_patterns = [
if
settings
.
XPACK_ENABLED
:
app_view_patterns
.
append
(
path
(
'xpack/'
,
include
(
'xpack.urls.view_urls'
,
namespace
=
'xpack'
)))
api_v1
.
append
(
path
(
'xpack/v1/'
,
include
(
'xpack.urls.api_urls'
,
namespace
=
'api-xpack'
)))
app_view_patterns
.
append
(
path
(
'xpack/'
,
include
(
'xpack.urls.view_urls'
,
namespace
=
'xpack'
))
)
api_v1
.
append
(
path
(
'xpack/v1/'
,
include
(
'xpack.urls.api_urls'
,
namespace
=
'api-xpack'
))
)
js_i18n_patterns
=
i18n_patterns
(
path
(
'jsi18n/'
,
JavaScriptCatalog
.
as_view
(),
name
=
'javascript-catalog'
),
...
...
apps/static/js/jumpserver.js
View file @
dfcbdb0c
...
...
@@ -475,6 +475,7 @@ jumpserver.initDataTable = function (options) {
dom
:
options
.
dom
||
'<"#uc.pull-left">flt<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>'
,
order
:
options
.
order
||
[],
// select: options.select || 'multi',
searchDelay
:
800
,
buttons
:
[],
columnDefs
:
columnDefs
,
ajax
:
{
...
...
@@ -574,6 +575,7 @@ jumpserver.initServerSideDataTable = function (options) {
columnDefs
:
columnDefs
,
serverSide
:
true
,
processing
:
true
,
searchDelay
:
800
,
ajax
:
{
url
:
options
.
ajax_url
,
error
:
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
...
...
@@ -1103,3 +1105,12 @@ function formatDateAsCN(d) {
var
date
=
new
Date
(
d
);
return
date
.
toISOString
().
replace
(
"T"
,
" "
).
replace
(
/
\.
.*/
,
""
);
}
function
getUrlParams
(
url
)
{
url
=
url
.
split
(
"?"
);
let
params
=
""
;
if
(
url
.
length
===
2
){
params
=
url
[
1
];
}
return
params
}
\ No newline at end of file
apps/terminal/api/__init__.py
View file @
dfcbdb0c
...
...
@@ -2,4 +2,5 @@
#
from
.terminal
import
*
from
.session
import
*
from
.command
import
*
from
.task
import
*
apps/terminal/api/command.py
0 → 100644
View file @
dfcbdb0c
# -*- coding: utf-8 -*-
#
import
time
from
django.utils
import
timezone
from
django.shortcuts
import
HttpResponse
from
rest_framework.pagination
import
LimitOffsetPagination
from
rest_framework
import
viewsets
from
rest_framework
import
generics
from
rest_framework.response
import
Response
from
django.template
import
loader
from
common.permissions
import
IsOrgAdminOrAppUser
,
IsAuditor
from
common.utils
import
get_logger
from
..backends
import
(
get_command_storage
,
get_multi_command_storage
,
SessionCommandSerializer
,
)
logger
=
get_logger
(
__name__
)
__all__
=
[
'CommandViewSet'
,
'CommandExportApi'
]
class
CommandQueryMixin
:
command_store
=
get_command_storage
()
pagination_class
=
LimitOffsetPagination
permission_classes
=
[
IsOrgAdminOrAppUser
|
IsAuditor
]
filter_fields
=
[
"asset"
,
"system_user"
,
"user"
,
"input"
,
"session"
,
]
default_days_ago
=
5
def
get_queryset
(
self
):
date_from
,
date_to
=
self
.
get_date_range
()
multi_command_storage
=
get_multi_command_storage
()
queryset
=
multi_command_storage
.
filter
(
date_from
=
date_from
,
date_to
=
date_to
)
return
queryset
def
get_filter_fields
(
self
):
fields
=
self
.
filter_fields
fields
.
extend
([
"date_from"
,
"date_to"
])
return
fields
def
get_date_range
(
self
):
now
=
timezone
.
now
()
days_ago
=
now
-
timezone
.
timedelta
(
days
=
self
.
default_days_ago
)
default_start_st
=
days_ago
.
timestamp
()
default_end_st
=
now
.
timestamp
()
query_params
=
self
.
request
.
query_params
date_from_st
=
query_params
.
get
(
"date_from"
)
or
default_start_st
date_to_st
=
query_params
.
get
(
"date_to"
)
or
default_end_st
return
float
(
date_from_st
),
float
(
date_to_st
)
class
CommandViewSet
(
CommandQueryMixin
,
viewsets
.
ModelViewSet
):
"""接受app发送来的command log, 格式如下
{
"user": "admin",
"asset": "localhost",
"system_user": "web",
"session": "xxxxxx",
"input": "whoami",
"output": "d2hvbWFp", # base64.b64encode(s)
"timestamp": 1485238673.0
}
"""
command_store
=
get_command_storage
()
serializer_class
=
SessionCommandSerializer
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
serializer
=
self
.
serializer_class
(
data
=
request
.
data
,
many
=
True
)
if
serializer
.
is_valid
():
ok
=
self
.
command_store
.
bulk_save
(
serializer
.
validated_data
)
if
ok
:
return
Response
(
"ok"
,
status
=
201
)
else
:
return
Response
(
"Save error"
,
status
=
500
)
else
:
msg
=
"Command not valid: {}"
.
format
(
serializer
.
errors
)
logger
.
error
(
msg
)
return
Response
({
"msg"
:
msg
},
status
=
401
)
class
CommandExportApi
(
CommandQueryMixin
,
generics
.
ListAPIView
):
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
self
.
filter_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
apps/terminal/api/session.py
View file @
dfcbdb0c
# -*- coding: utf-8 -*-
#
import
logging
import
os
from
django.shortcuts
import
get_object_or_404
from
django.core.files.storage
import
default_storage
from
django.http
import
HttpResponseNotFound
from
django.conf
import
settings
from
django.utils
import
timezone
from
rest_framework.pagination
import
LimitOffsetPagination
from
rest_framework
import
viewsets
from
rest_framework.response
import
Response
...
...
@@ -15,16 +13,15 @@ from rest_framework_bulk import BulkModelViewSet
import
jms_storage
from
common.utils
import
is_uuid
from
common.utils
import
is_uuid
,
get_logger
from
common.permissions
import
IsOrgAdminOrAppUser
,
IsAuditor
from
..hands
import
SystemUser
from
..models
import
Terminal
,
Session
from
..models
import
Session
from
..
import
serializers
from
..backends
import
get_command_storage
,
get_multi_command_storage
,
\
SessionCommandSerializer
__all__
=
[
'SessionViewSet'
,
'SessionReplayViewSet'
,
'CommandViewSet'
]
logger
=
logging
.
getLogger
(
__file__
)
__all__
=
[
'SessionViewSet'
,
'SessionReplayViewSet'
,]
logger
=
get_logger
(
__name__
)
class
SessionViewSet
(
BulkModelViewSet
):
...
...
@@ -32,15 +29,7 @@ class SessionViewSet(BulkModelViewSet):
serializer_class
=
serializers
.
SessionSerializer
pagination_class
=
LimitOffsetPagination
permission_classes
=
(
IsOrgAdminOrAppUser
|
IsAuditor
,
)
def
get_queryset
(
self
):
queryset
=
super
()
.
get_queryset
()
terminal_id
=
self
.
kwargs
.
get
(
"terminal"
,
None
)
if
terminal_id
:
terminal
=
get_object_or_404
(
Terminal
,
id
=
terminal_id
)
queryset
=
queryset
.
filter
(
terminal
=
terminal
)
return
queryset
return
queryset
filter_fields
=
[
"user"
,
"asset"
,
"system_user"
,
"terminal"
]
def
get_object
(
self
):
# 解决guacamole更新session时并发导致幽灵会话的问题
...
...
@@ -60,63 +49,6 @@ class SessionViewSet(BulkModelViewSet):
return
super
()
.
perform_create
(
serializer
)
class
CommandViewSet
(
viewsets
.
ModelViewSet
):
"""接受app发送来的command log, 格式如下
{
"user": "admin",
"asset": "localhost",
"system_user": "web",
"session": "xxxxxx",
"input": "whoami",
"output": "d2hvbWFp", # base64.b64encode(s)
"timestamp": 1485238673.0
}
"""
command_store
=
get_command_storage
()
serializer_class
=
SessionCommandSerializer
pagination_class
=
LimitOffsetPagination
permission_classes
=
[
IsOrgAdminOrAppUser
|
IsAuditor
]
filter_fields
=
[
"asset"
,
"system_user"
,
"user"
,
"input"
,
"session"
,
]
default_days_ago
=
5
def
get_queryset
(
self
):
date_from
,
date_to
=
self
.
get_date_range
()
multi_command_storage
=
get_multi_command_storage
()
queryset
=
multi_command_storage
.
filter
(
date_from
=
date_from
,
date_to
=
date_to
)
return
queryset
def
get_filter_fields
(
self
):
fields
=
self
.
filter_fields
fields
.
extend
([
"date_from"
,
"date_to"
])
return
fields
def
get_date_range
(
self
):
now
=
timezone
.
now
()
days_ago
=
now
-
timezone
.
timedelta
(
days
=
self
.
default_days_ago
)
default_start_st
=
days_ago
.
timestamp
()
default_end_st
=
now
.
timestamp
()
query_params
=
self
.
request
.
query_params
date_from_st
=
query_params
.
get
(
"date_from"
)
or
default_start_st
date_to_st
=
query_params
.
get
(
"date_to"
)
or
default_end_st
return
int
(
date_from_st
),
int
(
date_to_st
)
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
serializer
=
self
.
serializer_class
(
data
=
request
.
data
,
many
=
True
)
if
serializer
.
is_valid
():
ok
=
self
.
command_store
.
bulk_save
(
serializer
.
validated_data
)
if
ok
:
return
Response
(
"ok"
,
status
=
201
)
else
:
return
Response
(
"Save error"
,
status
=
500
)
else
:
msg
=
"Command not valid: {}"
.
format
(
serializer
.
errors
)
logger
.
error
(
msg
)
return
Response
({
"msg"
:
msg
},
status
=
401
)
class
SessionReplayViewSet
(
viewsets
.
ViewSet
):
serializer_class
=
serializers
.
ReplaySerializer
permission_classes
=
(
IsOrgAdminOrAppUser
,)
...
...
apps/terminal/templates/terminal/command_list.html
View file @
dfcbdb0c
...
...
@@ -80,7 +80,7 @@ $(document).ready(function () {
table
=
initTable
().
on
(
"init"
,
function
()
{
var
dateFromRef
=
$
(
"#date_from"
);
var
dateToRef
=
$
(
"#date_to"
);
let
options
=
{
var
options
=
{
format
:
"yyyy-mm-dd"
,
todayBtn
:
"linked"
,
keyboardNavigation
:
false
,
...
...
@@ -90,16 +90,15 @@ $(document).ready(function () {
language
:
navigator
.
language
||
"en"
,
};
dateFromRef
.
datepicker
(
options
).
on
(
"changeDate"
,
function
()
{
let
date
=
new
Date
(
$
(
this
).
val
()
+
' 0:0:0'
);
let
url
=
table
.
ajax
.
url
();
var
date
=
new
Date
(
$
(
this
).
val
()
+
' 0:0:0'
);
var
url
=
table
.
ajax
.
url
();
url
=
setUrlParam
(
url
,
"date_from"
,
date
.
getTime
()
/
1000
);
table
.
ajax
.
url
(
url
);
table
.
ajax
.
reload
();
console
.
log
(
"On change"
)
});
dateToRef
.
datepicker
(
options
).
on
(
"changeDate"
,
function
()
{
let
date
=
new
Date
(
$
(
this
).
val
()
+
' 23:59:59'
);
let
url
=
table
.
ajax
.
url
();
var
date
=
new
Date
(
$
(
this
).
val
()
+
' 23:59:59'
);
var
url
=
table
.
ajax
.
url
();
url
=
setUrlParam
(
url
,
"date_to"
,
date
.
getTime
()
/
1000
);
table
.
ajax
.
url
(
url
);
table
.
ajax
.
reload
();
...
...
@@ -107,15 +106,11 @@ $(document).ready(function () {
});
})
.
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
;
// var action = $('#slct_bulk_update').val();
var
params
=
getUrlParams
(
table
.
ajax
.
url
());
var
exportPath
=
"{% url 'api-terminal:command-export' %}"
;
var
url
=
exportPath
+
"?"
+
params
;
window
.
open
(
url
);
}).
on
(
"click"
,
'#command_table_filter input'
,
function
(
e
)
{
e
.
preventDefault
();
...
...
@@ -182,8 +177,13 @@ function format(d) {
return
output
}
var
commandListUrl
=
'{% url "api-terminal:command-list" %}'
;
var
dateFrom
=
"{{ date_from.timestamp }}"
;
var
dateTo
=
"{{ date_to.timestamp }}"
;
function
initTable
()
{
commandListUrl
=
setUrlParam
(
commandListUrl
,
"date_from"
,
dateFrom
);
commandListUrl
=
setUrlParam
(
commandListUrl
,
"date_to"
,
dateTo
);
var
options
=
{
ele
:
$
(
'#command_table'
),
columnDefs
:
[
...
...
@@ -202,7 +202,7 @@ function initTable() {
}},
],
toggle
:
true
,
ajax_url
:
'{% url "api-terminal:command-list" %}'
,
ajax_url
:
commandListUrl
,
columns
:
[
{
data
:
"id"
},
{
data
:
"input"
,
orderable
:
false
},
{
data
:
"user"
,
orderable
:
false
},
{
data
:
"asset"
},
{
data
:
"system_user"
},
...
...
apps/terminal/urls/api_urls.py
View file @
dfcbdb0c
...
...
@@ -26,6 +26,7 @@ urlpatterns = [
path
(
'terminal/<uuid:terminal>/access-key/'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
path
(
'terminal/config/'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
path
(
'commands/export/'
,
api
.
CommandExportApi
.
as_view
(),
name
=
"command-export"
)
# v2: get session's replay
# path('v2/sessions/<uuid:pk>/replay/',
# api.SessionReplayV2ViewSet.as_view({'get': 'retrieve'}),
...
...
apps/terminal/urls/views_urls.py
View file @
dfcbdb0c
...
...
@@ -25,6 +25,5 @@ urlpatterns = [
# Command view
path
(
'command/'
,
views
.
CommandListView
.
as_view
(),
name
=
'command-list'
),
path
(
'command/export/'
,
views
.
CommandExportView
.
as_view
(),
name
=
'command-export'
)
]
apps/terminal/utils.py
View file @
dfcbdb0c
...
...
@@ -9,7 +9,7 @@ from .const import USERS_CACHE_KEY, ASSETS_CACHE_KEY, SYSTEM_USER_CACHE_KEY
def
get_session_asset_list
():
return
Asset
.
objects
.
values_list
()
return
Asset
.
objects
.
values_list
(
'hostname'
,
flat
=
True
)
def
get_session_user_list
():
...
...
apps/terminal/views/command.py
View file @
dfcbdb0c
...
...
@@ -10,10 +10,9 @@ import time
from
common.mixins
import
DatetimeSearchMixin
from
common.permissions
import
PermissionsMixin
,
IsOrgAdmin
,
IsAuditor
from
..models
import
Command
from
..backends
import
get_multi_command_storage
__all__
=
[
'CommandListView'
,
'CommandExportView'
]
__all__
=
[
'CommandListView'
]
common_storage
=
get_multi_command_storage
()
...
...
@@ -33,45 +32,3 @@ class CommandListView(DatetimeSearchMixin, PermissionsMixin, TemplateView):
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandExportView
(
DatetimeSearchMixin
,
PermissionsMixin
,
View
):
model
=
Command
command
=
user
=
asset
=
system_user
=
action
=
''
date_from
=
date_to
=
None
permission_classes
=
[
IsOrgAdmin
|
IsAuditor
]
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
apps/terminal/views/session.py
View file @
dfcbdb0c
...
...
@@ -38,21 +38,11 @@ class SessionListView(PermissionsMixin, DatetimeSearchMixin, ListView):
filter_kwargs
=
dict
()
filter_kwargs
[
'date_start__gt'
]
=
self
.
date_from
filter_kwargs
[
'date_start__lt'
]
=
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
filter_kwargs
:
self
.
queryset
=
self
.
queryset
.
filter
(
**
filter_kwargs
)
return
self
.
queryset
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'user_list'
:
utils
.
get_session_user_list
(),
'asset_list'
:
utils
.
get_session_asset_list
(),
'system_user_list'
:
utils
.
get_session_system_user_list
(),
'asset_list'
:
utils
.
get_session_asset_list
()[:
10
],
'date_from'
:
self
.
date_from
,
'date_to'
:
self
.
date_to
,
'user'
:
self
.
user
,
...
...
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