diff --git a/apps/audits/__init__.py b/apps/audits/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/apps/audits/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/audits/api.py b/apps/audits/api.py
deleted file mode 100644
index d8a7b21de..000000000
--- a/apps/audits/api.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-#
-
-
-from __future__ import absolute_import, unicode_literals
-
-from rest_framework import generics, viewsets
-from rest_framework_bulk import BulkModelViewSet
-
-from audits.backends import command_store, record_store
-from audits.backends.command.serializers import CommandLogSerializer
-from audits.backends.record.serializers import RecordSerializer
-from . import models, serializers
-from .hands import IsSuperUserOrAppUser, IsAppUser
-
-
-class ProxyLogReceiveView(generics.CreateAPIView):
- queryset = models.ProxyLog.objects.all()
- serializer_class = serializers.ProxyLogSerializer
- permission_classes = (IsAppUser,)
-
- def get_serializer(self, *args, **kwargs):
- kwargs['data']['terminal'] = self.request.user.terminal.name
- return super(ProxyLogReceiveView, self).get_serializer(*args, **kwargs)
-
-
-class ProxyLogViewSet(viewsets.ModelViewSet):
- """User proxy to backend server need call this api.
-
- params: {
- "username": "",
- "name": "",
- "hostname": "",
- "ip": "",
- "terminal": "",
- "login_type": "",
- "system_user": "",
- "was_failed": "",
- "date_start": ""
- }
-
- """
-
- queryset = models.ProxyLog.objects.all()
- serializer_class = serializers.ProxyLogSerializer
- permission_classes = (IsSuperUserOrAppUser,)
-
-
-class CommandLogViewSet(BulkModelViewSet):
- """接受app发送来的command log, 格式如下
- {
- "proxy_log_id": 23,
- "user": "admin",
- "asset": "localhost",
- "system_user": "web",
- "command_no": 1,
- "command": "whoami",
- "output": "d2hvbWFp", # base64.b64encode(s)
- "timestamp": 1485238673.0
- }
-
- """
- queryset = command_store.all()
- serializer_class = CommandLogSerializer
- permission_classes = (IsSuperUserOrAppUser,)
-
-
-class RecordLogViewSet(BulkModelViewSet):
- """接受app发送来的record log, 格式如下
- {
- "proxy_log_id": 23,
- "output": "d2hvbWFp", # base64.b64encode(s)
- "timestamp": 1485238673.0
- }
- """
-
- serializer_class = RecordSerializer
- permission_classes = (IsSuperUserOrAppUser,)
-
- def get_queryset(self):
- filter_kwargs = {}
- proxy_log_id = self.request.query_params.get('proxy_log_id')
- data_from_ts = self.request.query_params.get('date_from_ts')
- if proxy_log_id:
- filter_kwargs['proxy_log_id'] = proxy_log_id
- if data_from_ts:
- filter_kwargs['date_from_ts'] = data_from_ts
- if filter_kwargs:
- return record_store.filter(**filter_kwargs)
- else:
- return record_store.all()
-
diff --git a/apps/audits/apps.py b/apps/audits/apps.py
deleted file mode 100644
index d376c1e65..000000000
--- a/apps/audits/apps.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from __future__ import unicode_literals
-
-from django.apps import AppConfig
-
-
-class AuditsConfig(AppConfig):
- name = 'audits'
diff --git a/apps/audits/backends/__init__.py b/apps/audits/backends/__init__.py
deleted file mode 100644
index 5a2a38ec7..000000000
--- a/apps/audits/backends/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from importlib import import_module
-from django.conf import settings
-
-command_engine = import_module(settings.COMMAND_STORE_BACKEND)
-command_store = command_engine.CommandStore()
-record_engine = import_module(settings.RECORD_STORE_BACKEND)
-record_store = record_engine.RecordStore()
-from .command.serializers import CommandLogSerializer
-
-
diff --git a/apps/audits/backends/command/__init__.py b/apps/audits/backends/command/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/apps/audits/backends/command/base.py b/apps/audits/backends/command/base.py
deleted file mode 100644
index 54279f133..000000000
--- a/apps/audits/backends/command/base.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# coding: utf-8
-import abc
-
-
-class CommandBase(object):
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def save(self, proxy_log_id, user, asset, system_user,
- command_no, command, output, timestamp):
- pass
-
- @abc.abstractmethod
- def filter(self, date_from_ts=None, date_to_ts=None, user='',
- asset='', system_user='', command='', proxy_log_id=0):
- pass
-
-
-
diff --git a/apps/audits/backends/command/db.py b/apps/audits/backends/command/db.py
deleted file mode 100644
index 26441e41f..000000000
--- a/apps/audits/backends/command/db.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-
-from .base import CommandBase
-from audits.models import CommandLog
-
-
-class CommandStore(CommandBase):
- model = CommandLog
- queryset = []
-
- def save(self, proxy_log_id, user, asset, system_user,
- command_no, command, output, timestamp):
- self.model.objects.create(
- proxy_log_id=proxy_log_id, user=user, asset=asset,
- system_user=system_user, command_no=command_no,
- command=command, output=output, timestamp=timestamp
- )
-
- def filter(self, date_from_ts=None, date_to_ts=None, user='',
- asset='', system_user='', command='', proxy_log_id=0):
- filter_kwargs = {}
-
- if date_from_ts:
- filter_kwargs['timestamp__gte'] = date_from_ts
- if date_to_ts:
- filter_kwargs['timestamp__lte'] = date_to_ts
- if user:
- filter_kwargs['user'] = user
- if asset:
- filter_kwargs['asset'] = asset
- if system_user:
- filter_kwargs['system_user'] = system_user
- if command:
- filter_kwargs['command__icontains'] = command
- if proxy_log_id:
- filter_kwargs['proxy_log_id'] = proxy_log_id
-
- if filter_kwargs:
- self.queryset = self.model.objects.filter(**filter_kwargs)
- return self.queryset
-
- def all(self):
- """返回所有数据"""
- return self.model.objects.iterator()
-
diff --git a/apps/audits/backends/command/serializers.py b/apps/audits/backends/command/serializers.py
deleted file mode 100644
index 32da6bcea..000000000
--- a/apps/audits/backends/command/serializers.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-import base64
-from rest_framework import serializers
-from audits.models import CommandLog
-from audits.backends import command_store
-
-
-class CommandLogSerializer(serializers.ModelSerializer):
- """使用这个类作为基础Command Log Serializer类, 用来序列化"""
-
- class Meta:
- model = CommandLog
- fields = '__all__'
-
- def create(self, validated_data):
- try:
- output = validated_data['output']
- validated_data['output'] = base64.b64decode(output)
- except IndexError:
- pass
- return command_store.save(**dict(validated_data))
diff --git a/apps/audits/backends/record/__init__.py b/apps/audits/backends/record/__init__.py
deleted file mode 100644
index 3e0d2fd0f..000000000
--- a/apps/audits/backends/record/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-
diff --git a/apps/audits/backends/record/base.py b/apps/audits/backends/record/base.py
deleted file mode 100644
index e96b8b131..000000000
--- a/apps/audits/backends/record/base.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# coding: utf-8
-import abc
-
-
-class RecordBase(object):
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def save(self, proxy_log_id, output, timestamp):
- pass
-
- @abc.abstractmethod
- def filter(self, date_from_ts=None, proxy_log_id=None):
- pass
diff --git a/apps/audits/backends/record/db.py b/apps/audits/backends/record/db.py
deleted file mode 100644
index e55211f65..000000000
--- a/apps/audits/backends/record/db.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-
-from .base import RecordBase
-from audits.models import RecordLog
-
-
-class RecordStore(RecordBase):
- model = RecordLog
- queryset = []
-
- def save(self, proxy_log_id, output, timestamp):
- return self.model.objects.create(
- proxy_log_id=proxy_log_id, output=output, timestamp=timestamp
- )
-
- def filter(self, date_from_ts=None, proxy_log_id=''):
- filter_kwargs = {}
-
- if date_from_ts:
- filter_kwargs['timestamp__gte'] = date_from_ts
- if proxy_log_id:
- filter_kwargs['proxy_log_id'] = proxy_log_id
-
- if filter_kwargs:
- self.queryset = self.model.objects.filter(**filter_kwargs)
- return self.queryset
-
- def all(self):
- """返回所有数据"""
- return self.model.objects.all()
-
diff --git a/apps/audits/backends/record/serializers.py b/apps/audits/backends/record/serializers.py
deleted file mode 100644
index 30a5867e1..000000000
--- a/apps/audits/backends/record/serializers.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-import base64
-from rest_framework import serializers
-from audits.models import RecordLog
-from audits.backends import record_store
-
-
-class RecordSerializer(serializers.ModelSerializer):
- """使用这个类作为基础Command Log Serializer类, 用来序列化"""
- class Meta:
- model = RecordLog
- fields = '__all__'
-
- def create(self, validated_data):
- try:
- output = validated_data['output']
- validated_data['output'] = base64.b64decode(output)
- except IndexError:
- pass
- return record_store.save(**dict(validated_data))
diff --git a/apps/audits/hands.py b/apps/audits/hands.py
deleted file mode 100644
index 11ba2e765..000000000
--- a/apps/audits/hands.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-#
-
-from users.utils import AdminUserRequiredMixin
-from users.models import User
-from assets.models import Asset, SystemUser
-from users.permissions import IsSuperUserOrAppUser, IsAppUser
-from terminal.models import Terminal
diff --git a/apps/audits/migrations/__init__.py b/apps/audits/migrations/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/apps/audits/models.py b/apps/audits/models.py
deleted file mode 100644
index 6d03b0231..000000000
--- a/apps/audits/models.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-
-from __future__ import unicode_literals
-
-import uuid
-
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-
-class LoginLog(models.Model):
- LOGIN_TYPE_CHOICE = (
- ('W', 'Web'),
- ('ST', 'SSH Terminal'),
- ('WT', 'Web Terminal')
- )
- id = models.UUIDField(default=uuid.uuid4, primary_key=True)
- username = models.CharField(max_length=20, verbose_name=_('Username'))
- name = models.CharField(max_length=20, blank=True, verbose_name=_('Name'))
- login_type = models.CharField(choices=LOGIN_TYPE_CHOICE, max_length=2,
- verbose_name=_('Login type'))
- login_ip = models.GenericIPAddressField(verbose_name=_('Login ip'))
- login_city = models.CharField(max_length=254, blank=True, null=True,
- verbose_name=_('Login city'))
- user_agent = models.CharField(max_length=254, blank=True, null=True,
- verbose_name=_('User agent'))
- date_login = models.DateTimeField(auto_now_add=True,
- verbose_name=_('Date login'))
-
- class Meta:
- db_table = 'login_log'
- ordering = ['-date_login', 'username']
-
-
-class ProxyLog(models.Model):
- LOGIN_TYPE_CHOICE = (
- ('ST', 'SSH Terminal'),
- ('WT', 'Web Terminal'),
- )
-
- id = models.UUIDField(default=uuid.uuid4, primary_key=True)
- user = models.CharField(max_length=32, verbose_name=_('User'))
- asset = models.CharField(max_length=32, verbose_name=_('Asset'))
- system_user = models.CharField(max_length=32, verbose_name=_('System user'))
- login_type = models.CharField(
- choices=LOGIN_TYPE_CHOICE, max_length=2, blank=True,
- null=True, verbose_name=_('Login type'))
- terminal = models.CharField(
- max_length=32, blank=True, null=True, verbose_name=_('Terminal'))
- is_failed = models.BooleanField(
- default=False, verbose_name=_('Did connect failed'))
- is_finished = models.BooleanField(
- default=False, verbose_name=_('Is finished'))
- date_start = models.DateTimeField(
- auto_created=True, verbose_name=_('Date start'))
- date_finished = models.DateTimeField(
- null=True, verbose_name=_('Date finished'))
-
- def __unicode__(self):
- return '%s-%s-%s' % (self.user, self.asset, self.system_user)
-
- def commands(self):
- from audits.backends import command_store
- return command_store.filter(proxy_log_id=self.id)
-
- class Meta:
- ordering = ['-date_start', 'user']
-
-
-class CommandLog(models.Model):
- id = models.UUIDField(default=uuid.uuid4, primary_key=True)
- proxy_log_id = models.IntegerField(db_index=True)
- user = models.CharField(max_length=48, db_index=True)
- asset = models.CharField(max_length=128, db_index=True)
- system_user = models.CharField(max_length=48, db_index=True)
- command_no = models.IntegerField()
- command = models.TextField(max_length=767, blank=True)
- output = models.TextField(blank=True)
- timestamp = models.FloatField(db_index=True)
-
- def __unicode__(self):
- return '%s: %s' % (self.id, self.command)
-
- class Meta:
- ordering = ['command_no', 'command']
-
-
-class RecordLog(models.Model):
- id = models.UUIDField(default=uuid.uuid4, primary_key=True)
- proxy_log_id = models.IntegerField(db_index=True)
- output = models.TextField(verbose_name=_('Output'))
- timestamp = models.FloatField(db_index=True)
-
- def __unicode__(self):
- return 'Record: %s' % self.proxy_log_id
-
- class Meta:
- ordering = ['timestamp']
diff --git a/apps/audits/serializers.py b/apps/audits/serializers.py
deleted file mode 100644
index 2f474ff7e..000000000
--- a/apps/audits/serializers.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-from __future__ import absolute_import, unicode_literals
-from rest_framework import serializers
-
-from common.utils import timesince
-from . import models
-
-
-class ProxyLogSerializer(serializers.ModelSerializer):
- time = serializers.SerializerMethodField()
- command_length = serializers.SerializerMethodField()
-
- class Meta:
- model = models.ProxyLog
- fields = '__all__'
-
- @staticmethod
- def get_time(obj):
- if not obj.is_finished:
- return ''
- else:
- return timesince(obj.date_start, since=obj.date_finished)
-
- @staticmethod
- def get_command_length(obj):
- return 2
-
diff --git a/apps/audits/templates/audits/command_log_list.html b/apps/audits/templates/audits/command_log_list.html
deleted file mode 100644
index 04bb976fb..000000000
--- a/apps/audits/templates/audits/command_log_list.html
+++ /dev/null
@@ -1,109 +0,0 @@
-{% extends '_base_list.html' %}
-{% load i18n %}
-{% load static %}
-{% load common_tags %}
-{% block content_left_head %}
-
-
-
-{% endblock %}
-
-{% block table_search %}
-
-{% endblock %}
-{% block table_container %}
-
-{% endblock %}
-
-{% block custom_foot_js %}
-
-
-
-{% endblock %}
-
-
diff --git a/apps/audits/templates/audits/login_log_list.html b/apps/audits/templates/audits/login_log_list.html
deleted file mode 100644
index eb7a4a813..000000000
--- a/apps/audits/templates/audits/login_log_list.html
+++ /dev/null
@@ -1,101 +0,0 @@
-{% extends '_base_list.html' %}
-{% load i18n %}
-{% load static %}
-{% load common_tags %}
-{% block content_left_head %}
-
-
-{% endblock %}
-
-
-{% block table_search %}
-
-{% endblock %}
-
-{% block table_head %}
- {% trans 'ID' %} |
- {% trans 'Username' %} |
- {% trans 'Name' %} |
- {% trans 'Type' %} |
- {% trans 'UA' %} |
- {% trans 'IP' %} |
- {% trans 'City' %} |
- {% trans 'Date' %} |
-{% endblock %}
-
-{% block table_body %}
- {% for login_log in login_log_list %}
-
-
- {{ login_log.id }}
-{# {{ login_log.id }}#}
- |
- {{ login_log.username }} |
- {{ login_log.name }} |
- {{ login_log.get_login_type_display }} |
- {% if login_log.login_type == 'W' %}
-
- {{ login_log.user_agent | truncatechars:20 }}
- |
- {% else %}
- {{ login_log.terminal }} |
- {% endif %}
- {{ login_log.login_ip }} |
- {{ login_log.login_city }} |
- {{ login_log.date_login }} |
-
- {% endfor %}
-{% endblock %}
-
-{% block custom_foot_js %}
-
-
-{% endblock %}
-
diff --git a/apps/audits/templates/audits/proxy_log_commands_list_modal.html b/apps/audits/templates/audits/proxy_log_commands_list_modal.html
deleted file mode 100644
index fca95de6e..000000000
--- a/apps/audits/templates/audits/proxy_log_commands_list_modal.html
+++ /dev/null
@@ -1,58 +0,0 @@
-{% load static %}
-
-
-
-
-
-
- {% include '_head_css_js.html' %}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/audits/templates/audits/proxy_log_detail.html b/apps/audits/templates/audits/proxy_log_detail.html
deleted file mode 100644
index 0fa28b517..000000000
--- a/apps/audits/templates/audits/proxy_log_detail.html
+++ /dev/null
@@ -1,85 +0,0 @@
-{% 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 }}
-
-
-
-
-
-
-
-
-
-
-
-{% endblock %}
-{% block custom_foot_js %}
-
-
-{% endblock %}
diff --git a/apps/audits/templates/audits/proxy_log_offline_list.html b/apps/audits/templates/audits/proxy_log_offline_list.html
deleted file mode 100644
index 7dcac94b7..000000000
--- a/apps/audits/templates/audits/proxy_log_offline_list.html
+++ /dev/null
@@ -1,159 +0,0 @@
-{% extends '_base_list.html' %}
-{% load i18n %}
-{% load static %}
-{% block content_left_head %}
-
-
-{% endblock %}
-
-
-{% block table_search %}
-
-{% 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/audits/templates/audits/proxy_log_online_list.html b/apps/audits/templates/audits/proxy_log_online_list.html
deleted file mode 100644
index 099ab3fca..000000000
--- a/apps/audits/templates/audits/proxy_log_online_list.html
+++ /dev/null
@@ -1,173 +0,0 @@
-{% extends '_base_list.html' %}
-{% load i18n %}
-{% load static %}
-{% block content_left_head %}
-
-
-{% endblock %}
-
-
-{% block table_search %}
-
-{% 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 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 content_bottom_left %}
-
-{% endblock %}
-
-{% block custom_foot_js %}
-
-
-{% endblock %}
-
diff --git a/apps/audits/templatetags/example_tags.py b/apps/audits/templatetags/example_tags.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/apps/audits/tests.py b/apps/audits/tests.py
deleted file mode 100644
index 7ce503c2d..000000000
--- a/apps/audits/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/apps/audits/urls/__init__.py b/apps/audits/urls/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/apps/audits/urls/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/audits/urls/api_urls.py b/apps/audits/urls/api_urls.py
deleted file mode 100644
index b9226d1b4..000000000
--- a/apps/audits/urls/api_urls.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from django.conf.urls import url
-from rest_framework import routers
-
-from .. import api
-
-app_name = 'audits'
-
-router = routers.DefaultRouter()
-router.register(r'v1/proxy-log', api.ProxyLogViewSet, 'proxy-log')
-router.register(r'v1/command-log', api.CommandLogViewSet, 'command-log')
-router.register(r'v1/replay-log', api.RecordLogViewSet, 'replay-log')
-
-urlpatterns = [
- url(r'^v1/proxy-log/receive/$', api.ProxyLogReceiveView.as_view(),
- name='proxy-log-receive'),
-]
-
-urlpatterns += router.urls
diff --git a/apps/audits/urls/views_urls.py b/apps/audits/urls/views_urls.py
deleted file mode 100644
index b36af1858..000000000
--- a/apps/audits/urls/views_urls.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from django.conf.urls import url
-from .. import views
-
-app_name = 'audits'
-
-urlpatterns = [
- url(r'^proxy-log-offline/$', views.ProxyLogOfflineListView.as_view(),
- name='proxy-log-offline-list'),
- url(r'^proxy-log-online/$', views.ProxyLogOnlineListView.as_view(),
- name='proxy-log-online-list'),
- url(r'^proxy-log/(?P[0-9a-zA-Z\-]+)/$', views.ProxyLogDetailView.as_view(),
- name='proxy-log-detail'),
- url(r'^command-log/$', views.CommandLogListView.as_view(),
- name='command-log-list'),
- url(r'^login-log/$', views.LoginLogListView.as_view(),
- name='login-log-list'),
-]
-
-
diff --git a/apps/audits/utils.py b/apps/audits/utils.py
deleted file mode 100644
index 4f57619d7..000000000
--- a/apps/audits/utils.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-#
-from __future__ import unicode_literals
-import requests
-import ipaddress
-
-from .models import LoginLog
-
-
-def validate_ip(ip):
- try:
- ipaddress.ip_address(ip)
- return True
- except ValueError:
- print('valid error')
- return False
-
-
-def write_login_log(username, name='', login_type='',
- login_ip='', user_agent=''):
- if not (login_ip and validate_ip(login_ip)):
- login_ip = '0.0.0.0'
- if not name:
- name = username
- login_city = get_ip_city(login_ip)
- LoginLog.objects.create(username=username, name=name, login_type=login_type,
- login_ip=login_ip, login_city=login_city, user_agent=user_agent)
-
-
-def get_ip_city(ip, timeout=10):
- # Taobao ip api: http://ip.taobao.com//service/getIpInfo.php?ip=8.8.8.8
- # Sina ip api: http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=8.8.8.8&format=json
-
- url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=%s&format=json' % ip
- try:
- r = requests.get(url, timeout=timeout)
- except requests.Timeout:
- r = None
- city = 'Unknown'
- if r and r.status_code == 200:
- try:
- data = r.json()
- if not isinstance(data, int) and data['ret'] == 1:
- city = data['country'] + ' ' + data['city']
- except ValueError:
- pass
- return city
-
-
diff --git a/apps/audits/views.py b/apps/audits/views.py
deleted file mode 100644
index 9767b54bd..000000000
--- a/apps/audits/views.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# ~*~ 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 .models import ProxyLog, CommandLog, LoginLog
-from .hands import User, Asset, SystemUser, AdminUserRequiredMixin
-from audits.backends import command_store
-from audits.backends import CommandLogSerializer
-
-
-class ProxyLogListView(AdminUserRequiredMixin, ListView):
- model = ProxyLog
- template_name = 'audits/proxy_log_online_list.html'
- context_object_name = 'proxy_log_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(ProxyLogListView, self).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(ProxyLog.objects.values_list('user', flat=True))),
- 'asset_list': set(
- list(ProxyLog.objects.values_list('asset', flat=True))),
- 'system_user_list': set(
- list(ProxyLog.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(ProxyLogListView, self).get_context_data(**kwargs)
-
-
-class ProxyLogOfflineListView(ProxyLogListView):
- template_name = 'audits/proxy_log_offline_list.html'
-
- def get_queryset(self):
- queryset = super(ProxyLogOfflineListView, self).get_queryset()
- queryset = queryset.filter(is_finished=True)
- return queryset
-
- def get_context_data(self, **kwargs):
- context = {
- 'action': _('Proxy log offline list'),
- }
- kwargs.update(context)
- return super(ProxyLogOfflineListView, self).get_context_data(**kwargs)
-
-
-class ProxyLogOnlineListView(ProxyLogListView):
- template_name = 'audits/proxy_log_online_list.html'
-
- def get_queryset(self):
- queryset = super(ProxyLogOnlineListView, self).get_queryset()
- queryset = queryset.filter(is_finished=False)
- return queryset
-
- def get_context_data(self, **kwargs):
- context = {
- 'action': _('Proxy log online list'),
- }
- kwargs.update(context)
- return super(ProxyLogOnlineListView, self).get_context_data(**kwargs)
-
-
-class ProxyLogDetailView(AdminUserRequiredMixin,
- SingleObjectMixin,
- ListView):
- template_name = 'audits/proxy_log_detail.html'
- context_object_name = 'proxy_log'
- object = ''
-
- def get(self, request, *args, **kwargs):
- self.object = self.get_object(queryset=ProxyLog.objects.all())
- return super(ProxyLogDetailView, self).get(request, *args, **kwargs)
-
- def get_queryset(self):
- return list(command_store.filter(proxy_log_id=self.object.id))
-
- def get_context_data(self, **kwargs):
- context = {
- 'app': 'Audits',
- 'action': 'Proxy log detail',
- }
- kwargs.update(context)
- return super(ProxyLogDetailView, self).get_context_data(**kwargs)
-
-
-# class ProxyLogCommandsListView(AdminUserRequiredMixin,
-# SingleObjectMixin,
-# ListView):
-# template_name = 'audits/proxy_log_commands_list_modal.html'
-# object = ''
-#
-# def get(self, request, *args, **kwargs):
-# self.object = self.get_object(queryset=ProxyLog.objects.all())
-# return super(ProxyLogCommandsListView, self).\
-# get(request, *args, **kwargs)
-#
-# def get_queryset(self):
-# return list(self.object.command_log.all())
-
-
-class CommandLogListView(AdminUserRequiredMixin, ListView):
- template_name = 'audits/command_log_list.html'
- paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
- context_object_name = 'command_list'
- username = ip = system_user = command = date_from_s = date_to_s = ''
- date_format = '%m/%d/%Y'
- ordering = ['-id']
-
- 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.command = self.request.GET.get('command', '')
- 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)\
- .replace(tzinfo=timezone.get_current_timezone())
- # date_from_utc = date_from.astimezone(pytz.utc)
- date_from_ts = time.mktime(date_from.timetuple())
- filter_kwargs['date_from_ts'] = date_from_ts
- if self.date_to_s:
- date_to = datetime.strptime(
- self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S')\
- .replace(tzinfo=timezone.get_current_timezone())
- date_to_ts = time.mktime(date_to.timetuple())
- filter_kwargs['date_to_ts'] = date_to_ts
- 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.command:
- filter_kwargs['command'] = self.command
- self.queryset = command_store.filter(**filter_kwargs).order_by(*self.ordering)
- return self.queryset
-
- def get_context_data(self, **kwargs):
- context = {
- 'app': _('Audits'),
- 'action': _('Command log list'),
- 'user_list': User.objects.all().order_by('username'),
- 'asset_list': Asset.objects.all().order_by('ip'),
- 'system_user_list': SystemUser.objects.all().order_by('username'),
- 'command': self.command,
- '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(CommandLogListView, self).get_context_data(**kwargs)
-
-
-class LoginLogListView(AdminUserRequiredMixin, ListView):
- model = LoginLog
- paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
- template_name = 'audits/login_log_list.html'
- context_object_name = 'login_log_list'
- keyword = username = date_from_s = date_to_s = ''
-
- def get_queryset(self):
- date_now = timezone.localtime(timezone.now())
- now_s = date_now.strftime('%m/%d/%Y')
- seven_days_ago_s = (date_now - timezone.timedelta(7))\
- .strftime('%m/%d/%Y')
- self.queryset = super(LoginLogListView, self).get_queryset()
- self.keyword = keyword = self.request.GET.get('keyword', '')
- self.username = username = self.request.GET.get('username', '')
- self.date_from_s = date_from_s = self.request.GET.get(
- 'date_from', '%s' % seven_days_ago_s)
- self.date_to_s = date_to_s = self.request.GET.get(
- 'date_to', '%s' % now_s)
-
- if date_from_s:
- date_from = timezone.datetime.strptime(date_from_s, '%m/%d/%Y')
- self.queryset = self.queryset.filter(date_login__gt=date_from)
- if date_to_s:
- date_to = timezone.datetime.strptime(
- date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S')
- self.queryset = self.queryset.filter(date_login__lt=date_to)
- if username:
- self.queryset = self.queryset.filter(username=username)
- if keyword:
- self.queryset = self.queryset.filter(
- Q(username__contains=keyword) |
- Q(name__icontains=keyword) |
- Q(login_ip=keyword)).distinct()
- return self.queryset
-
- def get_context_data(self, **kwargs):
- context = {
- 'app': _('Audits'),
- 'action': _('Proxy log list'),
- 'user_list': User.objects.all().order_by('username'),
- 'keyword': self.keyword,
- 'date_from': self.date_from_s,
- 'date_to': self.date_to_s,
- 'username': self.username,
- }
- kwargs.update(context)
- return super(LoginLogListView, self).get_context_data(**kwargs)
diff --git a/apps/common/templatetags/common_tags.py b/apps/common/templatetags/common_tags.py
index ee6c4bdfb..12a30927d 100644
--- a/apps/common/templatetags/common_tags.py
+++ b/apps/common/templatetags/common_tags.py
@@ -3,7 +3,6 @@
from django import template
from django.utils import timezone
from django.utils.html import escape
-from audits.backends import command_store
register = template.Library()
@@ -70,6 +69,6 @@ def to_html(s):
return escape(s).replace('\n', '
')
-@register.filter
-def proxy_log_commands(log_id):
- return command_store.filter(proxy_log_id=log_id)
+# @register.filter
+# def proxy_log_commands(log_id):
+# return 1
diff --git a/apps/common/views.py b/apps/common/views.py
index 5663b8b19..4cee32ba7 100644
--- a/apps/common/views.py
+++ b/apps/common/views.py
@@ -1,4 +1,2 @@
from __future__ import absolute_import, unicode_literals
-from django.shortcuts import render
-from django.views.generic import TemplateView
diff --git a/apps/jumpserver/middleware.py b/apps/jumpserver/middleware.py
index 28e718d7d..f93edf73a 100644
--- a/apps/jumpserver/middleware.py
+++ b/apps/jumpserver/middleware.py
@@ -9,7 +9,7 @@ from django.shortcuts import HttpResponse
DEMO_MODE = os.environ.get("DEMO_MODE", "")
-SAFE_URL = r'^/users/login|^/api/terminal/v1/.*|/api/audits/.*|/api/users/v1/auth/|/api/users/v1/profile/'
+SAFE_URL = r'^/users/login|^/api/terminal/v1/.*|/api/terminal/.*|/api/users/v1/auth/|/api/users/v1/profile/'
class TimezoneMiddleware(MiddlewareMixin):
diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py
index 00290db0d..795223d84 100644
--- a/apps/jumpserver/settings.py
+++ b/apps/jumpserver/settings.py
@@ -59,7 +59,7 @@ INSTALLED_APPS = [
'assets.apps.AssetsConfig',
'perms.apps.PermsConfig',
'ops.apps.OpsConfig',
- 'audits.apps.AuditsConfig',
+ # 'audits.apps.AuditsConfig',
'common.apps.CommonConfig',
'terminal.apps.ApplicationsConfig',
'rest_framework',
@@ -364,7 +364,7 @@ CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',)
CAPTCHA_TEST_MODE = CONFIG.CAPTCHA_TEST_MODE
COMMAND_STORE_BACKEND = 'terminal.backends.command.db'
-RECORD_STORE_BACKEND = 'terminal.backends.replay.db'
+REPLAY_STORE_BACKEND = 'terminal.backends.replay.db'
# Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py
index 80e8df1f2..cf5270d29 100644
--- a/apps/jumpserver/urls.py
+++ b/apps/jumpserver/urls.py
@@ -16,7 +16,7 @@ urlpatterns = [
url(r'^users/', include('users.urls.views_urls', namespace='users')),
url(r'^assets/', include('assets.urls.views_urls', namespace='assets')),
url(r'^perms/', include('perms.urls.views_urls', namespace='perms')),
- url(r'^audits/', include('audits.urls.views_urls', namespace='audits')),
+ # url(r'^audits/', include('audits.urls.views_urls', namespace='audits')),
url(r'^terminal/', include('terminal.urls.views_urls', namespace='terminal')),
url(r'^ops/', include('ops.urls.view_urls', namespace='ops')),
@@ -24,7 +24,7 @@ urlpatterns = [
url(r'^api/users/', include('users.urls.api_urls', namespace='api-users')),
url(r'^api/assets/', include('assets.urls.api_urls', namespace='api-assets')),
url(r'^api/perms/', include('perms.urls.api_urls', namespace='api-perms')),
- url(r'^api/audits/', include('audits.urls.api_urls', namespace='api-audits')),
+ # url(r'^api/audits/', include('audits.urls.api_urls', namespace='api-audits')),
url(r'^api/terminal/', include('terminal.urls.api_urls', namespace='api-terminal')),
url(r'^api/ops/', include('ops.urls.api_urls', namespace='api-ops')),
url(r'^captcha/', include('captcha.urls')),
diff --git a/apps/jumpserver/views.py b/apps/jumpserver/views.py
index e08956de0..08ddbf3db 100644
--- a/apps/jumpserver/views.py
+++ b/apps/jumpserver/views.py
@@ -6,70 +6,146 @@ from django.shortcuts import redirect
from users.models import User
from assets.models import Asset
-from audits.models import ProxyLog
+from terminal.models import Session
class IndexView(LoginRequiredMixin, TemplateView):
template_name = 'index.html'
+ session_week = None
+ session_month = None
+ session_month_dates = []
+ session_month_dates_archive = []
+
def get(self, request, *args, **kwargs):
if not request.user.is_superuser:
return redirect('assets:user-asset-list')
return super(IndexView, self).get(request, *args, **kwargs)
- def get_context_data(self, **kwargs):
- seven_days_ago = timezone.now() - timezone.timedelta(days=7)
- month_ago = timezone.now() - timezone.timedelta(days=30)
- proxy_log_seven_days = ProxyLog.objects.filter(date_start__gt=seven_days_ago, is_failed=False)
- proxy_log_month = ProxyLog.objects.filter(date_start__gt=month_ago, is_failed=False)
- month_dates = proxy_log_month.dates('date_start', 'day')
- month_total_visit = [ProxyLog.objects.filter(date_start__date=d) for d in month_dates]
- month_str = [d.strftime('%m-%d') for d in month_dates] or ['0']
- month_total_visit_count = [p.count() for p in month_total_visit] or [0]
- month_user = [p.values('user').distinct().count() for p in month_total_visit] or [0]
- month_asset = [p.values('asset').distinct().count() for p in month_total_visit] or [0]
- month_user_active = User.objects.filter(last_login__gt=month_ago).count()
- month_user_inactive = User.objects.filter(last_login__lt=month_ago).count()
- month_user_disabled = User.objects.filter(is_active=False).count()
- month_asset_active = proxy_log_month.values('asset').distinct().count()
- month_asset_inactive = Asset.objects.all().count() - month_asset_active
- month_asset_disabled = Asset.objects.filter(is_active=False).count()
- week_asset_hot_ten = list(proxy_log_seven_days.values('asset').annotate(total=Count('asset')).order_by('-total')[:10])
- for p in week_asset_hot_ten:
- last_login = ProxyLog.objects.filter(asset=p['asset']).order_by('date_start').last()
- p['last'] = last_login
- last_login_ten = ProxyLog.objects.all().order_by('-date_start')[:10]
- for p in last_login_ten:
+ @staticmethod
+ def get_user_count():
+ return User.objects.filter(role__in=('Admin', 'User')).count()
+
+ @staticmethod
+ def get_asset_count():
+ return Asset.objects.all().count()
+
+ @staticmethod
+ def get_online_user_count():
+ return len(set(Session.objects.filter(is_finished=False).values_list('user', flat=True)))
+
+ @staticmethod
+ def get_online_session_count():
+ return Session.objects.filter(is_finished=False).count()
+
+ def get_top5_user_a_week(self):
+ return self.session_week.values('user').annotate(total=Count('user')).order_by('-total')[:5]
+
+ def get_week_login_user_count(self):
+ return self.session_week.values('user').distinct().count()
+
+ def get_week_login_asset_count(self):
+ return self.session_week.values('asset').distinct().count()
+
+ def get_month_day_metrics(self):
+ month_str = [d.strftime('%m-%d') for d in self.session_month_dates] or ['0']
+ return month_str
+
+ def get_month_login_metrics(self):
+ return [self.session_month.filter(date_start__date=d).count()
+ for d in self.session_month_dates]
+
+ def get_month_active_user_metrics(self):
+ if self.session_month_dates_archive:
+ return [q.values('user').distinct().count()
+ for q in self.session_month_dates_archive]
+ else:
+ return [0]
+
+ def get_month_active_asset_metrics(self):
+ if self.session_month_dates_archive:
+ return [q.values('asset').distinct().count()
+ for q in self.session_month_dates_archive]
+ else:
+ return [0]
+
+ def get_month_active_user_total(self):
+ return self.session_month.values('user').distinct().count()
+
+ def get_month_inactive_user_total(self):
+ return User.objects.all().count() - self.get_month_active_user_total()
+
+ def get_month_active_asset_total(self):
+ return self.session_month.values('asset').distinct().count()
+
+ def get_month_inactive_asset_total(self):
+ return Asset.objects.all().count() - self.get_month_active_asset_total()
+
+ @staticmethod
+ def get_user_disabled_total():
+ return User.objects.filter(is_active=False).count()
+
+ @staticmethod
+ def get_asset_disabled_total():
+ return Asset.objects.filter(is_active=False).count()
+
+ def get_week_top10_asset(self):
+ assets = list(self.session_week.values('asset').annotate(total=Count('asset')).order_by('-total')[:10])
+ for asset in assets:
+ last_login = self.session_week.filter(asset=asset["asset"]).order_by('date_start').last()
+ asset['last'] = last_login
+ print(asset)
+ return assets
+
+ def get_week_top10_user(self):
+ users = list(self.session_week.values('user').annotate(
+ total=Count('asset')).order_by('-total')[:10])
+ for user in users:
+ last_login = self.session_week.filter(user=user["user"]).order_by('date_start').last()
+ user['last'] = last_login
+ return users
+
+ def get_last10_sessions(self):
+ sessions = self.session_week.order_by('-date_start')[:10]
+ for session in sessions:
try:
- p.avatar_url = User.objects.get(username=p.user).avatar_url()
+ session.avatar_url = User.objects.get(username=session.user).avatar_url()
except User.DoesNotExist:
- p.avatar_url = User.objects.first().avatar_url()
- week_user_hot_ten = list(proxy_log_seven_days.values('user').annotate(total=Count('user')).order_by('-total')[:10])
- for p in week_user_hot_ten:
- last_login = ProxyLog.objects.filter(user=p['user']).order_by('date_start').last()
- p['last'] = last_login
+ session.avatar_url = User.objects.first().avatar_url()
+ return sessions
+
+ def get_context_data(self, **kwargs):
+ week_ago = timezone.now() - timezone.timedelta(weeks=1)
+ month_ago = timezone.now() - timezone.timedelta(days=30)
+ self.session_week = Session.objects.filter(date_start__gt=week_ago)
+ self.session_month = Session.objects.filter(date_start__gt=month_ago)
+ self.session_month_dates = self.session_month.dates('date_start', 'day')
+ self.session_month_dates_archive = [
+ self.session_month.filter(date_start__date=d)
+ for d in self.session_month_dates
+ ]
context = {
- 'assets_count': Asset.objects.count(),
- 'users_count': User.objects.filter(role__in=('Admin', 'User')).count(),
- 'online_user_count': ProxyLog.objects.filter(is_finished=False).values('user').distinct().count(),
- 'online_asset_count': ProxyLog.objects.filter(is_finished=False).values('asset').distinct().count(),
- 'user_visit_count_weekly': proxy_log_seven_days.values('user').distinct().count(),
- 'asset_visit_count_weekly': proxy_log_seven_days.count(),
- 'user_visit_count_top_five': proxy_log_seven_days.values('user').annotate(total=Count('user')).order_by('-total')[:5],
- 'month_str': month_str,
- 'month_total_visit_count': month_total_visit_count,
- 'month_user': month_user,
- 'mouth_asset': month_asset,
- 'month_user_active': month_user_active,
- 'month_user_inactive': month_user_inactive,
- 'month_user_disabled': month_user_disabled,
- 'month_asset_active': month_asset_active,
- 'month_asset_inactive': month_asset_inactive,
- 'month_asset_disabled': month_asset_disabled,
- 'week_asset_hot_ten': week_asset_hot_ten,
- 'last_login_ten': last_login_ten,
- 'week_user_hot_ten': week_user_hot_ten,
+ 'assets_count': self.get_asset_count(),
+ 'users_count': self.get_user_count(),
+ 'online_user_count': self.get_online_user_count(),
+ 'online_asset_count': self.get_online_session_count(),
+ 'user_visit_count_weekly': self.get_week_login_user_count(),
+ 'asset_visit_count_weekly': self.get_week_login_asset_count(),
+ 'user_visit_count_top_five': self.get_top5_user_a_week(),
+ 'month_str': self.get_month_day_metrics(),
+ 'month_total_visit_count': self.get_month_login_metrics(),
+ 'month_user': self.get_month_active_user_metrics(),
+ 'mouth_asset': self.get_month_active_asset_metrics(),
+ 'month_user_active': self.get_month_active_user_total(),
+ 'month_user_inactive': self.get_month_inactive_user_total(),
+ 'month_user_disabled': self.get_user_disabled_total(),
+ 'month_asset_active': self.get_month_active_asset_total(),
+ 'month_asset_inactive': self.get_month_inactive_asset_total(),
+ 'month_asset_disabled': self.get_asset_disabled_total(),
+ 'week_asset_hot_ten': self.get_week_top10_asset(),
+ 'last_login_ten': self.get_last10_sessions(),
+ 'week_user_hot_ten': self.get_week_top10_user(),
}
kwargs.update(context)
diff --git a/apps/templates/index.html b/apps/templates/index.html
index 581751f22..5ddbc17ab 100644
--- a/apps/templates/index.html
+++ b/apps/templates/index.html
@@ -35,7 +35,7 @@
在线用户
@@ -45,11 +45,11 @@
Connected
-
已连接服务器
+ 在线会话
-
-
Connected host
+
+
Online sessions
diff --git a/apps/terminal/api.py b/apps/terminal/api.py
index 681dca4c1..6fcd2fc18 100644
--- a/apps/terminal/api.py
+++ b/apps/terminal/api.py
@@ -1,10 +1,8 @@
# -*- coding: utf-8 -*-
#
-import base64
from collections import OrderedDict
import copy
import logging
-import tarfile
import os
from rest_framework import viewsets, serializers
@@ -18,7 +16,7 @@ from common.utils import get_object_or_none
from .models import Terminal, Status, Session, Task
from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer, TaskSerializer
-from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
+from .hands import IsSuperUserOrAppUser, IsAppUser, \
IsSuperUserOrAppUserOrUserReadonly
from .backends import get_command_store, get_replay_store, SessionCommandSerializer
@@ -221,7 +219,9 @@ class CommandViewSet(viewsets.ViewSet):
else:
return Response("Save error", status=500)
else:
- return Response({"msg": "Not valid: {}".format(serializer.errors)}, status=401)
+ msg = "Not valid: {}".format(serializer.errors)
+ logger.error(msg)
+ return Response({"msg": msg}, status=401)
def list(self, request, *args, **kwargs):
queryset = list(self.command_store.all())
diff --git a/apps/terminal/backends/__init__.py b/apps/terminal/backends/__init__.py
index 813f7f88c..6a9d06079 100644
--- a/apps/terminal/backends/__init__.py
+++ b/apps/terminal/backends/__init__.py
@@ -12,6 +12,6 @@ def get_command_store():
def get_replay_store():
- replay_engine = import_module(settings.RECORD_STORE_BACKEND)
- replay_store = replay_engine.RecordStore()
+ replay_engine = import_module(settings.REPLAY_STORE_BACKEND)
+ replay_store = replay_engine.ReplayStore()
return replay_store
diff --git a/apps/terminal/backends/replay/base.py b/apps/terminal/backends/replay/base.py
index e96b8b131..46a2df845 100644
--- a/apps/terminal/backends/replay/base.py
+++ b/apps/terminal/backends/replay/base.py
@@ -2,7 +2,7 @@
import abc
-class RecordBase(object):
+class ReplayBase(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
diff --git a/apps/terminal/backends/replay/db.py b/apps/terminal/backends/replay/db.py
index e55211f65..06d2c5ab3 100644
--- a/apps/terminal/backends/replay/db.py
+++ b/apps/terminal/backends/replay/db.py
@@ -1,31 +1,8 @@
# ~*~ coding: utf-8 ~*~
-from .base import RecordBase
-from audits.models import RecordLog
+from .base import ReplayBase
-class RecordStore(RecordBase):
- model = RecordLog
- queryset = []
-
- def save(self, proxy_log_id, output, timestamp):
- return self.model.objects.create(
- proxy_log_id=proxy_log_id, output=output, timestamp=timestamp
- )
-
- def filter(self, date_from_ts=None, proxy_log_id=''):
- filter_kwargs = {}
-
- if date_from_ts:
- filter_kwargs['timestamp__gte'] = date_from_ts
- if proxy_log_id:
- filter_kwargs['proxy_log_id'] = proxy_log_id
-
- if filter_kwargs:
- self.queryset = self.model.objects.filter(**filter_kwargs)
- return self.queryset
-
- def all(self):
- """返回所有数据"""
- return self.model.objects.all()
+class ReplayStore(ReplayBase):
+ pass
diff --git a/apps/terminal/backends/replay/serializers.py b/apps/terminal/backends/replay/serializers.py
deleted file mode 100644
index 30a5867e1..000000000
--- a/apps/terminal/backends/replay/serializers.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# ~*~ coding: utf-8 ~*~
-import base64
-from rest_framework import serializers
-from audits.models import RecordLog
-from audits.backends import record_store
-
-
-class RecordSerializer(serializers.ModelSerializer):
- """使用这个类作为基础Command Log Serializer类, 用来序列化"""
- class Meta:
- model = RecordLog
- fields = '__all__'
-
- def create(self, validated_data):
- try:
- output = validated_data['output']
- validated_data['output'] = base64.b64decode(output)
- except IndexError:
- pass
- return record_store.save(**dict(validated_data))
diff --git a/apps/terminal/hands.py b/apps/terminal/hands.py
index 23a93691d..ce075bfc5 100644
--- a/apps/terminal/hands.py
+++ b/apps/terminal/hands.py
@@ -4,5 +4,4 @@
from users.models import User
from users.permissions import IsSuperUserOrAppUser, IsAppUser, \
IsSuperUserOrAppUserOrUserReadonly
-from audits.models import ProxyLog
from users.utils import AdminUserRequiredMixin
\ No newline at end of file
diff --git a/apps/terminal/tasks.py b/apps/terminal/tasks.py
index 4bcfae396..47b0748af 100644
--- a/apps/terminal/tasks.py
+++ b/apps/terminal/tasks.py
@@ -13,6 +13,7 @@ ASSETS_CACHE_KEY = "terminal__session__assets"
USERS_CACHE_KEY = "terminal__session__users"
SYSTEM_USER_CACHE_KEY = "terminal__session__system_users"
CACHE_REFRESH_INTERVAL = 10
+RUNNING = False
# Todo: 定期清理上报history
@@ -46,7 +47,16 @@ def set_cache():
def main():
+ global RUNNING
+ if RUNNING:
+ return
+ threads = []
thread = threading.Thread(target=set_cache)
- thread.start()
+ threads.append(thread)
+
+ for t in threads:
+ t.daemon = True
+ t.start()
+ RUNNING = True
main()
diff --git a/apps/users/api.py b/apps/users/api.py
index aed67cc8c..522a47bb5 100644
--- a/apps/users/api.py
+++ b/apps/users/api.py
@@ -9,7 +9,7 @@ from rest_framework_bulk import BulkModelViewSet
from django_filters.rest_framework import DjangoFilterBackend
from . import serializers
-from .hands import write_login_log_async
+from .tasks import write_login_log_async
from .models import User, UserGroup
from .permissions import IsSuperUser, IsValidUser, IsCurrentUserOrReadOnly
from .utils import check_user_valid, generate_token
diff --git a/apps/users/hands.py b/apps/users/hands.py
index b44b9bb84..bf47d775a 100644
--- a/apps/users/hands.py
+++ b/apps/users/hands.py
@@ -10,8 +10,8 @@
:license: GPL v2, see LICENSE for more details.
"""
-from terminal.models import Terminal
-from audits.tasks import write_login_log_async
-from users.models import User
+# from terminal.models import Terminal
+# from audits.tasks import write_login_log_async
+# from users.models import User
# from perms.models import AssetPermission
# from perms.utils import get_user_granted_assets, get_user_granted_asset_groups
diff --git a/apps/users/models/authentication.py b/apps/users/models/authentication.py
index 954c7e5bc..61f84b81f 100644
--- a/apps/users/models/authentication.py
+++ b/apps/users/models/authentication.py
@@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.authtoken.models import Token
from . import User
-__all__ = ['AccessKey', 'PrivateToken']
+__all__ = ['AccessKey', 'PrivateToken', 'LoginLog']
class AccessKey(models.Model):
@@ -34,3 +34,22 @@ class PrivateToken(Token):
class Meta:
verbose_name = _('Private Token')
+
+
+class LoginLog(models.Model):
+ LOGIN_TYPE_CHOICE = (
+ ('W', 'Web'),
+ ('ST', 'SSH Terminal'),
+ ('WT', 'Web Terminal')
+ )
+ id = models.UUIDField(default=uuid.uuid4, primary_key=True)
+ username = models.CharField(max_length=20, verbose_name=_('Username'))
+ type = models.CharField(choices=LOGIN_TYPE_CHOICE, max_length=2, verbose_name=_('Login type'))
+ ip = models.GenericIPAddressField(verbose_name=_('Login ip'))
+ city = models.CharField(max_length=254, blank=True, null=True, verbose_name=_('Login city'))
+ user_agent = models.CharField(max_length=254, blank=True, null=True, verbose_name=_('User agent'))
+ datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('Date login'))
+
+ class Meta:
+ db_table = 'login_log'
+ ordering = ['-datetime', 'username']
diff --git a/apps/users/models/group.py b/apps/users/models/group.py
index 0e75a16d5..c0950cf9f 100644
--- a/apps/users/models/group.py
+++ b/apps/users/models/group.py
@@ -24,9 +24,8 @@ class UserGroup(NoDeleteModelMixin):
verbose_name=_('Date created'))
created_by = models.CharField(max_length=100)
- def __unicode__(self):
+ def __str__(self):
return self.name
- __str__ = __unicode__
def delete(self, using=None, keep_parents=False):
if self.name != 'Default':
diff --git a/apps/audits/tasks.py b/apps/users/tasks.py
similarity index 76%
rename from apps/audits/tasks.py
rename to apps/users/tasks.py
index f80aa5f75..8d8eb6553 100644
--- a/apps/audits/tasks.py
+++ b/apps/users/tasks.py
@@ -1,6 +1,5 @@
-#!/usr/bin/env python
-# ~*~ coding: utf-8 ~*~
-#
+# -*- coding: utf-8 -*-
+#
from celery import shared_task
from .utils import write_login_log
diff --git a/apps/users/utils.py b/apps/users/utils.py
index 6610c2112..c62784e91 100644
--- a/apps/users/utils.py
+++ b/apps/users/utils.py
@@ -5,7 +5,8 @@ import base64
import logging
import uuid
-from paramiko.rsakey import RSAKey
+import requests
+import ipaddress
from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin
from django.contrib.auth import authenticate
@@ -14,13 +15,7 @@ from django.core.cache import cache
from common.tasks import send_mail_async
from common.utils import reverse, get_object_or_none
-from .models import User
-
-
-# try:
-# from io import StringIO
-# except ImportError:
-# from StringIO import StringIO
+from .models import User, LoginLog
logger = logging.getLogger('jumpserver')
@@ -172,3 +167,40 @@ def generate_token(request, user):
return token
+def validate_ip(ip):
+ try:
+ ipaddress.ip_address(ip)
+ return True
+ except ValueError:
+ pass
+ return False
+
+
+def write_login_log(username, type='', ip='', user_agent=''):
+ if not (ip and validate_ip(ip)):
+ ip = '0.0.0.0'
+ city = get_ip_city(ip)
+ LoginLog.objects.create(
+ username=username, type=type,
+ ip=ip, city=city, user_agent=user_agent
+ )
+
+
+def get_ip_city(ip, timeout=10):
+ # Taobao ip api: http://ip.taobao.com//service/getIpInfo.php?ip=8.8.8.8
+ # Sina ip api: http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=8.8.8.8&format=json
+
+ url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=%s&format=json' % ip
+ try:
+ r = requests.get(url, timeout=timeout)
+ except requests.Timeout:
+ r = None
+ city = 'Unknown'
+ if r and r.status_code == 200:
+ try:
+ data = r.json()
+ if not isinstance(data, int) and data['ret'] == 1:
+ city = data['country'] + ' ' + data['city']
+ except ValueError:
+ pass
+ return city
diff --git a/apps/users/views/login.py b/apps/users/views/login.py
index 115db0f1a..a09125c02 100644
--- a/apps/users/views/login.py
+++ b/apps/users/views/login.py
@@ -21,7 +21,7 @@ from django.conf import settings
from common.utils import get_object_or_none
from ..models import User
from ..utils import send_reset_password_mail
-from ..hands import write_login_log_async
+from ..tasks import write_login_log_async
from .. import forms