From bf8fa95597a4175bad8ac6251fb910bd9d86135a Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 1 Dec 2017 21:22:32 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9session?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/templates/_nav.html | 2 +- apps/terminal/api.py | 13 +- apps/terminal/models.py | 6 +- apps/terminal/serializers.py | 9 +- .../templates/terminal/command_list.html | 109 +++++++++++ .../terminal/session_commands_list_modal.html | 58 ++++++ .../templates/terminal/session_detail.html | 85 +++++++++ .../templates/terminal/session_offline.html | 159 ++++++++++++++++ .../templates/terminal/session_online.html | 173 ++++++++++++++++++ apps/terminal/urls/views_urls.py | 17 +- apps/terminal/views/__init__.py | 4 + apps/terminal/views/session.py | 126 +++++++++++++ apps/terminal/{views.py => views/terminal.py} | 14 +- 13 files changed, 753 insertions(+), 22 deletions(-) create mode 100644 apps/terminal/templates/terminal/command_list.html create mode 100644 apps/terminal/templates/terminal/session_commands_list_modal.html create mode 100644 apps/terminal/templates/terminal/session_detail.html create mode 100644 apps/terminal/templates/terminal/session_offline.html create mode 100644 apps/terminal/templates/terminal/session_online.html create mode 100644 apps/terminal/views/__init__.py create mode 100644 apps/terminal/views/session.py rename apps/terminal/{views.py => views/terminal.py} (90%) diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html index 6d125e9c2..9558bb48d 100644 --- a/apps/templates/_nav.html +++ b/apps/templates/_nav.html @@ -41,7 +41,7 @@ diff --git a/apps/terminal/api.py b/apps/terminal/api.py index ca3e5b112..d8b90e734 100644 --- a/apps/terminal/api.py +++ b/apps/terminal/api.py @@ -78,19 +78,20 @@ class TerminalStatusViewSet(viewsets.ModelViewSet): sessions_active = [] for session_data in self.request.data.get("sessions", []): session_data["terminal"] = self.request.user.terminal.id - _id = session_data["id"] - session = get_object_or_none(Session, id=_id) + _uuid = session_data["uuid"] + session = get_object_or_none(Session, uuid=_uuid) if session: - serializer = TerminalSessionSerializer(data=session_data, - instance=session) + serializer = TerminalSessionSerializer( + data=session_data, instance=session + ) else: serializer = TerminalSessionSerializer(data=session_data) if serializer.is_valid(): serializer.save() else: - logger.error("session serializer is not valid {}".format( - serializer.errors)) + msg = "session data is not valid {}".format(serializer.errors) + logger.error(msg) if not session_data["is_finished"]: sessions_active.append(session_data["id"]) diff --git a/apps/terminal/models.py b/apps/terminal/models.py index e7643e5b4..2e0fe98e2 100644 --- a/apps/terminal/models.py +++ b/apps/terminal/models.py @@ -74,6 +74,10 @@ class Status(models.Model): class Meta: db_table = 'terminal_status' + get_latest_by = 'date_created' + + def __str__(self): + return self.date_created.strftime("%Y-%m-%d %H:%M:%S") class Session(models.Model): @@ -82,7 +86,7 @@ class Session(models.Model): ('WT', 'Web Terminal'), ) - id = models.UUIDField(default=uuid.uuid4, primary_key=True) + uuid = models.UUIDField(default=uuid.uuid4, db_index=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")) diff --git a/apps/terminal/serializers.py b/apps/terminal/serializers.py index 7abab05b7..79d1bc03f 100644 --- a/apps/terminal/serializers.py +++ b/apps/terminal/serializers.py @@ -23,8 +23,13 @@ class TerminalSerializer(serializers.ModelSerializer): @staticmethod def get_is_alive(obj): - log = obj.status_set.last() - if log and timezone.now() - log.date_created < timezone.timedelta(seconds=600): + status = obj.status_set.latest() + + if not status: + return False + + delta = timezone.now() - status.date_created + if delta < timezone.timedelta(seconds=600): return True else: return False diff --git a/apps/terminal/templates/terminal/command_list.html b/apps/terminal/templates/terminal/command_list.html new file mode 100644 index 000000000..04bb976fb --- /dev/null +++ b/apps/terminal/templates/terminal/command_list.html @@ -0,0 +1,109 @@ +{% extends '_base_list.html' %} +{% load i18n %} +{% load static %} +{% load common_tags %} +{% block content_left_head %} + + + +{% endblock %} + +{% block table_search %} +
+
+
+ + + to + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+{% endblock %} +{% block table_container %} + + + + + + + + + + + + + + + {% for command in command_list %} + + + + + + + + + + + {% endfor %} + +
IDCommandUsernameIPSystem userProxy logDatetimeOutput
{{ command.id }}{{ command.command }}{{ command.user }}{{ command.asset }}{{ command.system_user }}{{ command.proxy_log_id}}{{ command.timestamp|ts_to_date }}
{{ command.output|to_html|safe }}
+{% endblock %} + +{% block custom_foot_js %} + + + +{% endblock %} + + diff --git a/apps/terminal/templates/terminal/session_commands_list_modal.html b/apps/terminal/templates/terminal/session_commands_list_modal.html new file mode 100644 index 000000000..fca95de6e --- /dev/null +++ b/apps/terminal/templates/terminal/session_commands_list_modal.html @@ -0,0 +1,58 @@ +{% load static %} + + + + + + + {% include '_head_css_js.html' %} + + + + + + + +
+
+
+ + + + + + + + + + + + {% for command in object_list %} + + + + + + + {% endfor %} + + + + + + +
IDCommandOutputDatetime
{{ command.command_no }}{{ command.command }}{{ command.output_decode |safe }}{{ command.datetime }}
+
    +
    +
    +
    +
    + + + + diff --git a/apps/terminal/templates/terminal/session_detail.html b/apps/terminal/templates/terminal/session_detail.html new file mode 100644 index 000000000..0fa28b517 --- /dev/null +++ b/apps/terminal/templates/terminal/session_detail.html @@ -0,0 +1,85 @@ +{% extends 'base.html' %} +{% load static %} +{% load i18n %} +{% load common_tags %} + +{% block custom_head_css_js %} + +{% endblock %} +{% block content %} +
    +
    +
    +
    + +
    +
    +
    +
    + {% trans 'Command log list' %} {{ user_object.name }} +
    + + + + + + + + + + +
    +
    +
    + + + + + + + + + + + {% for command in object_list %} + + + + + + + {% endfor %} + + + + + + +
    IDCommandOutputDatetime
    {{ command.command_no }}{{ command.command }}
    {{ command.output|to_html|safe}}
    {{ command.timestamp|ts_to_date}}
    +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +{% endblock %} +{% block custom_foot_js %} + + +{% endblock %} diff --git a/apps/terminal/templates/terminal/session_offline.html b/apps/terminal/templates/terminal/session_offline.html new file mode 100644 index 000000000..7dcac94b7 --- /dev/null +++ b/apps/terminal/templates/terminal/session_offline.html @@ -0,0 +1,159 @@ +{% extends '_base_list.html' %} +{% load i18n %} +{% load static %} +{% block content_left_head %} + + +{% endblock %} + + +{% block table_search %} +
      +
      +
      + + + to + +
      +
      +
      + +
      +
      + +
      +
      + +
      +
      + +
      +
      +
      + +
      +
      +
      +{% endblock %} + +{% block table_head %} + + {% trans 'ID' %} + {% trans 'User' %} + {% trans 'Asset' %} + {% trans 'System user' %} + {% trans 'Terminal' %} + {% trans 'Command' %} + {% trans 'Success' %} + {% trans 'Finished' %} + {% trans 'Play' %} + {% trans 'Date start' %} + {% trans 'Time' %} +{% endblock %} + +{% block table_body %} + {% for proxy_log in proxy_log_list %} + + + + {{ proxy_log.id }} + + {{ proxy_log.user }} + {{ proxy_log.asset }} + {{ proxy_log.system_user }} + {{ proxy_log.terminal }} + {{ proxy_log.commands.all|length}} + + {% if proxy_log.is_failed %} + + {% else %} + + {% endif %} + + {% if proxy_log.is_finished %} + + + + + + + {% else %} + + + + + + + {% endif %} + {{ proxy_log.date_start }} + {{ proxy_log.date_finished|timeuntil:proxy_log.date_start }} + + {% endfor %} +{% endblock %} + + +{% block custom_foot_js %} + + +{% endblock %} + diff --git a/apps/terminal/templates/terminal/session_online.html b/apps/terminal/templates/terminal/session_online.html new file mode 100644 index 000000000..e190a92ad --- /dev/null +++ b/apps/terminal/templates/terminal/session_online.html @@ -0,0 +1,173 @@ +{% extends '_base_list.html' %} +{% load i18n %} +{% load static %} +{% block content_left_head %} + + +{% endblock %} + + +{% block table_search %} +
      +
      +
      + + + to + +
      +
      +
      + +
      +
      + +
      +
      + +
      +
      + +
      +
      +
      + +
      +
      +
      +{% endblock %} + +{% block table_head %} + + {% trans 'ID' %} + {% trans 'User' %} + {% trans 'Asset' %} + {% trans 'System user' %} + {% trans 'Terminal' %} + {% trans 'Command' %} + {% trans 'Success' %} + {% trans 'Finished' %} + {% trans 'Monitor' %} + {% trans 'Date start' %} + {% trans 'Time' %} +{% endblock %} + +{% block table_body %} + {% for session in session_list %} + + + + {{ session.id }} + + {{ session.user }} + {{ session.asset }} + {{ session.system_user }} + {{ session.terminal.name }} + {{ session.commands.all|length}} + + {% if session.is_failed %} + + {% else %} + + {% endif %} + + {% if session.is_finished %} + + + + + + + {% else %} + + + + + + + {% endif %} + {{ session.date_start }} + {{ session.date_finished|timeuntil:session.date_start }} + + {% endfor %} +{% endblock %} + +{% block content_bottom_left %} +
      +
      + +
      + +
      +
      +
      +{% endblock %} + +{% block custom_foot_js %} + + +{% endblock %} + diff --git a/apps/terminal/urls/views_urls.py b/apps/terminal/urls/views_urls.py index 8792f55aa..373385e28 100644 --- a/apps/terminal/urls/views_urls.py +++ b/apps/terminal/urls/views_urls.py @@ -9,13 +9,14 @@ from .. import views app_name = 'terminal' urlpatterns = [ + # Terminal view url(r'^terminal/$', views.TerminalListView.as_view(), name='terminal-list'), - url(r'^terminal/(?P[0-9a-zA-Z\-]+)/$', views.TerminalDetailView.as_view(), - name='terminal-detail'), - url(r'^terminal/(?P[0-9a-zA-Z\-]+)/connect/$', views.TerminalConnectView.as_view(), - name='terminal-connect'), - url(r'^terminal/(?P[0-9a-zA-Z\-]+)/update/$', views.TerminalUpdateView.as_view(), - name='terminal-update'), - url(r'^(?P[0-9a-zA-Z\-]+)/accept/$', views.TerminalAccept.as_view(), - name='terminal-accept'), + url(r'^terminal/(?P[0-9a-zA-Z\-]+)/$', views.TerminalDetailView.as_view(), name='terminal-detail'), + url(r'^terminal/(?P[0-9a-zA-Z\-]+)/connect/$', views.TerminalConnectView.as_view(), name='terminal-connect'), + url(r'^terminal/(?P[0-9a-zA-Z\-]+)/update/$', views.TerminalUpdateView.as_view(), name='terminal-update'), + url(r'^(?P[0-9a-zA-Z\-]+)/accept/$', views.TerminalAcceptView.as_view(), name='terminal-accept'), + + # 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'), ] diff --git a/apps/terminal/views/__init__.py b/apps/terminal/views/__init__.py new file mode 100644 index 000000000..69525d808 --- /dev/null +++ b/apps/terminal/views/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# +from .terminal import * +from .session import * diff --git a/apps/terminal/views/session.py b/apps/terminal/views/session.py new file mode 100644 index 000000000..b809a3be2 --- /dev/null +++ b/apps/terminal/views/session.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# + +import time +from datetime import datetime + +from django.views.generic import ListView, UpdateView, DeleteView, DetailView, TemplateView +from django.views.generic.edit import SingleObjectMixin +from django.utils.translation import ugettext as _ +from django.utils import timezone +from django.utils.module_loading import import_string +from django.urls import reverse_lazy +from django.http import HttpResponse +from django.conf import settings +from django.db.models import Q + +from users.utils import AdminUserRequiredMixin +from ..models import Session, Command, Terminal +from ..backends import get_command_store + + +__all__ = [ + 'SessionOnlineListView', 'SessionOfflineListView', +] + + +class SessionListView(AdminUserRequiredMixin, ListView): + model = Session + template_name = 'terminal/session_online.html' + context_object_name = 'session_list' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + keyword = username = hostname = system_user = date_from_s = date_to_s = '' + ordering = ['is_finished', '-id'] + date_format = '%m/%d/%Y' + + def get_queryset(self): + date_now = timezone.localtime(timezone.now()) + date_to_default = date_now.strftime(self.date_format) + date_from_default = (date_now-timezone.timedelta(7)).strftime(self.date_format) + + self.queryset = super().get_queryset() + self.keyword = self.request.GET.get('keyword', '') + self.username = self.request.GET.get('username') + self.ip = self.request.GET.get('ip') + self.system_user = self.request.GET.get('system_user') + self.date_from_s = self.request.GET.get('date_from', date_from_default) + self.date_to_s = self.request.GET.get('date_to', date_to_default) + + filter_kwargs = {} + if self.date_from_s: + date_from = datetime.strptime(self.date_from_s, self.date_format) + date_from = date_from.replace(tzinfo=timezone.get_current_timezone()) + filter_kwargs['date_start__gt'] = date_from + if self.date_to_s: + date_to = timezone.datetime.strptime( + self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S') + date_to = date_to.replace(tzinfo=timezone.get_current_timezone()) + filter_kwargs['date_start__lt'] = date_to + if self.username: + filter_kwargs['user'] = self.username + if self.ip: + filter_kwargs['asset'] = self.ip + if self.system_user: + filter_kwargs['system_user'] = self.system_user + if self.keyword: + self.queryset = self.queryset.filter( + Q(user__icontains=self.keyword) | + Q(asset__icontains=self.keyword) | + Q(system_user__icontains=self.keyword)).distinct() + if filter_kwargs: + self.queryset = self.queryset.filter(**filter_kwargs) + return self.queryset + + def get_context_data(self, **kwargs): + context = { + 'app': _('Audits'), + 'action': _('Proxy log list'), + 'user_list': set( + list(Session.objects.values_list('user', flat=True))), + 'asset_list': set( + list(Session.objects.values_list('asset', flat=True))), + 'system_user_list': set( + list(Session.objects.values_list('system_user', flat=True))), + 'keyword': self.keyword, + 'date_from': self.date_from_s, + 'date_to': self.date_to_s, + 'username': self.username, + 'ip': self.ip, + 'system_user': self.system_user, + } + kwargs.update(context) + return super().get_context_data(**kwargs) + + +class SessionOnlineListView(SessionListView): + template_name = 'terminal/session_online.html' + + def get_queryset(self): + queryset = super().get_queryset().filter(is_finished=False) + return queryset + + def get_context_data(self, **kwargs): + context = { + 'action': _('Session online list'), + } + kwargs.update(context) + return super().get_context_data(**kwargs) + + +class SessionOfflineListView(SessionListView): + template_name = 'terminal/session_offline.html' + + def get_queryset(self): + queryset = super().get_queryset() + queryset = queryset.filter(is_finished=True) + return queryset + + def get_context_data(self, **kwargs): + context = { + 'action': _('Session offline list'), + } + kwargs.update(context) + return super().get_context_data(**kwargs) + + + diff --git a/apps/terminal/views.py b/apps/terminal/views/terminal.py similarity index 90% rename from apps/terminal/views.py rename to apps/terminal/views/terminal.py index 357521d1b..673851f94 100644 --- a/apps/terminal/views.py +++ b/apps/terminal/views/terminal.py @@ -8,9 +8,15 @@ from django.utils.translation import ugettext as _ from django.urls import reverse_lazy, reverse from common.mixins import JSONResponseMixin -from .models import Terminal -from .forms import TerminalForm -from .hands import AdminUserRequiredMixin +from ..models import Terminal +from ..forms import TerminalForm +from ..hands import AdminUserRequiredMixin + + +__all__ = [ + "TerminalListView", "TerminalUpdateView", "TerminalDetailView", + "TerminalDeleteView", "TerminalConnectView", "TerminalAcceptView", +] class TerminalListView(LoginRequiredMixin, ListView): @@ -60,7 +66,7 @@ class TerminalDeleteView(AdminUserRequiredMixin, DeleteView): success_url = reverse_lazy('terminal:terminal-list') -class TerminalAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView): +class TerminalAcceptView(AdminUserRequiredMixin, JSONResponseMixin, UpdateView): model = Terminal form_class = TerminalForm template_name = 'Terminal/terminal_modal_test.html'