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
787be3ff
Unverified
Commit
787be3ff
authored
Apr 25, 2018
by
老广
Committed by
GitHub
Apr 25, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1248 from jumpserver/dev
Bugfix 修复搜索命令的bug
parents
5c17b1a7
d5debc37
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
111 additions
and
9 deletions
+111
-9
asset.py
apps/assets/serializers/asset.py
+32
-2
node.py
apps/assets/serializers/node.py
+6
-0
api.py
apps/terminal/api.py
+56
-0
base.py
apps/terminal/backends/command/base.py
+2
-2
models.py
apps/terminal/models.py
+6
-1
session_list.html
apps/terminal/templates/terminal/session_list.html
+2
-2
api_urls.py
apps/terminal/urls/api_urls.py
+6
-1
command.py
apps/terminal/views/command.py
+1
-1
No files found.
apps/assets/serializers/asset.py
View file @
787be3ff
...
@@ -4,9 +4,38 @@ from rest_framework import serializers
...
@@ -4,9 +4,38 @@ from rest_framework import serializers
from
rest_framework_bulk.serializers
import
BulkListSerializer
from
rest_framework_bulk.serializers
import
BulkListSerializer
from
common.mixins
import
BulkSerializerMixin
from
common.mixins
import
BulkSerializerMixin
from
..models
import
Asset
from
..models
import
Asset
,
Node
from
.system_user
import
AssetSystemUserSerializer
from
.system_user
import
AssetSystemUserSerializer
__all__
=
[
'AssetSerializer'
,
'AssetGrantedSerializer'
,
'MyAssetGrantedSerializer'
,
]
class
NodeTMPSerializer
(
serializers
.
ModelSerializer
):
parent
=
serializers
.
SerializerMethodField
()
assets_amount
=
serializers
.
SerializerMethodField
()
class
Meta
:
model
=
Node
fields
=
[
'id'
,
'key'
,
'value'
,
'parent'
,
'assets_amount'
,
'is_asset'
]
list_serializer_class
=
BulkListSerializer
@staticmethod
def
get_parent
(
obj
):
return
obj
.
parent
.
id
@staticmethod
def
get_assets_amount
(
obj
):
return
obj
.
get_all_assets
()
.
count
()
def
get_fields
(
self
):
fields
=
super
()
.
get_fields
()
field
=
fields
[
"key"
]
field
.
required
=
False
return
fields
class
AssetSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
class
AssetSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
"""
"""
...
@@ -33,12 +62,13 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
...
@@ -33,12 +62,13 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
"""
"""
system_users_granted
=
AssetSystemUserSerializer
(
many
=
True
,
read_only
=
True
)
system_users_granted
=
AssetSystemUserSerializer
(
many
=
True
,
read_only
=
True
)
system_users_join
=
serializers
.
SerializerMethodField
()
system_users_join
=
serializers
.
SerializerMethodField
()
nodes
=
NodeTMPSerializer
(
many
=
True
,
read_only
=
True
)
class
Meta
:
class
Meta
:
model
=
Asset
model
=
Asset
fields
=
(
fields
=
(
"id"
,
"hostname"
,
"ip"
,
"port"
,
"system_users_granted"
,
"id"
,
"hostname"
,
"ip"
,
"port"
,
"system_users_granted"
,
"is_active"
,
"system_users_join"
,
"os"
,
'domain'
,
"is_active"
,
"system_users_join"
,
"os"
,
'domain'
,
"nodes"
,
"platform"
,
"comment"
"platform"
,
"comment"
)
)
...
...
apps/assets/serializers/node.py
View file @
787be3ff
...
@@ -7,6 +7,12 @@ from ..models import Asset, Node
...
@@ -7,6 +7,12 @@ from ..models import Asset, Node
from
.asset
import
AssetGrantedSerializer
from
.asset
import
AssetGrantedSerializer
__all__
=
[
'NodeSerializer'
,
"NodeGrantedSerializer"
,
"NodeAddChildrenSerializer"
,
"NodeAssetsSerializer"
,
]
class
NodeGrantedSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
class
NodeGrantedSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
"""
"""
授权资产组
授权资产组
...
...
apps/terminal/api.py
View file @
787be3ff
...
@@ -182,6 +182,11 @@ class SessionViewSet(viewsets.ModelViewSet):
...
@@ -182,6 +182,11 @@ class SessionViewSet(viewsets.ModelViewSet):
self
.
queryset
=
terminal
.
session_set
.
all
()
self
.
queryset
=
terminal
.
session_set
.
all
()
return
self
.
queryset
return
self
.
queryset
def
perform_create
(
self
,
serializer
):
if
self
.
request
.
user
.
terminal
:
serializer
.
validated_data
[
"terminal"
]
=
self
.
request
.
user
.
terminal
return
super
()
.
perform_create
(
serializer
)
class
TaskViewSet
(
BulkModelViewSet
):
class
TaskViewSet
(
BulkModelViewSet
):
queryset
=
Task
.
objects
.
all
()
queryset
=
Task
.
objects
.
all
()
...
@@ -299,6 +304,57 @@ class SessionReplayViewSet(viewsets.ViewSet):
...
@@ -299,6 +304,57 @@ class SessionReplayViewSet(viewsets.ViewSet):
return
HttpResponseNotFound
()
return
HttpResponseNotFound
()
class
SessionReplayV2ViewSet
(
viewsets
.
ViewSet
):
serializer_class
=
ReplaySerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
session
=
None
def
gen_session_path
(
self
):
date
=
self
.
session
.
date_start
.
strftime
(
'
%
Y-
%
m-
%
d'
)
replay
=
{
"id"
:
self
.
session
.
id
,
# "width": 100,
# "heith": 100
}
if
self
.
session
.
protocol
==
"ssh"
:
replay
[
'type'
]
=
"json"
replay
[
'path'
]
=
os
.
path
.
join
(
date
,
str
(
self
.
session
.
id
)
+
'.gz'
)
return
replay
elif
self
.
session
.
protocol
==
"rdp"
:
replay
[
'type'
]
=
"mp4"
replay
[
'path'
]
=
os
.
path
.
join
(
date
,
str
(
self
.
session
.
id
)
+
'.mp4'
)
return
replay
else
:
return
replay
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
session_id
=
kwargs
.
get
(
'pk'
)
self
.
session
=
get_object_or_404
(
Session
,
id
=
session_id
)
replay
=
self
.
gen_session_path
()
if
replay
.
get
(
"path"
,
""
)
==
""
:
return
HttpResponseNotFound
()
if
default_storage
.
exists
(
replay
[
"path"
]):
replay
[
"src"
]
=
default_storage
.
url
(
replay
[
"path"
])
return
Response
(
replay
)
else
:
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
.
items
()
if
not
configs
:
return
HttpResponseNotFound
()
for
name
,
config
in
configs
:
client
=
jms_storage
.
init
(
config
)
target_path
=
default_storage
.
base_location
+
'/'
+
replay
[
"path"
]
if
client
and
client
.
has_file
(
replay
[
"path"
])
and
\
client
.
download_file
(
replay
[
"path"
],
target_path
):
replay
[
"src"
]
=
default_storage
.
url
(
replay
[
"path"
])
return
Response
(
replay
)
return
HttpResponseNotFound
()
class
TerminalConfig
(
APIView
):
class
TerminalConfig
(
APIView
):
permission_classes
=
(
IsAppUser
,)
permission_classes
=
(
IsAppUser
,)
...
...
apps/terminal/backends/command/base.py
View file @
787be3ff
...
@@ -21,7 +21,7 @@ class CommandBase(object):
...
@@ -21,7 +21,7 @@ class CommandBase(object):
@abc.abstractmethod
@abc.abstractmethod
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
input
=
None
,
session
=
None
):
pass
pass
apps/terminal/models.py
View file @
787be3ff
...
@@ -117,6 +117,10 @@ class Session(models.Model):
...
@@ -117,6 +117,10 @@ class Session(models.Model):
(
'ST'
,
'SSH Terminal'
),
(
'ST'
,
'SSH Terminal'
),
(
'WT'
,
'Web Terminal'
),
(
'WT'
,
'Web Terminal'
),
)
)
PROTOCOL_CHOICES
=
(
(
'ssh'
,
'ssh'
),
(
'rdp'
,
'rdp'
)
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
user
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"User"
))
user
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"User"
))
...
@@ -128,8 +132,9 @@ class Session(models.Model):
...
@@ -128,8 +132,9 @@ class Session(models.Model):
has_replay
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Replay"
))
has_replay
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Replay"
))
has_command
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Command"
))
has_command
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Command"
))
terminal
=
models
.
ForeignKey
(
Terminal
,
null
=
True
,
on_delete
=
models
.
SET_NULL
)
terminal
=
models
.
ForeignKey
(
Terminal
,
null
=
True
,
on_delete
=
models
.
SET_NULL
)
protocol
=
models
.
CharField
(
choices
=
PROTOCOL_CHOICES
,
default
=
'ssh'
,
max_length
=
8
)
date_last_active
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date last active"
),
default
=
timezone
.
now
)
date_last_active
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date last active"
),
default
=
timezone
.
now
)
date_start
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date start"
),
db_index
=
True
)
date_start
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date start"
),
db_index
=
True
,
default
=
timezone
.
now
)
date_end
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date end"
),
null
=
True
)
date_end
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date end"
),
null
=
True
)
class
Meta
:
class
Meta
:
...
...
apps/terminal/templates/terminal/session_list.html
View file @
787be3ff
...
@@ -72,7 +72,7 @@
...
@@ -72,7 +72,7 @@
<th
class=
"text-center"
>
{% trans 'Asset' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset' %}
</th>
<th
class=
"text-center"
>
{% trans 'System user' %}
</th>
<th
class=
"text-center"
>
{% trans 'System user' %}
</th>
<th
class=
"text-center"
>
{% trans 'Remote addr' %}
</th>
<th
class=
"text-center"
>
{% trans 'Remote addr' %}
</th>
<th
class=
"text-center"
>
{% trans '
Termina
l' %}
</th>
<th
class=
"text-center"
>
{% trans '
Protoco
l' %}
</th>
<th
class=
"text-center"
>
{% trans 'Command' %}
</th>
<th
class=
"text-center"
>
{% trans 'Command' %}
</th>
<th
class=
"text-center"
>
{% trans 'Date start' %}
</th>
<th
class=
"text-center"
>
{% trans 'Date start' %}
</th>
{#
<th
class=
"text-center"
>
{% trans 'Date last active' %}
</th>
#}
{#
<th
class=
"text-center"
>
{% trans 'Date last active' %}
</th>
#}
...
@@ -91,7 +91,7 @@
...
@@ -91,7 +91,7 @@
<td
class=
"text-center"
>
{{ session.asset }}
</td>
<td
class=
"text-center"
>
{{ session.asset }}
</td>
<td
class=
"text-center"
>
{{ session.system_user }}
</td>
<td
class=
"text-center"
>
{{ session.system_user }}
</td>
<td
class=
"text-center"
>
{{ session.remote_addr|default:"" }}
</td>
<td
class=
"text-center"
>
{{ session.remote_addr|default:"" }}
</td>
<td
class=
"text-center"
>
{{ session.
terminal.name
}}
</td>
<td
class=
"text-center"
>
{{ session.
protocol
}}
</td>
<td
class=
"text-center"
>
{{ session.id | get_session_command_amount }}
</td>
<td
class=
"text-center"
>
{{ session.id | get_session_command_amount }}
</td>
<td
class=
"text-center"
>
{{ session.date_start }}
</td>
<td
class=
"text-center"
>
{{ session.date_start }}
</td>
...
...
apps/terminal/urls/api_urls.py
View file @
787be3ff
...
@@ -23,8 +23,13 @@ urlpatterns = [
...
@@ -23,8 +23,13 @@ urlpatterns = [
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
name
=
'session-replay'
),
name
=
'session-replay'
),
url
(
r'^v1/tasks/kill-session/'
,
api
.
KillSessionAPI
.
as_view
(),
name
=
'kill-session'
),
url
(
r'^v1/tasks/kill-session/'
,
api
.
KillSessionAPI
.
as_view
(),
name
=
'kill-session'
),
url
(
r'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
url
(
r'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
url
(
r'^v1/terminal/config'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
url
(
r'^v1/terminal/config'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
# v2: get session's replay
url
(
r'^v2/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$'
,
api
.
SessionReplayV2ViewSet
.
as_view
({
'get'
:
'retrieve'
}),
name
=
'session-replay-v2'
),
]
]
urlpatterns
+=
router
.
urls
urlpatterns
+=
router
.
urls
apps/terminal/views/command.py
View file @
787be3ff
...
@@ -38,7 +38,7 @@ class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView):
...
@@ -38,7 +38,7 @@ class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView):
if
self
.
system_user
:
if
self
.
system_user
:
filter_kwargs
[
'system_user'
]
=
self
.
system_user
filter_kwargs
[
'system_user'
]
=
self
.
system_user
if
self
.
command
:
if
self
.
command
:
filter_kwargs
[
'input
__contains
'
]
=
self
.
command
filter_kwargs
[
'input'
]
=
self
.
command
queryset
=
common_storage
.
filter
(
**
filter_kwargs
)
queryset
=
common_storage
.
filter
(
**
filter_kwargs
)
return
queryset
return
queryset
...
...
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