mirror of https://github.com/jumpserver/jumpserver
[Feture] session detail页面,包含命令列表
parent
01558c985a
commit
9b6696bb6e
|
@ -2,7 +2,6 @@
|
|||
|
||||
from django import template
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
from django.utils.html import escape
|
||||
from audits.backends import command_store
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class StatusViewSet(viewsets.ModelViewSet):
|
|||
for session_data in self.request.data.get("sessions", []):
|
||||
self.create_or_update_session(session_data)
|
||||
if not session_data["is_finished"]:
|
||||
sessions_active.append(session_data["uuid"])
|
||||
sessions_active.append(session_data["id"])
|
||||
|
||||
sessions_in_db_active = Session.objects.filter(
|
||||
is_finished=False,
|
||||
|
@ -92,15 +92,15 @@ class StatusViewSet(viewsets.ModelViewSet):
|
|||
)
|
||||
|
||||
for session in sessions_in_db_active:
|
||||
if str(session.uuid) not in sessions_active:
|
||||
if str(session.id) not in sessions_active:
|
||||
session.is_finished = True
|
||||
session.date_end = timezone.now()
|
||||
session.save()
|
||||
|
||||
def create_or_update_session(self, session_data):
|
||||
session_data["terminal"] = self.request.user.terminal.id
|
||||
_uuid = session_data["uuid"]
|
||||
session = get_object_or_none(Session, uuid=_uuid)
|
||||
_id = session_data["id"]
|
||||
session = get_object_or_none(Session, id=_id)
|
||||
if session:
|
||||
serializer = SessionSerializer(
|
||||
data=session_data, instance=session
|
||||
|
@ -210,7 +210,7 @@ class CommandViewSet(viewsets.ViewSet):
|
|||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
def get_queryset(self):
|
||||
self.command_store.all()
|
||||
self.command_store.filter(**dict(self.request.data))
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data, many=True)
|
||||
|
@ -221,7 +221,6 @@ class CommandViewSet(viewsets.ViewSet):
|
|||
else:
|
||||
return Response("save error", status=500)
|
||||
else:
|
||||
print(serializer.errors)
|
||||
return Response({"msg": "Not valid: {}".format(serializer.errors)}, status=401)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
|
|
|
@ -14,9 +14,8 @@ class CommandBase(object):
|
|||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def filter(self, date_from=None, date_to=None, user=None,
|
||||
asset=None, system_user=None, command=None, session=None):
|
||||
def filter(self, date_from=None, date_to=None,
|
||||
user=None, asset=None, system_user=None,
|
||||
input=None, session=None):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -37,27 +37,26 @@ class CommandStore(CommandBase):
|
|||
))
|
||||
return self.model.objects.bulk_create(_commands)
|
||||
|
||||
def filter(self, date_from=None, date_to=None, user=None,
|
||||
asset=None, system_user=None, _input=None, session=None):
|
||||
def filter(self, date_from=None, date_to=None,
|
||||
user=None, asset=None, system_user=None,
|
||||
input=None, session=None):
|
||||
filter_kwargs = {}
|
||||
date_from_default = timezone.now() - datetime.timedelta(days=7)
|
||||
date_to_default = timezone.now()
|
||||
|
||||
date_from = date_from if date_from else date_from_default
|
||||
date_to = date_to if date_to else date_to_default
|
||||
filter_kwargs['timestamp__gte'] = int(date_from.timestamp())
|
||||
filter_kwargs['timestamp__lte'] = int(date_to.timestamp())
|
||||
|
||||
if date_from:
|
||||
filter_kwargs['timestamp__gte'] = int(date_from.timestamp())
|
||||
else:
|
||||
week_ago = timezone.now() - datetime.timedelta(days=7)
|
||||
filter_kwargs['timestamp__gte'] = int(week_ago.timestamp())
|
||||
if date_to:
|
||||
filter_kwargs['timestamp__lte'] = int(date_to.timestamp())
|
||||
else:
|
||||
filter_kwargs['timestamp__lte'] = int(timezone.now().timestamp())
|
||||
if user:
|
||||
filter_kwargs['user'] = user
|
||||
filter_kwargs["user"] = user
|
||||
if asset:
|
||||
filter_kwargs['asset'] = asset
|
||||
if system_user:
|
||||
filter_kwargs['system_user'] = system_user
|
||||
if _input:
|
||||
filter_kwargs['input__icontains'] = _input
|
||||
if input:
|
||||
filter_kwargs['input__icontains'] = input
|
||||
if session:
|
||||
filter_kwargs['session'] = session
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ class AbstractSessionCommand(models.Model):
|
|||
asset = models.CharField(max_length=128, verbose_name=_("Asset"))
|
||||
system_user = models.CharField(max_length=64, verbose_name=_("System user"))
|
||||
input = models.CharField(max_length=128, db_index=True, verbose_name=_("Input"))
|
||||
output = models.CharField(max_length=1024, verbose_name=_("Output"))
|
||||
output = models.CharField(max_length=1024, blank=True, verbose_name=_("Output"))
|
||||
session = models.CharField(max_length=36, db_index=True, verbose_name=_("Session"))
|
||||
timestamp = models.IntegerField(db_index=True)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class SessionCommandSerializer(serializers.Serializer):
|
|||
asset = serializers.CharField(max_length=128)
|
||||
system_user = serializers.CharField(max_length=64)
|
||||
input = serializers.CharField(max_length=128)
|
||||
output = serializers.CharField(max_length=1024)
|
||||
output = serializers.CharField(max_length=1024, allow_blank=True)
|
||||
session = serializers.CharField(max_length=36)
|
||||
timestamp = serializers.IntegerField()
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class Session(models.Model):
|
|||
('WT', 'Web Terminal'),
|
||||
)
|
||||
|
||||
uuid = models.UUIDField(default=uuid.uuid4, db_index=True)
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
user = models.CharField(max_length=128, verbose_name=_("User"))
|
||||
asset = models.CharField(max_length=1024, verbose_name=_("Asset"))
|
||||
system_user = models.CharField(max_length=128, verbose_name=_("System User"))
|
||||
|
@ -126,3 +126,4 @@ class Command(AbstractSessionCommand):
|
|||
|
||||
class Meta:
|
||||
db_table = "terminal_command"
|
||||
ordering = ('timestamp',)
|
||||
|
|
|
@ -5,7 +5,7 @@ from django.utils import timezone
|
|||
from rest_framework import serializers
|
||||
|
||||
from .models import Terminal, Status, Session, Task
|
||||
from .hands import ProxyLog
|
||||
from .backends import get_command_store
|
||||
|
||||
|
||||
class TerminalSerializer(serializers.ModelSerializer):
|
||||
|
@ -36,11 +36,16 @@ class TerminalSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class SessionSerializer(serializers.ModelSerializer):
|
||||
command_amount = serializers.SerializerMethodField()
|
||||
command_store = get_command_store()
|
||||
|
||||
class Meta:
|
||||
model = Session
|
||||
fields = '__all__'
|
||||
|
||||
def get_command_amount(self, obj):
|
||||
return len(self.command_store.filter(session=obj.session))
|
||||
|
||||
|
||||
class StatusSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="col-sm-11" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Command log list' %} <b>{{ user_object.name }}</b></span>
|
||||
<span style="float: left">{% trans 'Command list' %} <b></b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
|
@ -43,18 +43,22 @@
|
|||
<tr>
|
||||
<th data-toggle="true">ID</th>
|
||||
<th>Command</th>
|
||||
<th data-hide="all">Output</th>
|
||||
<th data-hide="all"></th>
|
||||
<th>Datetime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for command in object_list %}
|
||||
<tr>
|
||||
<td>{{ command.command_no }}</td>
|
||||
<td>{{ command.command }}</td>
|
||||
<td><pre style="border: none;background: none">{{ command.output|to_html|safe}}</pre></td>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ command.input }}</td>
|
||||
<td><pre style="border: none;background: none">{{ command.output }}</pre></td>
|
||||
<td>{{ command.timestamp|ts_to_date}}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="3">{% trans "There is no command about this session" %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load terminal_tags %}
|
||||
{% block content_left_head %}
|
||||
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
|
||||
<style>
|
||||
|
@ -77,13 +78,13 @@
|
|||
<tr class="gradeX">
|
||||
<td class="text-center"><input type="checkbox" class="cbx-term" value="{{ session.id }}"></td>
|
||||
<td class="text-center">
|
||||
<a href="">{{ session.id }}</a>
|
||||
<a href="{% url 'terminal:session-detail' pk=session.id %}">{{ forloop.counter }}</a>
|
||||
</td>
|
||||
<td class="text-center">{{ session.user }}</td>
|
||||
<td class="text-center">{{ session.asset }}</td>
|
||||
<td class="text-center">{{ session.system_user }}</td>
|
||||
<td class="text-center">{{ session.terminal.name }}</td>
|
||||
<td class="text-center">{{ session.commands.all|length}}</td>
|
||||
<td class="text-center">{{ session.id | get_session_command_amount }}</td>
|
||||
{% if session.is_finished %}
|
||||
<td class="text-center">
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
|
@ -0,0 +1,14 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
from django import template
|
||||
from ..backends import get_command_store
|
||||
|
||||
register = template.Library()
|
||||
command_store = get_command_store()
|
||||
|
||||
|
||||
@register.filter
|
||||
def get_session_command_amount(session_id):
|
||||
print(session_id)
|
||||
return len(command_store.filter(session=str(session_id)))
|
||||
|
|
@ -19,4 +19,5 @@ urlpatterns = [
|
|||
# Session view
|
||||
url(r'^session/online/$', views.SessionOnlineListView.as_view(), name='session-online-list'),
|
||||
url(r'^session/offline$', views.SessionOfflineListView.as_view(), name='session-offline-list'),
|
||||
url(r'^session/(?P<pk>[0-9a-zA-Z\-]+)/$', views.SessionDetailView.as_view(), name='session-detail'),
|
||||
]
|
||||
|
|
|
@ -21,8 +21,11 @@ from ..backends import get_command_store
|
|||
|
||||
__all__ = [
|
||||
'SessionOnlineListView', 'SessionOfflineListView',
|
||||
'SessionDetailView',
|
||||
]
|
||||
|
||||
command_store = get_command_store()
|
||||
|
||||
|
||||
class SessionListView(AdminUserRequiredMixin, ListView):
|
||||
model = Session
|
||||
|
@ -101,6 +104,7 @@ class SessionOnlineListView(SessionListView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Terminal'),
|
||||
'action': _('Session online list'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
|
@ -117,10 +121,26 @@ class SessionOfflineListView(SessionListView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Terminal'),
|
||||
'action': _('Session offline list'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class SessionDetailView(SingleObjectMixin, ListView):
|
||||
template_name = 'terminal/session_detail.html'
|
||||
model = Session
|
||||
|
||||
def get_queryset(self):
|
||||
self.object = self.get_object(self.model.objects.all())
|
||||
return command_store.filter(session=self.object.id)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Terminal'),
|
||||
'action': _('Session detail'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
|
Loading…
Reference in New Issue