From 71a30792212cffba2bd0a6487e63834926ee69d7 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 4 Dec 2017 16:41:00 +0800 Subject: [PATCH] =?UTF-8?q?[Feature]=20=E7=A6=BB=E7=BA=BFsession=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/templates/_nav.html | 5 +- apps/templates/_nav_user.html | 4 +- apps/terminal/api.py | 2 +- apps/terminal/models.py | 3 +- apps/terminal/tasks.py | 42 +++++ .../templates/terminal/command_list.html | 18 +- .../templates/terminal/session_detail.html | 69 +++++++- ...{session_online.html => session_list.html} | 60 +++---- .../templates/terminal/session_offline.html | 159 ------------------ .../templates/terminal/terminal_detail.html | 10 +- apps/terminal/templatetags/terminal_tags.py | 1 - apps/terminal/urls/views_urls.py | 8 +- apps/terminal/utils.py | 20 +++ apps/terminal/views/__init__.py | 1 + apps/terminal/views/command.py | 84 +++++++++ apps/terminal/views/session.py | 53 +++--- 16 files changed, 282 insertions(+), 257 deletions(-) rename apps/terminal/templates/terminal/{session_online.html => session_list.html} (71%) delete mode 100644 apps/terminal/templates/terminal/session_offline.html create mode 100644 apps/terminal/utils.py create mode 100644 apps/terminal/views/command.py diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html index 9558bb48d..d4f4311ad 100644 --- a/apps/templates/_nav.html +++ b/apps/templates/_nav.html @@ -41,8 +41,9 @@ diff --git a/apps/templates/_nav_user.html b/apps/templates/_nav_user.html index 296d8bc89..323d18f76 100644 --- a/apps/templates/_nav_user.html +++ b/apps/templates/_nav_user.html @@ -9,8 +9,8 @@ {% trans 'Profile' %} -
  • - +
  • + {% trans 'Terminal' %}
  • diff --git a/apps/terminal/api.py b/apps/terminal/api.py index a0b930d4b..681dca4c1 100644 --- a/apps/terminal/api.py +++ b/apps/terminal/api.py @@ -219,7 +219,7 @@ class CommandViewSet(viewsets.ViewSet): if ok: return Response("ok", status=201) else: - return Response("save error", status=500) + return Response("Save error", status=500) else: return Response({"msg": "Not valid: {}".format(serializer.errors)}, status=401) diff --git a/apps/terminal/models.py b/apps/terminal/models.py index fa6f219ac..c4e80da78 100644 --- a/apps/terminal/models.py +++ b/apps/terminal/models.py @@ -100,6 +100,7 @@ class Session(models.Model): class Meta: db_table = "terminal_session" + ordering = ["-date_start"] def __str__(self): return "{0.id} of {0.user} to {0.asset}".format(self) @@ -126,4 +127,4 @@ class Command(AbstractSessionCommand): class Meta: db_table = "terminal_command" - ordering = ('timestamp',) + ordering = ('-timestamp',) diff --git a/apps/terminal/tasks.py b/apps/terminal/tasks.py index 8d85f7e4d..4bcfae396 100644 --- a/apps/terminal/tasks.py +++ b/apps/terminal/tasks.py @@ -1,10 +1,52 @@ # -*- coding: utf-8 -*- # +import threading +import time from celery import shared_task +from django.core.cache import cache + +from .models import Session + + +ASSETS_CACHE_KEY = "terminal__session__assets" +USERS_CACHE_KEY = "terminal__session__users" +SYSTEM_USER_CACHE_KEY = "terminal__session__system_users" +CACHE_REFRESH_INTERVAL = 10 # Todo: 定期清理上报history @shared_task def clean_terminal_history(): pass + + +def get_session_asset_list(): + return set(list(Session.objects.values_list('asset', flat=True))) + + +def get_session_user_list(): + return set(list(Session.objects.values_list('user', flat=True))) + + +def get_session_system_user_list(): + return set(list(Session.objects.values_list('system_user', flat=True))) + + +def set_cache(): + while True: + assets = get_session_asset_list() + users = get_session_user_list() + system_users = get_session_system_user_list() + + cache.set(ASSETS_CACHE_KEY, assets) + cache.set(USERS_CACHE_KEY, users) + cache.set(SYSTEM_USER_CACHE_KEY, system_users) + time.sleep(10) + + +def main(): + thread = threading.Thread(target=set_cache) + thread.start() + +main() diff --git a/apps/terminal/templates/terminal/command_list.html b/apps/terminal/templates/terminal/command_list.html index 04bb976fb..df70fe78e 100644 --- a/apps/terminal/templates/terminal/command_list.html +++ b/apps/terminal/templates/terminal/command_list.html @@ -26,7 +26,7 @@ @@ -34,7 +34,7 @@ @@ -42,7 +42,7 @@ @@ -67,22 +67,22 @@ Username IP System user - Proxy log + Session Datetime - Output + {% for command in command_list %} - {{ command.id }} - {{ command.command }} + {{ forloop.counter }} + {{ command.input }} {{ command.user }} {{ command.asset }} {{ command.system_user }} - {{ command.proxy_log_id}} + {% trans "Goto" %} {{ command.timestamp|ts_to_date }} -
    {{ command.output|to_html|safe }}
    +
    {{ command.output }}
    {% endfor %} diff --git a/apps/terminal/templates/terminal/session_detail.html b/apps/terminal/templates/terminal/session_detail.html index 116ac3c9b..6ff576d6e 100644 --- a/apps/terminal/templates/terminal/session_detail.html +++ b/apps/terminal/templates/terminal/session_detail.html @@ -14,12 +14,15 @@
    -
    +
    {% trans 'Command list' %} @@ -72,6 +75,46 @@
    +
    +
    +
    + {% trans 'Quick modify' %} +
    +
    + + + {% if object.is_finished %} + + + + + {% else %} + + + + + + + + + {% endif %} + +
    {% trans 'Replay session' %}: + + + +
    {% trans 'Monitor session' %}: + + + +
    {% trans 'Terminate session' %}: + + + +
    +
    +
    +
    @@ -82,8 +125,28 @@ {% block custom_foot_js %} {% endblock %} diff --git a/apps/terminal/templates/terminal/session_online.html b/apps/terminal/templates/terminal/session_list.html similarity index 71% rename from apps/terminal/templates/terminal/session_online.html rename to apps/terminal/templates/terminal/session_list.html index d0e533ba5..ce0640b57 100644 --- a/apps/terminal/templates/terminal/session_online.html +++ b/apps/terminal/templates/terminal/session_list.html @@ -23,18 +23,18 @@
    - {% for u in user_list %} - + {% endfor %}
    - {% for a in asset_list %} - + {% endfor %}
    @@ -46,9 +46,9 @@ {% endfor %} -
    - -
    +{#
    #} +{# #} +{#
    #}
    -
    -
    - -{% endblock %} - {% block custom_foot_js %} - -{% endblock %} - diff --git a/apps/terminal/templates/terminal/terminal_detail.html b/apps/terminal/templates/terminal/terminal_detail.html index e1847b645..d9e615f1b 100644 --- a/apps/terminal/templates/terminal/terminal_detail.html +++ b/apps/terminal/templates/terminal/terminal_detail.html @@ -13,7 +13,7 @@ {% trans 'Terminal detail' %}
  • - Update + Update
  • @@ -48,12 +48,12 @@ {{ terminal.remote_addr }} - {% trans 'URL to login' %}: - {{ terminal.url }} + {% trans 'SSH port' %}: + {{ terminal.ssh_port }} - {% trans 'Terminal type' %}: - {{ terminal.get_type_display }} + {% trans 'Http port' %}: + {{ terminal.http_port }} {% trans 'Date created' %}: diff --git a/apps/terminal/templatetags/terminal_tags.py b/apps/terminal/templatetags/terminal_tags.py index 4d3896a58..22b517880 100644 --- a/apps/terminal/templatetags/terminal_tags.py +++ b/apps/terminal/templatetags/terminal_tags.py @@ -9,6 +9,5 @@ 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))) diff --git a/apps/terminal/urls/views_urls.py b/apps/terminal/urls/views_urls.py index 6f472196e..9de230506 100644 --- a/apps/terminal/urls/views_urls.py +++ b/apps/terminal/urls/views_urls.py @@ -17,7 +17,11 @@ urlpatterns = [ 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'), + 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[0-9a-zA-Z\-]+)/$', views.SessionDetailView.as_view(), name='session-detail'), + + # Command view + url(r'^command/$', views.CommandListView.as_view(), name='command-list'), + ] diff --git a/apps/terminal/utils.py b/apps/terminal/utils.py new file mode 100644 index 000000000..c24571c77 --- /dev/null +++ b/apps/terminal/utils.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +from django.core.cache import cache + +from .tasks import USERS_CACHE_KEY, ASSETS_CACHE_KEY, SYSTEM_USER_CACHE_KEY + + +def get_user_list_from_cache(): + return cache.get(USERS_CACHE_KEY) + + +def get_asset_list_from_cache(): + return cache.get(ASSETS_CACHE_KEY) + + +def get_system_user_list_from_cache(): + return cache.get(SYSTEM_USER_CACHE_KEY) + + + diff --git a/apps/terminal/views/__init__.py b/apps/terminal/views/__init__.py index 69525d808..8267a40bc 100644 --- a/apps/terminal/views/__init__.py +++ b/apps/terminal/views/__init__.py @@ -2,3 +2,4 @@ # from .terminal import * from .session import * +from .command import * diff --git a/apps/terminal/views/command.py b/apps/terminal/views/command.py new file mode 100644 index 000000000..54f301214 --- /dev/null +++ b/apps/terminal/views/command.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# +from datetime import datetime + +from django.views.generic import ListView +from django.conf import settings +from django.utils import timezone +from django.utils.translation import ugettext as _ + +from ..models import Command +from .. import utils +from ..backends import get_command_store + +__all__ = ['CommandListView'] +command_store = get_command_store() + + +class CommandListView(ListView): + model = Command + template_name = "terminal/command_list.html" + context_object_name = 'command_list' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + command = user = asset = system_user = date_from_s = date_to_s = '' + date_format = '%m/%d/%Y' + + def get_queryset(self): + date_to_default = timezone.now() + date_from_default = timezone.now() - timezone.timedelta(7) + date_to_default_s = date_to_default.strftime(self.date_format) + date_from_default_s = date_from_default.strftime(self.date_format) + + 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') + self.date_from_s = self.request.GET.get('date_from', date_from_default_s) + self.date_to_s = self.request.GET.get('date_to', date_to_default_s) + + 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_from'] = 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_to'] = 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 + if filter_kwargs: + self.queryset = command_store.filter(**filter_kwargs) + return self.queryset + + def get_context_data(self, **kwargs): + context = { + 'app': _('Terminal'), + 'action': _('Command list'), + 'user_list': utils.get_user_list_from_cache(), + 'asset_list': utils.get_asset_list_from_cache(), + 'system_user_list': utils.get_system_user_list_from_cache(), + 'command': self.command, + 'date_from': self.date_from_s, + 'date_to': self.date_to_s, + 'user': self.user, + 'asset': self.asset, + 'system_user': self.system_user, + } + kwargs.update(context) + return super().get_context_data(**kwargs) + + + + + + diff --git a/apps/terminal/views/session.py b/apps/terminal/views/session.py index 9e4c24fd8..658742ad2 100644 --- a/apps/terminal/views/session.py +++ b/apps/terminal/views/session.py @@ -17,6 +17,7 @@ from django.db.models import Q from users.utils import AdminUserRequiredMixin from ..models import Session, Command, Terminal from ..backends import get_command_store +from .. import utils __all__ = [ @@ -29,25 +30,24 @@ command_store = get_command_store() class SessionListView(AdminUserRequiredMixin, ListView): model = Session - template_name = 'terminal/session_online.html' + template_name = 'terminal/session_list.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'] + user = asset = system_user = date_from_s = date_to_s = '' 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) + date_to_default = timezone.now() + date_from_default = timezone.now() - timezone.timedelta(7) + date_to_default_s = date_to_default.strftime(self.date_format) + date_from_default_s = date_from_default.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.user = self.request.GET.get('user') + self.asset = self.request.GET.get('asset') 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) + self.date_from_s = self.request.GET.get('date_from', date_from_default_s) + self.date_to_s = self.request.GET.get('date_to', date_to_default_s) filter_kwargs = {} if self.date_from_s: @@ -59,17 +59,12 @@ class SessionListView(AdminUserRequiredMixin, ListView): 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.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.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 @@ -78,17 +73,13 @@ class SessionListView(AdminUserRequiredMixin, ListView): 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, + 'user_list': utils.get_user_list_from_cache(), + 'asset_list': utils.get_asset_list_from_cache(), + 'system_user_list': utils.get_system_user_list_from_cache(), 'date_from': self.date_from_s, 'date_to': self.date_to_s, - 'username': self.username, - 'ip': self.ip, + 'user': self.user, + 'asset': self.asset, 'system_user': self.system_user, } kwargs.update(context) @@ -96,7 +87,6 @@ class SessionListView(AdminUserRequiredMixin, ListView): class SessionOnlineListView(SessionListView): - template_name = 'terminal/session_online.html' def get_queryset(self): queryset = super().get_queryset().filter(is_finished=False) @@ -106,13 +96,13 @@ class SessionOnlineListView(SessionListView): context = { 'app': _('Terminal'), 'action': _('Session online list'), + 'now': timezone.now(), } 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() @@ -123,6 +113,7 @@ class SessionOfflineListView(SessionListView): context = { 'app': _('Terminal'), 'action': _('Session offline list'), + 'now': timezone.now(), } kwargs.update(context) return super().get_context_data(**kwargs)