Commit 41337d28 authored by ibuler's avatar ibuler

add proxy log search

parent 1d29c52a
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
# #
from users.models import User
from assets.models import Asset, SystemUser
from users.backends import IsSuperUserOrTerminalUser from users.backends import IsSuperUserOrTerminalUser
from terminal.models import Terminal from terminal.models import Terminal
...@@ -71,7 +71,7 @@ class ProxyLog(models.Model): ...@@ -71,7 +71,7 @@ class ProxyLog(models.Model):
class CommandLog(models.Model): class CommandLog(models.Model):
proxy_log = models.ForeignKey(ProxyLog, on_delete=models.CASCADE, related_name='command_log') proxy_log = models.ForeignKey(ProxyLog, on_delete=models.CASCADE, related_name='commands')
command_no = models.IntegerField() command_no = models.IntegerField()
command = models.CharField(max_length=1000, blank=True) command = models.CharField(max_length=1000, blank=True)
output = models.TextField(blank=True) output = models.TextField(blank=True)
......
...@@ -14,7 +14,8 @@ class ProxyLogSerializer(serializers.ModelSerializer): ...@@ -14,7 +14,8 @@ class ProxyLogSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.ProxyLog model = models.ProxyLog
fields = ['id', 'name', 'username', 'hostname', 'ip', 'system_user', 'login_type', 'terminal', fields = ['id', 'name', 'username', 'hostname', 'ip', 'system_user', 'login_type', 'terminal',
'log_file', 'was_failed', 'is_finished', 'date_start', 'time', 'command_length', "commands_dict"] 'log_file', 'was_failed', 'is_finished', 'date_start', 'date_finished', 'time',
'command_length', "commands_dict"]
@staticmethod @staticmethod
def get_time(obj): def get_time(obj):
...@@ -25,7 +26,7 @@ class ProxyLogSerializer(serializers.ModelSerializer): ...@@ -25,7 +26,7 @@ class ProxyLogSerializer(serializers.ModelSerializer):
@staticmethod @staticmethod
def get_command_length(obj): def get_command_length(obj):
return len(obj.command_log.all()) return len(obj.commands.all())
class CommandLogSerializer(serializers.ModelSerializer): class CommandLogSerializer(serializers.ModelSerializer):
......
...@@ -3,10 +3,44 @@ ...@@ -3,10 +3,44 @@
{% load static %} {% load static %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block content_left_head %}
{# <a href="{% url 'perms:asset-permission-create' %}" class="btn btn-sm btn-primary "> {% trans "Create permission" %} </a>#}
<link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet">
<style>
#search_btn {
margin-bottom: 0;
}
</style>
{% endblock %} {% endblock %}
{% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline">
<div class="input-group">
<select class="select2 form-control" name="user">
<option>{% trans 'Select user' %}</option>
{% for user in user_list %}
<option value="{{ user.username }}">{{ user.username }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="asset">
<option>{% trans 'Select asset' %}</option>
{% for asset in asset_list %}
<option value="{{ asset.ip }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
</div>
<div class="input-group">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
{% endblock %}
{% block table_container %} {% block table_container %}
<table class="footable table table-stripped toggle-arrow-tiny" data-page="false"> <table class="footable table table-stripped toggle-arrow-tiny" data-page="false">
<thead> <thead>
...@@ -16,6 +50,7 @@ ...@@ -16,6 +50,7 @@
<th>Username</th> <th>Username</th>
<th>IP</th> <th>IP</th>
<th>System user</th> <th>System user</th>
<th>Proxy log</th>
<th>Datetime</th> <th>Datetime</th>
<th data-hide="all">Output</th> <th data-hide="all">Output</th>
</tr> </tr>
...@@ -23,11 +58,12 @@ ...@@ -23,11 +58,12 @@
<tbody> <tbody>
{% for command in command_list %} {% for command in command_list %}
<tr> <tr>
<td>{{ command.command_no }}</td> <td>{{ command.id }}</td>
<td>{{ command.command }}</td> <td>{{ command.command }}</td>
<td>{{ command.proxy_log.username }}</td> <td>{{ command.proxy_log.username }}</td>
<td>{{ command.proxy_log.ip }}</td> <td>{{ command.proxy_log.ip }}</td>
<td>{{ command.proxy_log.system_user }}</td> <td>{{ command.proxy_log.system_user }}</td>
<td><a href="{% url 'audits:proxy-log-detail' pk=command.proxy_log.id %}">{{ command.proxy_log.id}}</a></td>
<td>{{ command.datetime }}</td> <td>{{ command.datetime }}</td>
<td>{{ command.output_decode |safe }}</td> <td>{{ command.output_decode |safe }}</td>
</tr> </tr>
...@@ -41,6 +77,7 @@ ...@@ -41,6 +77,7 @@
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.footable').footable(); $('.footable').footable();
$('.select2').select2();
}); });
</script> </script>
{% endblock %} {% endblock %}
......
{% extends '_base_list.html' %} {% extends '_base_list.html' %}
{% load i18n %} {% load i18n %}
{% load static %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %}
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<style>
#search_btn {
margin-bottom: 0;
}
</style>
{% endblock %}
{% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline">
<div class="form-group" id="date">
<div class="input-daterange input-group" id="datepicker">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_from" value="{{ date_from }}">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_to" value="{{ date_to }}">
</div>
</div>
<div class="input-group">
<select class="select2 form-control" name="username">
<option value="">{% trans 'Select user' %}</option>
{% for user in user_list %}
<option value="{{ user.username }}">{{ user.username }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<select class="select2 form-control" name="ip">
<option value="">{% trans 'Select asset' %}</option>
{% for asset in asset_list %}
<option value="{{ asset.ip }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
</div>
<div class="input-group">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
{% endblock %}
{% block table_head %} {% block table_head %}
<th class="text-center">{% trans 'ID' %}</th> <th class="text-center">{% trans 'ID' %}</th>
...@@ -22,8 +71,8 @@ ...@@ -22,8 +71,8 @@
</td> </td>
<td class="text-center">{{ proxy_log.username }}</td> <td class="text-center">{{ proxy_log.username }}</td>
<td class="text-center">{{ proxy_log.ip }}</td> <td class="text-center">{{ proxy_log.ip }}</td>
<td class="text-center">{{ proxy_log.system_user.name }}</td> <td class="text-center">{{ proxy_log.system_user }}</td>
<td class="text-center">{{ proxy_log.command.count }}</td> <td class="text-center">{{ proxy_log.commands.all|length}}</td>
<td class="text-center"> <td class="text-center">
{% if proxy_log.was_failed %} {% if proxy_log.was_failed %}
<i class="fa fa-times text-danger"></i> <i class="fa fa-times text-danger"></i>
...@@ -33,25 +82,33 @@ ...@@ -33,25 +82,33 @@
</td> </td>
<td class="text-center"> <td class="text-center">
{% if proxy_log.is_finished %} {% if proxy_log.is_finished %}
<i class="fa fa-times text-danger"></i>
{% else %}
<i class="fa fa-check text-navy"></i> <i class="fa fa-check text-navy"></i>
{% else %}
<i class="fa fa-times text-danger"></i>
{% endif %} {% endif %}
</td> </td>
<td class="text-center">{{ proxy_log.date_start }}</td> <td class="text-center">{{ proxy_log.date_start }}</td>
<td class="text-center">{{ proxy_log.date_finished }}</td> <td class="text-center">{{ proxy_log.date_finished|timeuntil:proxy_log.date_start }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('table').DataTable({ $('table').DataTable({
"searching": false, "searching": false,
"paging": false, "paging": false,
"order": [] "order": []
}) });
$('.select2').select2();
$('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
}) })
</script> </script>
{% endblock %} {% endblock %}
......
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
# #
import datetime
from django.views.generic import ListView, UpdateView, DeleteView, DetailView, TemplateView from django.views.generic import ListView, UpdateView, DeleteView, DetailView, TemplateView
from django.views.generic.edit import SingleObjectMixin from django.views.generic.edit import SingleObjectMixin
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils import timezone
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings from django.conf import settings
from django.db.models import Q
from .models import ProxyLog, CommandLog from .models import ProxyLog, CommandLog
from .utils import AdminUserRequiredMixin from .utils import AdminUserRequiredMixin
from .hands import User, Asset, SystemUser
class ProxyLogListView(ListView): class ProxyLogListView(AdminUserRequiredMixin, ListView):
model = ProxyLog model = ProxyLog
template_name = 'audits/proxy_log_list.html' template_name = 'audits/proxy_log_list.html'
context_object_name = 'proxy_log_list' context_object_name = 'proxy_log_list'
def get_queryset(self):
self.queryset = super(ProxyLogListView, self).get_queryset()
self.keyword = keyword = self.request.GET.get('keyword', '')
self.username = username = self.request.GET.get('username', '')
self.ip = ip = self.request.GET.get('ip', '')
self.date_from_s = date_from_s = \
self.request.GET.get('date_from', '%s' % (datetime.datetime.now()-datetime.timedelta(7)).strftime('%m/%d/%Y'))
self.date_to_s = date_to_s = self.request.GET.get('date_to', '%s' % datetime.datetime.now().strftime('%m/%d/%Y'))
if date_from_s:
date_from = timezone.datetime.strptime(date_from_s, '%m/%d/%Y')
self.queryset = self.queryset.filter(date_start__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_start__lt=date_to)
if username:
self.queryset = self.queryset.filter(username=username)
if ip:
self.queryset = self.queryset.filter(ip=ip)
if keyword:
self.queryset = self.queryset.filter(Q(username__contains=keyword) |
Q(name__icontains=keyword) |
Q(hostname__icontains=keyword) |
Q(ip__icontains=keyword) |
Q(system_user__icontains=keyword)).distinct()
return self.queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ProxyLogListView, self).get_context_data(**kwargs) context = {
context.update({'app': _('Audits'), 'action': _('Proxy log list')}) 'app': _('Audits'),
return context 'action': _('Proxy log list'),
'user_list': User.objects.all(),
'asset_list': Asset.objects.all(),
'system_user_list': SystemUser.objects.all(),
'keyword': self.keyword,
'date_from': self.date_from_s,
'date_to': self.date_to_s,
}
kwargs.update(context)
return super(ProxyLogListView, self).get_context_data(**kwargs)
class ProxyLogDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): class ProxyLogDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
...@@ -31,7 +72,7 @@ class ProxyLogDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): ...@@ -31,7 +72,7 @@ class ProxyLogDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
return super(ProxyLogDetailView, self).get(request, *args, **kwargs) return super(ProxyLogDetailView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return list(self.object.command_log.all()) return list(self.object.commands.all())
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
...@@ -74,8 +115,11 @@ class CommandLogListView(AdminUserRequiredMixin, ListView): ...@@ -74,8 +115,11 @@ class CommandLogListView(AdminUserRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'Audits', 'app': _('Audits'),
'action': 'Command log list' 'action': _('Command log list'),
'user_list': User.objects.all(),
'asset_list': Asset.objects.all(),
'system_user_list': SystemUser.objects.all(),
} }
kwargs.update(context) kwargs.update(context)
return super(CommandLogListView, self).get_context_data(**kwargs) return super(CommandLogListView, self).get_context_data(**kwargs)
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
</div> </div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datapicker/bootstrap-datepicker.js' %}"></script> <script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
......
...@@ -33,15 +33,19 @@ ...@@ -33,15 +33,19 @@
<div class="" id="content_start"> <div class="" id="content_start">
{% block content_left_head %} {% endblock %} {% block content_left_head %} {% endblock %}
{% block table_search %} {% block table_search %}
<form id="search_form" method="get" action="" class="pull-right mail-search"> <form id="search_form" method="get" action="" class="pull-right mail-search form-inline">
{% block search_form %}
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}"> <input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
</div>
<div class="input-group">
<div class="input-group-btn"> <div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary"> <button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索 搜索
</button> </button>
</div> </div>
</div> </div>
{% endblock %}
</form> </form>
{% endblock %} {% endblock %}
{% block tags_list %}{% endblock %} {% block tags_list %}{% endblock %}
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</div> </div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datapicker/bootstrap-datepicker.js' %}"></script> <script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
</div> </div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datapicker/bootstrap-datepicker.js' %}"></script> <script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment