mirror of https://github.com/jumpserver/jumpserver
[Feature] 离线session完成
parent
9b6696bb6e
commit
71a3079221
|
@ -41,8 +41,9 @@
|
|||
</a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li>
|
||||
<li id="session"><a href="{% url 'terminal:session-online-list' %}">{% trans 'Session' %}</a></li>
|
||||
<li id="command"><a href="">{% trans 'Command' %}</a></li>
|
||||
<li id="session-online"><a href="{% url 'terminal:session-online-list' %}">{% trans 'Session online' %}</a></li>
|
||||
<li id="session-offline"><a href="{% url 'terminal:session-offline-list' %}">{% trans 'Session offline' %}</a></li>
|
||||
<li id="command"><a href="{% url 'terminal:command-list' %}">{% trans 'Command' %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<i class="fa fa-user" ></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="applications">
|
||||
<a href="{% url 'applications:terminal-list' %}">
|
||||
<li id="terminal">
|
||||
<a href="{% url 'terminal:terminal-list' %}">
|
||||
<i class="fa fa-terminal" ></i> <span class="nav-label">{% trans 'Terminal' %}</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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',)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<select class="select2 form-control" name="username">
|
||||
<option value="">{% trans 'User' %}</option>
|
||||
{% for u in user_list %}
|
||||
<option value="{{ u.username }}" {% if username == u.username %} selected {% endif %}>{{ u.username }}</option>
|
||||
<option value="{{ u }}" {% if user == u %} selected {% endif %}>{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@
|
|||
<select class="select2 form-control" name="ip">
|
||||
<option value="">{% trans 'Asset' %}</option>
|
||||
{% for a in asset_list %}
|
||||
<option value="{{ a.ip }}" {% if ip == a.ip %} selected {% endif %}>{{ a.ip }}</option>
|
||||
<option value="{{ a }}" {% if a == asset %} selected {% endif %}>{{ a }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -42,7 +42,7 @@
|
|||
<select class="select2 form-control" name="system_user">
|
||||
<option value="">{% trans 'System user' %}</option>
|
||||
{% for s in system_user_list %}
|
||||
<option value="{{ s.username }}" {% if s.username == system_user %} selected {% endif %}>{{ s.username }}</option>
|
||||
<option value="{{ s }}" {% if s == system_user %} selected {% endif %}>{{ s }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -67,22 +67,22 @@
|
|||
<th>Username</th>
|
||||
<th>IP</th>
|
||||
<th>System user</th>
|
||||
<th>Proxy log</th>
|
||||
<th>Session</th>
|
||||
<th>Datetime</th>
|
||||
<th data-hide="all">Output</th>
|
||||
<th data-hide="all"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for command in command_list %}
|
||||
<tr>
|
||||
<td>{{ command.id }}</td>
|
||||
<td>{{ command.command }}</td>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ command.input }}</td>
|
||||
<td>{{ command.user }}</td>
|
||||
<td>{{ command.asset }}</td>
|
||||
<td>{{ command.system_user }}</td>
|
||||
<td><a href="{% url 'audits:proxy-log-detail' pk=command.proxy_log_id %}">{{ command.proxy_log_id}}</a></td>
|
||||
<td><a href="{% url 'terminal:session-detail' pk=command.session %}">{% trans "Goto" %}</a></td>
|
||||
<td>{{ command.timestamp|ts_to_date }}</td>
|
||||
<td><pre style="border: none; background: none">{{ command.output|to_html|safe }}</pre></td>
|
||||
<td><pre style="border: none; background: none">{{ command.output }}</pre></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#" class="text-center"> {% trans 'Proxy log detail' %} </a>
|
||||
<a href="#" class="text-center"> {% trans 'Session detail' %} </a>
|
||||
</li>
|
||||
{# <li>#}
|
||||
{# <a href="#" class="text-center"> {% trans 'Session commands' %} </a>#}
|
||||
{# </li>#}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-11" style="padding-left: 0;">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Command list' %} <b></b></span>
|
||||
|
@ -72,6 +75,46 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% if object.is_finished %}
|
||||
<tr>
|
||||
<td class="no-borders">{% trans 'Replay session' %}:</td>
|
||||
<td class="no-borders">
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_password" style="width: 54px">{% trans 'Go' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="no-borders" >{% trans 'Monitor session' %}:</td>
|
||||
<td class="no-borders" >
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs " style="width: 54px">{% trans 'Go' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Terminate session' %}:</td>
|
||||
<td>
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs btn-term" value="{{ object.id }}" terminal="{{ object.terminal.id }}" style="width: 54px;">{% trans 'Confirm' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,8 +125,28 @@
|
|||
{% block custom_foot_js %}
|
||||
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
|
||||
<script>
|
||||
function terminateSession(data) {
|
||||
function success() {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload()
|
||||
}, 300)
|
||||
}
|
||||
var the_url = "{% url 'api-terminal:tasks-list' %}";
|
||||
APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'});
|
||||
}
|
||||
$(document).ready(function () {
|
||||
$('.footable').footable();
|
||||
});
|
||||
}).on('click', '.btn-term', function () {
|
||||
var $this = $(this);
|
||||
var session_id = $this.attr('value');
|
||||
var terminal_id = $this.attr('terminal');
|
||||
alert(session_id);
|
||||
var data = {
|
||||
name: "kill_session",
|
||||
args: session_id,
|
||||
terminal: terminal_id
|
||||
};
|
||||
terminateSession(data)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -23,18 +23,18 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<select class="select2 form-control" name="username">
|
||||
<select class="select2 form-control" name="user">
|
||||
<option value="">{% trans 'User' %}</option>
|
||||
{% for u in user_list %}
|
||||
<option value="{{ u }}" {% if u == username %} selected {% endif %}>{{ u }}</option>
|
||||
<option value="{{ u }}" {% if u == user %} selected {% endif %}>{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<select class="select2 form-control" name="ip">
|
||||
<select class="select2 form-control" name="asset">
|
||||
<option value="">{% trans 'Asset' %}</option>
|
||||
{% for a in asset_list %}
|
||||
<option value="{{ a }}" {% if a == ip %} selected {% endif %}>{{ a }}</option>
|
||||
<option value="{{ a }}" {% if a == asset %} selected {% endif %}>{{ a }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -46,9 +46,9 @@
|
|||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" name="keyword" placeholder="Keyword" value="{{ keyword }}">
|
||||
</div>
|
||||
{# <div class="input-group">#}
|
||||
{# <input type="text" class="form-control input-sm" name="keyword" placeholder="Keyword" value="{{ keyword }}">#}
|
||||
{# </div>#}
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
|
||||
|
@ -67,10 +67,9 @@
|
|||
<th class="text-center">{% trans 'System user' %}</th>
|
||||
<th class="text-center">{% trans 'Terminal' %}</th>
|
||||
<th class="text-center">{% trans 'Command' %}</th>
|
||||
<th class="text-center">{% trans 'Monitor' %}</th>
|
||||
<th class="text-center">{% trans 'Terminate' %}</th>
|
||||
<th class="text-center">{% trans 'Date start' %}</th>
|
||||
<th class="text-center">{% trans 'Time' %}</th>
|
||||
<th class="text-center">{% trans 'Duration' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
{% endblock %}
|
||||
|
||||
{% block table_body %}
|
||||
|
@ -85,42 +84,21 @@
|
|||
<td class="text-center">{{ session.system_user }}</td>
|
||||
<td class="text-center">{{ session.terminal.name }}</td>
|
||||
<td class="text-center">{{ session.id | get_session_command_amount }}</td>
|
||||
{% if session.is_finished %}
|
||||
<td class="text-center">
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a><span class="text-navy"><i class="fa fa-play-circle"></i></span></a>
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="text-center">
|
||||
<a><span class="text-danger"><i class="fa fa-eye"></i></span></a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a class="btn-term" value="{{ session.uuid }}" terminal="{{ session.terminal.id }}"><i class="fa fa-times text-danger"></i></a>
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<td class="text-center">{{ session.date_start }}</td>
|
||||
<td class="text-center">{{ session.date_finished|timeuntil:session.date_start }}</td>
|
||||
<td class="text-center">{{ session.date_end|default_if_none:now|timeuntil:session.date_start }}</td>
|
||||
<td>
|
||||
{% if session.is_finished %}
|
||||
<a href="" class="btn btn-xs btn-warning btn-replay" >{% trans "Replay" %}</a>
|
||||
{% else %}
|
||||
<a class="btn btn-xs btn-warning btn-monitor" >{% trans "Monitor" %}</a>
|
||||
<a class="btn btn-xs btn-danger btn-term" value="{{ session.id }}" terminal="{{ session.terminal.id }}" >{% trans "Terminate" %}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_bottom_left %}
|
||||
<div id="actions">
|
||||
<div class="input-group">
|
||||
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||
<option value="terminate">{% trans 'Terminate selected' %}</option>
|
||||
</select>
|
||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
||||
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
||||
{% trans 'Submit' %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||
<script>
|
|
@ -1,159 +0,0 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% 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 'User' %}</option>
|
||||
{% for u in user_list %}
|
||||
<option value="{{ u }}" {% if u == username %} selected {% endif %}>{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<select class="select2 form-control" name="ip">
|
||||
<option value="">{% trans 'Asset' %}</option>
|
||||
{% for a in asset_list %}
|
||||
<option value="{{ a }}" {% if a == ip %} selected {% endif %}>{{ a }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<select class="select2 form-control" name="system_user">
|
||||
<option value="">{% trans 'System user' %}</option>
|
||||
{% for su in system_user_list %}
|
||||
<option value="{{ su }}" {% if su == system_user %} selected {% endif %}>{{ su }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" name="keyword" placeholder="Keyword" 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 %}
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">{% trans 'ID' %}</th>
|
||||
<th class="text-center">{% trans 'User' %}</th>
|
||||
<th class="text-center">{% trans 'Asset' %}</th>
|
||||
<th class="text-center">{% trans 'System user' %}</th>
|
||||
<th class="text-center">{% trans 'Terminal' %}</th>
|
||||
<th class="text-center">{% trans 'Command' %}</th>
|
||||
<th class="text-center">{% trans 'Success' %}</th>
|
||||
<th class="text-center">{% trans 'Finished' %}</th>
|
||||
<th class="text-center">{% trans 'Play' %}</th>
|
||||
<th class="text-center">{% trans 'Date start' %}</th>
|
||||
<th class="text-center">{% trans 'Time' %}</th>
|
||||
{% endblock %}
|
||||
|
||||
{% block table_body %}
|
||||
{% for proxy_log in proxy_log_list %}
|
||||
<tr class="gradeX">
|
||||
<td class="text-center"><input type="checkbox" class="cbx-term" value="{{ proxy_log.id }}"></td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'audits:proxy-log-detail' pk=proxy_log.id %}">{{ proxy_log.id }}</a>
|
||||
</td>
|
||||
<td class="text-center">{{ proxy_log.user }}</td>
|
||||
<td class="text-center">{{ proxy_log.asset }}</td>
|
||||
<td class="text-center">{{ proxy_log.system_user }}</td>
|
||||
<td class="text-center">{{ proxy_log.terminal }}</td>
|
||||
<td class="text-center">{{ proxy_log.commands.all|length}}</td>
|
||||
<td class="text-center">
|
||||
{% if proxy_log.is_failed %}
|
||||
<i class="fa fa-times text-danger"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if proxy_log.is_finished %}
|
||||
<td class="text-center">
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a><span class="text-navy"><i class="fa fa-play-circle"></i></span></a>
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="text-center">
|
||||
<a class="btn-term" value="{{ proxy_log.id }}"><i class="fa fa-times text-danger"></i></a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a><span class="text-danger"><i class="fa fa-eye"></i></span></a>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="text-center">{{ proxy_log.date_start }}</td>
|
||||
<td class="text-center">{{ proxy_log.date_finished|timeuntil:proxy_log.date_start }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||
<script>
|
||||
function terminateConnection(data) {
|
||||
function success() {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload()
|
||||
}, 300)
|
||||
}
|
||||
var the_url = "";
|
||||
APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'});
|
||||
}
|
||||
$(document).ready(function() {
|
||||
$('table').DataTable({
|
||||
"searching": false,
|
||||
"paging": false,
|
||||
"bInfo" : false,
|
||||
"order": []
|
||||
});
|
||||
$('.select2').select2();
|
||||
$('#date .input-daterange').datepicker({
|
||||
dateFormat: 'mm/dd/yy',
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
autoclose: true
|
||||
});
|
||||
}).on('click', '.btn-term', function () {
|
||||
var $this = $(this);
|
||||
var proxy_log_id = $this.attr('value');
|
||||
var data = {
|
||||
proxy_log_id: proxy_log_id
|
||||
};
|
||||
terminateConnection(data)
|
||||
}).on('click', '#btn_bulk_update', function () {
|
||||
var data = [];
|
||||
$('.cbx-term:checked').each(function () {
|
||||
data.push({proxy_log_id: $(this).attr('value')})
|
||||
});
|
||||
terminateConnection(data)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Terminal detail' %} </a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'applications:terminal-update' pk=terminal.id %}"><i class="fa fa-edit"></i>Update</a>
|
||||
<a class="btn btn-outline btn-default" href="{% url 'terminal:terminal-update' pk=terminal.id %}"><i class="fa fa-edit"></i>Update</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -48,12 +48,12 @@
|
|||
<td><b>{{ terminal.remote_addr }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'URL to login' %}:</td>
|
||||
<td><b>{{ terminal.url }}</b></td>
|
||||
<td>{% trans 'SSH port' %}:</td>
|
||||
<td><b>{{ terminal.ssh_port }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Terminal type' %}:</td>
|
||||
<td><b>{{ terminal.get_type_display }}</b></td>
|
||||
<td>{% trans 'Http port' %}:</td>
|
||||
<td><b>{{ terminal.http_port }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Date created' %}:</td>
|
||||
|
|
|
@ -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)))
|
||||
|
||||
|
|
|
@ -17,7 +17,11 @@ urlpatterns = [
|
|||
url(r'^(?P<pk>[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<pk>[0-9a-zA-Z\-]+)/$', views.SessionDetailView.as_view(), name='session-detail'),
|
||||
|
||||
# Command view
|
||||
url(r'^command/$', views.CommandListView.as_view(), name='command-list'),
|
||||
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
@ -2,3 +2,4 @@
|
|||
#
|
||||
from .terminal import *
|
||||
from .session import *
|
||||
from .command import *
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue