mirror of https://github.com/jumpserver/jumpserver
[Update] 修改command列表
parent
e7d600ee50
commit
5f6af8c07d
|
@ -46,7 +46,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all">
|
||||
</th>
|
||||
<th class="text-center">{% trans 'Name' %}</th>
|
||||
<th class="text-center">{% trans 'Username' %}</th>
|
||||
|
|
|
@ -146,6 +146,8 @@ class CanUpdateSuperUser(permissions.BasePermission):
|
|||
def has_object_permission(self, request, view, obj):
|
||||
if request.method in ['GET', 'OPTIONS']:
|
||||
return True
|
||||
if str(request.user.id) == str(obj.id):
|
||||
return False
|
||||
if request.user.is_superuser:
|
||||
return True
|
||||
if hasattr(obj, 'is_superuser') and obj.is_superuser:
|
||||
|
|
|
@ -304,7 +304,7 @@ table.dataTable tbody td.selected td i.text-navy {
|
|||
|
||||
div.dataTables_wrapper div.dataTables_filter,
|
||||
.dataTables_length {
|
||||
float: right !important;
|
||||
// float: right !important;
|
||||
}
|
||||
|
||||
div.dataTables_wrapper div.dataTables_filter {
|
||||
|
@ -466,3 +466,11 @@ div.dataTables_wrapper div.dataTables_filter {
|
|||
span.select2-selection__placeholder {
|
||||
line-height: 34px !important;
|
||||
}
|
||||
|
||||
.p-l-5 {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.p-r-5 {
|
||||
padding-right: 5px;
|
||||
}
|
|
@ -567,7 +567,8 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
};
|
||||
var table = ele.DataTable({
|
||||
pageLength: options.pageLength || 15,
|
||||
dom: options.dom || '<"#uc.pull-left">fltr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
|
||||
// dom: options.dom || '<"#uc.pull-left">fltr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
|
||||
dom: options.dom || '<"#uc.pull-left"><"pull-right"<"inline"l><"#fb.inline"><"inline"f><"#fa.inline">>tr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
|
||||
order: options.order || [],
|
||||
buttons: [],
|
||||
columnDefs: columnDefs,
|
||||
|
@ -668,8 +669,6 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
})
|
||||
}
|
||||
}).on('draw', function(){
|
||||
$('#op').html(options.op_html || '');
|
||||
$('#uc').html(options.uc_html || '');
|
||||
$('[data-toggle="popover"]').popover({
|
||||
html: true,
|
||||
placement: 'bottom',
|
||||
|
@ -691,6 +690,11 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
table.rows(index).select()
|
||||
}
|
||||
});
|
||||
}).on("init", function () {
|
||||
$('#op').html(options.op_html || '');
|
||||
$('#uc').html(options.uc_html || '');
|
||||
$('#fb').html(options.fb_html || '');
|
||||
$('#fa').html(options.fa_html || '');
|
||||
});
|
||||
var table_id = table.settings()[0].sTableId;
|
||||
$('#' + table_id + ' .ipt_check_all').on('click', function() {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
!function(a){a.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1}}(jQuery);
|
|
@ -7,6 +7,7 @@ from django.shortcuts import get_object_or_404
|
|||
from django.core.files.storage import default_storage
|
||||
from django.http import HttpResponseNotFound
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from rest_framework.pagination import LimitOffsetPagination
|
||||
from rest_framework import viewsets
|
||||
from rest_framework.response import Response
|
||||
|
@ -39,11 +40,15 @@ class SessionViewSet(BulkModelViewSet):
|
|||
terminal = get_object_or_404(Terminal, id=terminal_id)
|
||||
queryset = queryset.filter(terminal=terminal)
|
||||
return queryset
|
||||
# 解决guacamole更新session时并发导致幽灵会话的问题
|
||||
if self.request.method in ('PATCH', ):
|
||||
queryset = queryset.select_for_update()
|
||||
return queryset
|
||||
|
||||
def get_object(self):
|
||||
# 解决guacamole更新session时并发导致幽灵会话的问题
|
||||
obj = super().get_object()
|
||||
if self.request.method in ('PATCH', ):
|
||||
obj = obj.select_for_update()
|
||||
return obj
|
||||
|
||||
def perform_create(self, serializer):
|
||||
if hasattr(self.request.user, 'terminal'):
|
||||
serializer.validated_data["terminal"] = self.request.user.terminal
|
||||
|
@ -71,14 +76,33 @@ class CommandViewSet(viewsets.ModelViewSet):
|
|||
command_store = get_command_storage()
|
||||
serializer_class = SessionCommandSerializer
|
||||
pagination_class = LimitOffsetPagination
|
||||
permission_classes = (IsOrgAdminOrAppUser | IsAuditor,)
|
||||
filter_fields = ("asset", "system_user", "user", "input")
|
||||
permission_classes = [IsOrgAdminOrAppUser | IsAuditor]
|
||||
filter_fields = [
|
||||
"asset", "system_user", "user", "input", "session",
|
||||
]
|
||||
default_days_ago = 5
|
||||
|
||||
def get_queryset(self):
|
||||
date_from, date_to = self.get_date_range()
|
||||
multi_command_storage = get_multi_command_storage()
|
||||
queryset = multi_command_storage.filter()
|
||||
queryset = multi_command_storage.filter(date_from=date_from, date_to=date_to)
|
||||
return queryset
|
||||
|
||||
def get_filter_fields(self):
|
||||
fields = self.filter_fields
|
||||
fields.extend(["date_from", "date_to"])
|
||||
return fields
|
||||
|
||||
def get_date_range(self):
|
||||
now = timezone.now()
|
||||
days_ago = now - timezone.timedelta(days=self.default_days_ago)
|
||||
default_start_st = days_ago.timestamp()
|
||||
default_end_st = now.timestamp()
|
||||
query_params = self.request.query_params
|
||||
date_from_st = query_params.get("date_from") or default_start_st
|
||||
date_to_st = query_params.get("date_to") or default_end_st
|
||||
return int(date_from_st), int(date_to_st)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data, many=True)
|
||||
if serializer.is_valid():
|
||||
|
|
|
@ -71,9 +71,13 @@ class CommandStore(CommandBase):
|
|||
if not date_to and not session:
|
||||
date_to = date_to_default
|
||||
if date_from is not None:
|
||||
filter_kwargs['timestamp__gte'] = int(date_from.timestamp())
|
||||
if isinstance(date_from, datetime.datetime):
|
||||
date_from = date_from.timestamp()
|
||||
filter_kwargs['timestamp__gte'] = int(date_from)
|
||||
if date_to is not None:
|
||||
filter_kwargs['timestamp__lte'] = int(date_to.timestamp())
|
||||
if isinstance(date_to, datetime.datetime):
|
||||
date_to = date_to.timestamp()
|
||||
filter_kwargs['timestamp__lte'] = int(date_to)
|
||||
|
||||
if user:
|
||||
filter_kwargs["user"] = user
|
||||
|
@ -85,7 +89,6 @@ class CommandStore(CommandBase):
|
|||
filter_kwargs['input__icontains'] = input
|
||||
if session:
|
||||
filter_kwargs['session'] = session
|
||||
|
||||
return filter_kwargs
|
||||
|
||||
def filter(self, date_from=None, date_to=None,
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
{% load static %}
|
||||
{% load common_tags %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet">
|
||||
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
<style>
|
||||
.toggle {
|
||||
cursor: pointer;
|
||||
|
@ -23,6 +20,7 @@
|
|||
|
||||
{% block table_search %}
|
||||
{% endblock %}
|
||||
|
||||
{% block table_container %}
|
||||
<table class="table table-striped table-bordered table-hover" id="command_table" data-page="false" >
|
||||
<thead>
|
||||
|
@ -53,35 +51,60 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hide" id="daterange">
|
||||
<div class="form-group p-l-5" id="date" style="padding-left: 5px">
|
||||
<div class="input-daterange input-group p-l-5" 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;" id="date_from" name="date_from" value="{{ date_from|date:'Y-m-d' }}">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input type="text" class="input-sm form-control" style="width: 100px;" id="date_to" name="date_to" value="{{ date_to|date:'Y-m-d' }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="dropdown-menu search-help">
|
||||
<li><a class="search-item" data-value="user">{% trans 'User' %}</a></li>
|
||||
<li><a class="search-item" data-value="asset">{% trans 'Asset' %}</a></li>
|
||||
<li><a class="search-item" data-value="system_user">{% trans 'System user' %}</a></li>
|
||||
<li><a class="search-item" data-value="command">{% trans 'Command' %}</a></li>
|
||||
<li><a class="search-item" data-value="input">{% trans 'Command' %}</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}" charset="UTF-8"></script>
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.zh-CN.min.js' %}" charset="UTF-8"></script>
|
||||
<script>
|
||||
|
||||
var table;
|
||||
$(document).ready(function () {
|
||||
$('.footable').footable();
|
||||
$('.select2').select2({
|
||||
dropdownAutoWidth : true,
|
||||
width: 'auto'
|
||||
table = initTable().on("init", function () {
|
||||
var dateFromRef = $("#date_from");
|
||||
var dateToRef = $("#date_to");
|
||||
let options = {
|
||||
format: "yyyy-mm-dd",
|
||||
todayBtn: "linked",
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
calendarWeeks: true,
|
||||
autoclose: true,
|
||||
language: navigator.language || "en",
|
||||
};
|
||||
dateFromRef.datepicker(options).on("changeDate", function () {
|
||||
let date = new Date($(this).val() + ' 0:0:0');
|
||||
let url = table.ajax.url();
|
||||
url = setUrlParam(url, "date_from", date.getTime()/1000);
|
||||
table.ajax.url(url);
|
||||
table.ajax.reload();
|
||||
console.log("On change")
|
||||
});
|
||||
dateToRef.datepicker(options).on("changeDate", function () {
|
||||
let date = new Date($(this).val() + ' 23:59:59');
|
||||
let url = table.ajax.url();
|
||||
url = setUrlParam(url, "date_to", date.getTime()/1000);
|
||||
table.ajax.url(url);
|
||||
table.ajax.reload();
|
||||
});
|
||||
});
|
||||
$('#date .input-daterange').datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
todayBtn: "linked",
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
calendarWeeks: true,
|
||||
autoclose: true
|
||||
});
|
||||
initTable();
|
||||
})
|
||||
.on('click', '#btn_bulk_update', function(){
|
||||
var action = $('#slct_bulk_update').val();
|
||||
|
@ -100,13 +123,11 @@ $(document).ready(function () {
|
|||
var offset1 = $('#command_table_filter input').offset();
|
||||
var x = offset1.left;
|
||||
var y = offset1.top;
|
||||
console.log(x, y)
|
||||
var offset = $(".search-help").parent().offset();
|
||||
x -= offset.left;
|
||||
y -= offset.top;
|
||||
x += 18;
|
||||
y += 80;
|
||||
console.log(x, y)
|
||||
$('.search-help').css({"top":y+"px", "left":x+"px", "position": "absolute"});
|
||||
$('.dropdown-menu.search-help').show();
|
||||
})
|
||||
|
@ -149,7 +170,9 @@ $(document).ready(function () {
|
|||
}
|
||||
}).on('click', 'body', function (e) {
|
||||
$('.dropdown-menu.search-help').hide()
|
||||
})
|
||||
}).on('change', '#date_start', function () {
|
||||
console.log("date change")
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
@ -186,7 +209,8 @@ function initTable() {
|
|||
{data: "session"}, {data: "timestamp", width: "160px"},
|
||||
],
|
||||
select: {},
|
||||
op_html: $('#actions').html()
|
||||
op_html: $('#actions').html(),
|
||||
fb_html: $("#daterange").html(),
|
||||
};
|
||||
table = jumpserver.initServerSideDataTable(options);
|
||||
return table
|
||||
|
|
|
@ -1,44 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from django.views.generic import ListView, View
|
||||
from django.conf import settings
|
||||
from django.views.generic import View, TemplateView
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
from django.utils import timezone
|
||||
import time
|
||||
|
||||
from common.mixins import DatetimeSearchMixin
|
||||
from common.permissions import PermissionsMixin, IsOrgAdmin, IsAuditor
|
||||
from ..models import Command
|
||||
from .. import utils
|
||||
from ..backends import get_multi_command_storage
|
||||
|
||||
__all__ = ['CommandListView', 'CommandExportView']
|
||||
common_storage = get_multi_command_storage()
|
||||
|
||||
|
||||
class CommandListView(DatetimeSearchMixin, PermissionsMixin, ListView):
|
||||
model = Command
|
||||
class CommandListView(DatetimeSearchMixin, PermissionsMixin, TemplateView):
|
||||
template_name = "terminal/command_list.html"
|
||||
context_object_name = 'command_list'
|
||||
paginate_by = settings.DISPLAY_PER_PAGE
|
||||
date_from = date_to = None
|
||||
permission_classes = [IsOrgAdmin | IsAuditor]
|
||||
|
||||
def get_queryset(self):
|
||||
filter_kwargs = dict()
|
||||
filter_kwargs['date_from'] = self.date_from
|
||||
filter_kwargs['date_to'] = self.date_to
|
||||
queryset = common_storage.filter(**filter_kwargs)
|
||||
return queryset
|
||||
default_days_ago = 5
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
now = timezone.now()
|
||||
context = {
|
||||
'app': _('Sessions'),
|
||||
'action': _('Command list'),
|
||||
'date_from': self.date_from,
|
||||
'date_to': self.date_to,
|
||||
'date_from': now - timezone.timedelta(days=self.default_days_ago),
|
||||
'date_to': now,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n static %}
|
||||
{% block table_search %}
|
||||
<div class="" style="float: right">
|
||||
<div class="pull-right" >
|
||||
<div class=" btn-group">
|
||||
<button data-toggle="dropdown" class="btn btn-default btn-sm dropdown-toggle">CSV <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -92,23 +92,23 @@ function initTable() {
|
|||
}},
|
||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = "";
|
||||
{#if (rowData.role === 'Admin' && ('{{ request.user.role }}' !== 'Admin')) {#}
|
||||
{# update_btn = '<a class="btn btn-xs disabled btn-info">{% trans "Update" %}</a>';#}
|
||||
{#}#}
|
||||
{#else{#}
|
||||
if (rowData.role === 'Admin' && ('{{ request.user.role }}' !== 'Admin')) {
|
||||
update_btn = '<a class="btn btn-xs disabled btn-info">{% trans "Update" %}</a>';
|
||||
}
|
||||
else{
|
||||
update_btn = '<a href="{% url "users:user-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('00000000-0000-0000-0000-000000000000', cellData);
|
||||
{#}#}
|
||||
}
|
||||
|
||||
var del_btn = "";
|
||||
{#if (rowData.id === 1 || rowData.username === "admin" || rowData.username === "{{ request.user.username }}" || (rowData.role === 'Admin' && ('{{ request.user.role }}' !== 'Admin'))) {#}
|
||||
{# del_btn = '<a class="btn btn-xs btn-danger m-l-xs" disabled>{% trans "Delete" %}</a>'#}
|
||||
{# .replace('{{ DEFAULT_PK }}', cellData)#}
|
||||
{# .replace('99991938', rowData.name);#}
|
||||
{#} else {#}
|
||||
if (rowData.id === 1 || rowData.username === "admin" || rowData.username === "{{ request.user.username }}" || (rowData.role === 'Admin' && ('{{ request.user.role }}' !== 'Admin'))) {
|
||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs" disabled>{% trans "Delete" %}</a>'
|
||||
.replace('{{ DEFAULT_PK }}', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
} else {
|
||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
|
||||
.replace('{{ DEFAULT_PK }}', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
{#}#}
|
||||
}
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}],
|
||||
ajax_url: '{% url "api-users:user-list" %}',
|
||||
|
|
Loading…
Reference in New Issue