mirror of https://github.com/jumpserver/jumpserver
[Update] 支持命令过滤
parent
78936bf9f2
commit
44bf01d4ed
|
@ -4,3 +4,4 @@ from .label import *
|
|||
from .system_user import *
|
||||
from .node import *
|
||||
from .domain import *
|
||||
from .cmd_filter import *
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from rest_framework_bulk import BulkModelViewSet
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from ..hands import IsOrgAdmin
|
||||
from ..models import CommandFilter, CommandFilterRule
|
||||
from .. import serializers
|
||||
|
||||
|
||||
__all__ = ['CommandFilterViewSet', 'CommandFilterRuleViewSet']
|
||||
|
||||
|
||||
class CommandFilterViewSet(BulkModelViewSet):
|
||||
permission_classes = (IsOrgAdmin,)
|
||||
queryset = CommandFilter.objects.all()
|
||||
serializer_class = serializers.CommandFilterSerializer
|
||||
|
||||
|
||||
class CommandFilterRuleViewSet(BulkModelViewSet):
|
||||
permission_classes = (IsOrgAdmin,)
|
||||
serializer_class = serializers.CommandFilterRuleSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
fpk = self.kwargs.get('filter_pk')
|
||||
if not fpk:
|
||||
return CommandFilterRule.objects.none()
|
||||
group = get_object_or_404(CommandFilter, pk=fpk)
|
||||
return group.rules.all().order_by('priority')
|
||||
|
||||
|
|
@ -33,7 +33,8 @@ __all__ = [
|
|||
'SystemUserViewSet', 'SystemUserAuthInfoApi',
|
||||
'SystemUserPushApi', 'SystemUserTestConnectiveApi',
|
||||
'SystemUserAssetsListView', 'SystemUserPushToAssetApi',
|
||||
'SystemUserTestAssetConnectabilityApi',
|
||||
'SystemUserTestAssetConnectabilityApi', 'SystemUserCommandFilterRuleListApi',
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
@ -127,3 +128,16 @@ class SystemUserTestAssetConnectabilityApi(generics.RetrieveAPIView):
|
|||
asset = get_object_or_404(Asset, id=asset_id)
|
||||
task = test_system_user_connectability_a_asset.delay(system_user, asset)
|
||||
return Response({"task": task.id})
|
||||
|
||||
|
||||
class SystemUserCommandFilterRuleListApi(generics.ListAPIView):
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
|
||||
def get_serializer_class(self):
|
||||
from ..serializers import CommandFilterRuleSerializer
|
||||
return CommandFilterRuleSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
pk = self.kwargs.get('pk', None)
|
||||
system_user = get_object_or_404(SystemUser, pk=pk)
|
||||
return system_user.cmd_filter_rules
|
||||
|
|
|
@ -4,3 +4,4 @@ from .asset import *
|
|||
from .label import *
|
||||
from .user import *
|
||||
from .domain import *
|
||||
from .cmd_filter import *
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from orgs.mixins import OrgModelForm
|
||||
from ..models import CommandFilter, CommandFilterRule
|
||||
|
||||
__all__ = ['CommandFilterForm', 'CommandFilterRuleForm']
|
||||
|
||||
|
||||
class CommandFilterForm(OrgModelForm):
|
||||
class Meta:
|
||||
model = CommandFilter
|
||||
fields = ['name', 'comment']
|
||||
|
||||
|
||||
class CommandFilterRuleForm(OrgModelForm):
|
||||
class Meta:
|
||||
model = CommandFilterRule
|
||||
fields = [
|
||||
'filter', 'type', 'content', 'priority', 'action', 'comment'
|
||||
]
|
|
@ -3,8 +3,9 @@
|
|||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from ..models import AdminUser, SystemUser
|
||||
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger
|
||||
from orgs.mixins import OrgModelForm
|
||||
from ..models import AdminUser, SystemUser
|
||||
|
||||
logger = get_logger(__file__)
|
||||
__all__ = [
|
||||
|
@ -85,7 +86,7 @@ class AdminUserForm(PasswordAndKeyAuthForm):
|
|||
}
|
||||
|
||||
|
||||
class SystemUserForm(PasswordAndKeyAuthForm):
|
||||
class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
|
||||
# Admin user assets define, let user select, save it in form not in view
|
||||
auto_generate_key = forms.BooleanField(initial=True, required=False)
|
||||
|
||||
|
@ -136,11 +137,14 @@ class SystemUserForm(PasswordAndKeyAuthForm):
|
|||
fields = [
|
||||
'name', 'username', 'protocol', 'auto_generate_key',
|
||||
'password', 'private_key_file', 'auto_push', 'sudo',
|
||||
'comment', 'shell', 'priority', 'login_mode',
|
||||
'comment', 'shell', 'priority', 'login_mode', 'cmd_filters',
|
||||
]
|
||||
widgets = {
|
||||
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
||||
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
|
||||
'cmd_filters': forms.SelectMultiple(attrs={
|
||||
'class': 'select2', 'data-placeholder': _('Command filter')
|
||||
}),
|
||||
}
|
||||
help_texts = {
|
||||
'name': '* required',
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from .user import AdminUser, SystemUser
|
||||
from .user import *
|
||||
from .label import Label
|
||||
from .cluster import *
|
||||
from .group import *
|
||||
from .domain import *
|
||||
from .node import *
|
||||
from .asset import *
|
||||
from .cmd_filter import *
|
||||
from .utils import *
|
||||
|
|
|
@ -15,7 +15,7 @@ from django.core.cache import cache
|
|||
|
||||
from ..const import ASSET_ADMIN_CONN_CACHE_KEY
|
||||
from .user import AdminUser, SystemUser
|
||||
from orgs.mixins import OrgModelMixin,OrgManager
|
||||
from orgs.mixins import OrgModelMixin, OrgManager
|
||||
|
||||
__all__ = ['Asset']
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orgs.mixins import OrgModelMixin
|
||||
|
||||
|
||||
__all__ = [
|
||||
'CommandFilter', 'CommandFilterRule'
|
||||
]
|
||||
|
||||
|
||||
class CommandFilter(OrgModelMixin):
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
name = models.CharField(max_length=64, verbose_name=_("Name"))
|
||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
||||
comment = models.TextField(blank=True, default='', verbose_name=_("Comment"))
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
date_updated = models.DateTimeField(auto_now=True)
|
||||
created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by'))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class CommandFilterRule(OrgModelMixin):
|
||||
TYPE_REGEX = 'regex'
|
||||
TYPE_COMMAND = 'command'
|
||||
TYPE_CHOICES = (
|
||||
(TYPE_REGEX, _('Regex')),
|
||||
(TYPE_COMMAND, _('Command')),
|
||||
)
|
||||
|
||||
ACTION_DENY = 'deny'
|
||||
ACTION_ACCEPT = 'accept'
|
||||
ACTION_CHOICES = (
|
||||
(ACTION_DENY, _('Deny')),
|
||||
(ACTION_ACCEPT, _('Accept'))
|
||||
)
|
||||
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
filter = models.ForeignKey('CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules')
|
||||
type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type"))
|
||||
priority = models.IntegerField(default=50, verbose_name=_("Priority"), validators=[MinValueValidator(1), MaxValueValidator(100)])
|
||||
content = models.TextField(max_length=1024, verbose_name=_("Content"), help_text=_("One line one command"))
|
||||
action = models.CharField(max_length=16, default=ACTION_DENY, choices=ACTION_CHOICES, verbose_name=_("Action"))
|
||||
comment = models.CharField(max_length=64, blank=True, default='', verbose_name=_("Comment"))
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
date_updated = models.DateTimeField(auto_now=True)
|
||||
created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by'))
|
||||
|
||||
def __str__(self):
|
||||
return '{} % {}'.format(self.type, self.content)
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
|
@ -118,6 +117,7 @@ class SystemUser(AssetUser):
|
|||
sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo'))
|
||||
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
|
||||
login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=AUTO_LOGIN, max_length=10, verbose_name=_('Login mode'))
|
||||
cmd_filters = models.ManyToManyField('CommandFilter', related_name='system_users', verbose_name=_("Command filter"))
|
||||
|
||||
cache_key = "__SYSTEM_USER_CACHED_{}"
|
||||
|
||||
|
@ -163,6 +163,14 @@ class SystemUser(AssetUser):
|
|||
def expire_cache(self):
|
||||
cache.delete(self.cache_key.format(self.id))
|
||||
|
||||
@property
|
||||
def cmd_filter_rules(self):
|
||||
from .cmd_filter import CommandFilterRule
|
||||
rules = CommandFilterRule.objects.filter(
|
||||
filter__in=self.cmd_filters.all()
|
||||
).order_by('priority').distinct()
|
||||
return rules
|
||||
|
||||
@classmethod
|
||||
def get_system_user_by_id_or_cached(cls, sid):
|
||||
cached = cache.get(cls.cache_key.format(sid))
|
||||
|
|
|
@ -7,3 +7,4 @@ from .label import *
|
|||
from .system_user import *
|
||||
from .node import *
|
||||
from .domain import *
|
||||
from .cmd_filter import *
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from rest_framework import serializers
|
||||
|
||||
from common.fields import ChoiceDisplayField
|
||||
from ..models import CommandFilter, CommandFilterRule, SystemUser
|
||||
|
||||
|
||||
class CommandFilterSerializer(serializers.ModelSerializer):
|
||||
rules = serializers.PrimaryKeyRelatedField(queryset=CommandFilterRule.objects.all(), many=True)
|
||||
system_users = serializers.PrimaryKeyRelatedField(queryset=SystemUser.objects.all(), many=True)
|
||||
|
||||
class Meta:
|
||||
model = CommandFilter
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class CommandFilterRuleSerializer(serializers.ModelSerializer):
|
||||
serializer_choice_field = ChoiceDisplayField
|
||||
|
||||
class Meta:
|
||||
model = CommandFilterRule
|
||||
fields = '__all__'
|
|
@ -62,6 +62,10 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
<div id="command-filter-block">
|
||||
<h3>{% trans 'Command filter' %}</h3>
|
||||
{% bootstrap_field form.cmd_filters layout="horizontal" %}
|
||||
</div>
|
||||
<h3>{% trans 'Other' %}</h3>
|
||||
{% bootstrap_field form.sudo layout="horizontal" %}
|
||||
{% bootstrap_field form.shell layout="horizontal" %}
|
||||
|
@ -101,6 +105,7 @@ var need_change_field_login_mode = [
|
|||
function protocolChange() {
|
||||
if ($(protocol_id + " option:selected").text() === 'rdp') {
|
||||
$('.auth-fields').removeClass('hidden');
|
||||
$('#command-filter-block').addClass('hidden');
|
||||
$.each(need_change_field, function (index, value) {
|
||||
$(value).closest('.form-group').addClass('hidden')
|
||||
});
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Select nodes' %}" id="nodes_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for node in nodes %}
|
||||
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.value }}</option>
|
||||
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{% extends '_base_create_update.html' %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block form %}
|
||||
<form id="groupForm" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_field form.name layout="horizontal" %}
|
||||
{% bootstrap_field form.comment layout="horizontal" %}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-2">
|
||||
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
|
||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,168 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
|
||||
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="{% url 'assets:cmd-filter-detail' pk=object.id %}" class="text-center">
|
||||
<i class="fa fa-laptop"></i> {% trans 'Detail' %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li>
|
||||
<a href="{% url 'assets:cmd-filter-rule-list' pk=object.id %}" class="text-center">
|
||||
<i class="fa fa-laptop"></i> {% trans 'Rules' %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:cmd-filter-update' pk=object.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-danger btn-del">
|
||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label"><b>{{ object.name }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr class="no-borders-tr">
|
||||
<td>{% trans 'Name' %}:</td>
|
||||
<td><b>{{ object.name }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Comment' %}:</td>
|
||||
<td><b>{{ object.comment }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Date created' %}:</td>
|
||||
<td><b>{{ object.date_created }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Date updated' %}:</td>
|
||||
<td><b>{{ object.date_updated }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Created by' %}:</td>
|
||||
<td><b>{{ object.created_by }}</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</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 'System users' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table group_edit" id="table-clusters">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Binding to system user' %}" id="system_users_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for system_user in system_users_remain %}
|
||||
<option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="btn-binding-system-users">{% trans 'Confirm' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
{% for system_user in object.system_users.all %}
|
||||
<tr>
|
||||
<td><b class="bdg-system-users" data-gid={{ system_user.id }}>{{ system_user }}</b></td>
|
||||
<td>
|
||||
<button class="btn btn-danger pull-right btn-xs btn-unbound-system-user" data-gid={{ system_user.id }} type="button"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
function updateCMDFilterSystemUsers(system_users) {
|
||||
var the_url = "{% url 'api-assets:cmd-filter-detail' pk=object.id %}";
|
||||
var body = {
|
||||
system_users: Object.assign([], system_users)
|
||||
};
|
||||
var success = function(data) {
|
||||
location.reload();
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PATCH',
|
||||
success: success
|
||||
});
|
||||
}
|
||||
$(document).ready(function () {
|
||||
$(".select2").select2();
|
||||
}).on('click', '#btn-binding-system-users', function () {
|
||||
var origin_system_users = $.map($(".bdg-system-users"), function (s) {
|
||||
return $(s).data('gid')
|
||||
});
|
||||
var new_selected_system_users_id = $.map($("#system_users_selected").select2('data'), function (s) {
|
||||
return s.id;
|
||||
});
|
||||
var system_users = origin_system_users.concat(new_selected_system_users_id);
|
||||
updateCMDFilterSystemUsers(system_users)
|
||||
}).on('click', '.btn-unbound-system-user', function () {
|
||||
var unbound_system_user = $(this).data('gid');
|
||||
var origin_system_users = $.map($(".bdg-system-users"), function (s) {
|
||||
return $(s).data('gid')
|
||||
});
|
||||
var system_users = $.grep(origin_system_users, function (n, i) {
|
||||
return n !== unbound_system_user
|
||||
});
|
||||
updateCMDFilterSystemUsers(system_users)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,79 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n static %}
|
||||
{% block table_search %}{% endblock %}
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-r-5">
|
||||
<a href="{% url 'assets:cmd-filter-create' %}" class="btn btn-sm btn-primary"> {% trans "Create command filter" %} </a>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="cmd_filter_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th class="text-center">{% trans 'Name' %}</th>
|
||||
<th class="text-center">{% trans 'Rules' %}</th>
|
||||
<th class="text-center">{% trans 'System users' %}</th>
|
||||
<th class="text-center">{% trans 'Comment' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#cmd_filter_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url 'assets:cmd-filter-detail' pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
||||
var filters_list_btn = '<a href="{% url "assets:cmd-filter-rule-list" pk=DEFAULT_PK %}">' + cellData.length + '</a>';
|
||||
filters_list_btn = filters_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
|
||||
$(td).html(filters_list_btn);
|
||||
}},
|
||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
||||
var system_users_list_btn = '<a href="{% url "assets:cmd-filter-detail" pk=DEFAULT_PK %}">' + cellData.length + '</a>';
|
||||
system_users_list_btn = system_users_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
|
||||
$(td).html(system_users_list_btn);
|
||||
}},
|
||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:cmd-filter-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-assets:cmd-filter-list" %}',
|
||||
columns: [
|
||||
{data: "id"}, {data: "name" }, {data: "rules" },
|
||||
{data: "system_users" }, {data: "comment"}, {data: "id"}
|
||||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
})
|
||||
.on('click', '.btn-delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $('#cmd_filter_list_table').DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:label-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
}, 3000);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5>{{ action }}</h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<form enctype="multipart/form-data" method="post" class="form-horizontal" action="" >
|
||||
{% csrf_token %}
|
||||
{% if form.non_field_errors %}
|
||||
<div class="alert alert-danger">
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout="horizontal" %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-2">
|
||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,115 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
|
||||
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{% url 'assets:cmd-filter-detail' pk=object.id %}" class="text-center">
|
||||
<i class="fa fa-laptop"></i> {% trans 'Detail' %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="{% url 'assets:cmd-filter-rule-list' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Rules' %} </a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-12" style="padding-left: 0;">
|
||||
<div class="" id="content_start">
|
||||
</div>
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left"><b>{% trans 'Command filter rule list' %}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<div class="uc pull-left m-r-5">
|
||||
<a href="{% url 'assets:cmd-filter-rule-create' filter_pk=object.id %}" class="btn btn-sm btn-primary"> {% trans "Create rule" %} </a>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="cmd_filter_rule_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th class="text-center">{% trans 'Type' %}</th>
|
||||
<th class="text-center">{% trans 'Content' %}</th>
|
||||
<th class="text-center">{% trans 'Priority' %}</th>
|
||||
<th class="text-center">{% trans 'Strategy' %}</th>
|
||||
<th class="text-center">{% trans 'Comment' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#cmd_filter_rule_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:cmd-filter-rule-update" filter_pk=object.id pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-assets:cmd-filter-rule-list" filter_pk=object.id %}',
|
||||
columns: [
|
||||
{data: "id"}, {data: "type.display" }, {data: 'content'}, {data: 'priority'},
|
||||
{data: 'action.display'}, {data: "comment" }, {data: "id"}
|
||||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
})
|
||||
.on('click', '.btn-delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $('#cmd_filter_rule_list_table').DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:cmd-filter-rule-detail" filter_pk=object.id pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
}, 3000);
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -156,44 +156,47 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{# <div class="panel panel-info">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <i class="fa fa-info-circle"></i> {% trans 'Nodes' %}#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <table class="table node_edit" id="add-asset2group">#}
|
||||
{# <tbody>#}
|
||||
{# <form>#}
|
||||
{# <tr>#}
|
||||
{# <td colspan="2" class="no-borders">#}
|
||||
{# <select data-placeholder="{% trans 'Add to node' %}" id="node_selected" class="select2" style="width: 100%" multiple="" tabindex="4">#}
|
||||
{# {% for node in nodes_remain %}#}
|
||||
{# <option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>#}
|
||||
{# {% endfor %}#}
|
||||
{# </select>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# <tr>#}
|
||||
{# <td colspan="2" class="no-borders">#}
|
||||
{# <button type="button" class="btn btn-info btn-sm" id="btn-add-to-node">{% trans 'Confirm' %}</button>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# </form>#}
|
||||
{##}
|
||||
{# {% for node in system_user.nodes.all %}#}
|
||||
{# <tr>#}
|
||||
{# <td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td>#}
|
||||
{# <td>#}
|
||||
{# <button class="btn btn-danger pull-right btn-xs btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# {% endfor %}#}
|
||||
{# </tbody>#}
|
||||
{# </table>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
</div>
|
||||
</div>
|
||||
{% if system_user.protocol != 'rdp' %}
|
||||
<div class="col-sm-4" style="padding-left: 0; padding-right: 0">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Command filter' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Binding command filters' %}" id="command_filters_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for cf in cmd_filters_remain %}
|
||||
<option value="{{ cf.id }}" id="opt_{{ cf.id }}" >{{ cf }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<button type="button" class="btn btn-info btn-sm" id="btn-binding-command-filters">{% trans 'Confirm' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
{% for cf in object.cmd_filters.all %}
|
||||
<tr>
|
||||
<td><b class="bdg-command-filters" data-gid={{ cf.id }}>{{ cf }}</b></td>
|
||||
<td>
|
||||
<button class="btn btn-danger pull-right btn-xs btn-unbound-command-filter" data-gid={{ cf.id }} type="button"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -201,27 +204,13 @@
|
|||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
function updateSystemUserNode(nodes) {
|
||||
function updateCommandFilters(command_filters) {
|
||||
var the_url = "{% url 'api-assets:system-user-detail' pk=system_user.id %}";
|
||||
var body = {
|
||||
nodes: Object.assign([], nodes)
|
||||
cmd_filters: Object.assign([], command_filters)
|
||||
};
|
||||
var success = function(data) {
|
||||
// remove all the selected groups from select > option and rendered ul element;
|
||||
$('.select2-selection__rendered').empty();
|
||||
$('#node_selected').val('');
|
||||
$.map(jumpserver.nodes_selected, function(node_name, index) {
|
||||
$('#opt_' + index).remove();
|
||||
// change tr html of user groups.
|
||||
$('.node_edit tbody').append(
|
||||
'<tr>' +
|
||||
'<td><b class="bdg_node" data-gid="' + index + '">' + node_name + '</b></td>' +
|
||||
'<td><button class="btn btn-danger btn-xs pull-right btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||
'</tr>'
|
||||
)
|
||||
});
|
||||
// clear jumpserver.groups_selected
|
||||
jumpserver.nodes_selected = {};
|
||||
location.reload();
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
|
@ -229,21 +218,12 @@ function updateSystemUserNode(nodes) {
|
|||
success: success
|
||||
});
|
||||
}
|
||||
jumpserver.nodes_selected = {};
|
||||
$(document).ready(function () {
|
||||
if($('#id_protocol_type').text() === 'rdp'){
|
||||
$('.only-ssh').addClass('hidden')
|
||||
}
|
||||
$(".panel-body .table tr:visible:first").addClass('no-borders-tr');
|
||||
$('.select2').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.nodes_selected[data.id];
|
||||
});
|
||||
})
|
||||
.on('click', '#btn-auto-push', function () {
|
||||
var checked = $(this).prop('checked');
|
||||
|
@ -255,33 +235,6 @@ $(document).ready(function () {
|
|||
url: the_url,
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
})
|
||||
.on('click', '#btn-add-to-node', function() {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var nodes = $('.bdg_node').map(function() {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
$.map(jumpserver.nodes_selected, function(value, index) {
|
||||
nodes.push(index);
|
||||
});
|
||||
updateSystemUserNode(nodes);
|
||||
})
|
||||
.on('click', '.btn-remove-from-node', function() {
|
||||
var $this = $(this);
|
||||
var $tr = $this.closest('tr');
|
||||
var $badge = $tr.find('.bdg_node');
|
||||
var gid = $badge.data('gid');
|
||||
var node_name = $badge.html() || $badge.text();
|
||||
$('#groups_selected').append(
|
||||
'<option value="' + gid + '" id="opt_' + gid + '">' + node_name + '</option>'
|
||||
);
|
||||
$tr.remove();
|
||||
var nodes = $('.bdg_node').map(function () {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
updateSystemUserNode(nodes);
|
||||
}).on('click', '.btn-del', function () {
|
||||
var $this = $(this);
|
||||
var name = "{{ system_user.name}}";
|
||||
|
@ -317,25 +270,24 @@ $(document).ready(function () {
|
|||
success: success,
|
||||
flash_message: false
|
||||
});
|
||||
}).on('click', '.btn-clear-auth', function () {
|
||||
var the_url = '{% url "api-assets:system-user-auth-info" pk=system_user.id %}';
|
||||
var name = '{{ system_user.name }}';
|
||||
swal({
|
||||
title: "{% trans 'Are you sure to remove authentication information for the system user ?' %}",
|
||||
text: " [" + name + "] ",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonText: "{% trans 'Cancel' %}",
|
||||
confirmButtonColor: "#ed5565",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: true
|
||||
}, function () {
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
method: 'DELETE',
|
||||
success_message: "{% trans 'Clear auth' %}" + " {% trans 'success' %}"
|
||||
});
|
||||
}).on('click', '#btn-binding-command-filters', function () {
|
||||
var new_selected_cmd_filters = $.map($('#command_filters_selected').select2('data'), function (i) {
|
||||
return i.id;
|
||||
});
|
||||
var origin_cmd_filters = $.map($(".bdg-command-filters"), function (s) {
|
||||
return $(s).data('gid')
|
||||
});
|
||||
var command_filters = new_selected_cmd_filters.concat(origin_cmd_filters);
|
||||
updateCommandFilters(command_filters)
|
||||
}).on('click', '.btn-unbound-command-filter', function () {
|
||||
var unbound_command_filter = $(this).data('gid');
|
||||
var origin_command_filters = $.map($(".bdg-command-filters"), function (s) {
|
||||
return $(s).data('gid')
|
||||
});
|
||||
var command_filters = $.grep(origin_command_filters, function (n, i) {
|
||||
return n !== unbound_command_filter
|
||||
});
|
||||
updateCommandFilters(command_filters)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
# coding:utf-8
|
||||
from django.urls import path
|
||||
from .. import api
|
||||
from rest_framework_nested import routers
|
||||
# from rest_framework.routers import DefaultRouter
|
||||
from rest_framework_bulk.routes import BulkRouter
|
||||
|
||||
from .. import api
|
||||
|
||||
app_name = 'assets'
|
||||
|
||||
router = BulkRouter()
|
||||
|
@ -13,6 +16,11 @@ router.register(r'labels', api.LabelViewSet, 'label')
|
|||
router.register(r'nodes', api.NodeViewSet, 'node')
|
||||
router.register(r'domain', api.DomainViewSet, 'domain')
|
||||
router.register(r'gateway', api.GatewayViewSet, 'gateway')
|
||||
router.register(r'cmd-filter', api.CommandFilterViewSet, 'cmd-filter')
|
||||
|
||||
cmd_filter_router = routers.NestedDefaultRouter(router, r'cmd-filter', lookup='filter')
|
||||
cmd_filter_router.register(r'rules', api.CommandFilterRuleViewSet, 'cmd-filter-rule')
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('assets-bulk/', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
|
||||
|
@ -42,6 +50,9 @@ urlpatterns = [
|
|||
path('system-user/<uuid:pk>/connective/',
|
||||
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
|
||||
|
||||
path('system-user/<uuid:pk>/cmd-filter-rules/',
|
||||
api.SystemUserCommandFilterRuleListApi.as_view(), name='system-user-cmd-filter-rule-list'),
|
||||
|
||||
path('nodes/<uuid:pk>/children/',
|
||||
api.NodeChildrenApi.as_view(), name='node-children'),
|
||||
path('nodes/children/', api.NodeChildrenApi.as_view(), name='node-children-2'),
|
||||
|
@ -64,5 +75,5 @@ urlpatterns = [
|
|||
api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
urlpatterns += router.urls + cmd_filter_router.urls
|
||||
|
||||
|
|
|
@ -49,4 +49,12 @@ urlpatterns = [
|
|||
|
||||
path('domain/<uuid:pk>/gateway/create/', views.DomainGatewayCreateView.as_view(), name='domain-gateway-create'),
|
||||
path('domain/gateway/<uuid:pk>/update/', views.DomainGatewayUpdateView.as_view(), name='domain-gateway-update'),
|
||||
|
||||
path('cmd-filter/', views.CommandFilterListView.as_view(), name='cmd-filter-list'),
|
||||
path('cmd-filter/create/', views.CommandFilterCreateView.as_view(), name='cmd-filter-create'),
|
||||
path('cmd-filter/<uuid:pk>/update/', views.CommandFilterUpdateView.as_view(), name='cmd-filter-update'),
|
||||
path('cmd-filter/<uuid:pk>/', views.CommandFilterDetailView.as_view(), name='cmd-filter-detail'),
|
||||
path('cmd-filter/<uuid:pk>/rule/', views.CommandFilterRuleListView.as_view(), name='cmd-filter-rule-list'),
|
||||
path('cmd-filter/<uuid:filter_pk>/rule/create/', views.CommandFilterRuleCreateView.as_view(), name='cmd-filter-rule-create'),
|
||||
path('cmd-filter/<uuid:filter_pk>/rule/<uuid:pk>/update/', views.CommandFilterRuleUpdateView.as_view(), name='cmd-filter-rule-update'),
|
||||
]
|
||||
|
|
|
@ -4,3 +4,4 @@ from .system_user import *
|
|||
from .admin_user import *
|
||||
from .label import *
|
||||
from .domain import *
|
||||
from .cmd_filter import *
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from django.views.generic import TemplateView, CreateView, \
|
||||
UpdateView, DeleteView, DetailView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.urls import reverse_lazy
|
||||
from django.shortcuts import get_object_or_404, reverse
|
||||
|
||||
from common.permissions import AdminUserRequiredMixin
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from ..models import CommandFilter, CommandFilterRule, SystemUser
|
||||
from ..forms import CommandFilterForm, CommandFilterRuleForm
|
||||
|
||||
|
||||
__all__ = (
|
||||
"CommandFilterListView", "CommandFilterCreateView",
|
||||
"CommandFilterUpdateView",
|
||||
"CommandFilterRuleListView", "CommandFilterRuleCreateView",
|
||||
"CommandFilterRuleUpdateView", "CommandFilterDetailView",
|
||||
)
|
||||
|
||||
|
||||
class CommandFilterListView(AdminUserRequiredMixin, TemplateView):
|
||||
template_name = 'assets/cmd_filter_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Command filter list'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterCreateView(AdminUserRequiredMixin, CreateView):
|
||||
model = CommandFilter
|
||||
template_name = 'assets/cmd_filter_create_update.html'
|
||||
form_class = CommandFilterForm
|
||||
success_url = reverse_lazy('assets:cmd-filter-list')
|
||||
success_message = create_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Create command filter'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||
model = CommandFilter
|
||||
template_name = 'assets/cmd_filter_create_update.html'
|
||||
form_class = CommandFilterForm
|
||||
success_url = reverse_lazy('assets:cmd-filter-list')
|
||||
success_message = update_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Update command filter'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterDetailView(AdminUserRequiredMixin, DetailView):
|
||||
model = CommandFilter
|
||||
template_name = 'assets/cmd_filter_detail.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
system_users_remain = SystemUser.objects\
|
||||
.exclude(cmd_filters=self.object)\
|
||||
.exclude(protocol='rdp')
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Command filter detail'),
|
||||
'system_users_remain': system_users_remain
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterRuleListView(AdminUserRequiredMixin, SingleObjectMixin, TemplateView):
|
||||
template_name = 'assets/cmd_filter_rule_list.html'
|
||||
model = CommandFilter
|
||||
object = None
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object(queryset=self.model.objects.all())
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Command filter rule list'),
|
||||
'object': self.get_object()
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterRuleCreateView(AdminUserRequiredMixin, CreateView):
|
||||
template_name = 'assets/cmd_filter_rule_create_update.html'
|
||||
model = CommandFilterRule
|
||||
form_class = CommandFilterRuleForm
|
||||
success_message = create_success_msg
|
||||
cmd_filter = None
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('assets:cmd-filter-rule-list', kwargs={
|
||||
'pk': self.cmd_filter.id
|
||||
})
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class=form_class)
|
||||
form['filter'].initial = self.cmd_filter
|
||||
form['filter'].field.widget.attrs['readonly'] = 1
|
||||
return form
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
filter_pk = self.kwargs.get('filter_pk')
|
||||
self.cmd_filter = get_object_or_404(CommandFilter, pk=filter_pk)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Create command filter rule'),
|
||||
'object': self.cmd_filter,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class CommandFilterRuleUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||
template_name = 'assets/cmd_filter_rule_create_update.html'
|
||||
model = CommandFilterRule
|
||||
form_class = CommandFilterRuleForm
|
||||
success_message = create_success_msg
|
||||
cmd_filter = None
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('assets:cmd-filter-rule-list', kwargs={
|
||||
'pk': self.cmd_filter.id
|
||||
})
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class=form_class)
|
||||
form['filter'].initial = self.cmd_filter
|
||||
form['filter'].field.widget.attrs['readonly'] = 1
|
||||
return form
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
filter_pk = self.kwargs.get('filter_pk')
|
||||
self.cmd_filter = get_object_or_404(CommandFilter, pk=filter_pk)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Update command filter rule'),
|
||||
'object': self.cmd_filter,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
|
@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView
|
|||
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from ..forms import SystemUserForm
|
||||
from ..models import SystemUser, Node
|
||||
from ..models import SystemUser, Node, CommandFilter
|
||||
from common.permissions import AdminUserRequiredMixin
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
|
|||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('System user detail'),
|
||||
'nodes_remain': Node.objects.exclude(systemuser=self.object)
|
||||
'cmd_filters_remain': CommandFilter.objects.exclude(system_users=self.object)
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -86,3 +86,21 @@ class FormEncryptCharField(FormEncryptMixin, forms.CharField):
|
|||
|
||||
class FormEncryptDictField(FormEncryptMixin, FormDictField):
|
||||
pass
|
||||
|
||||
|
||||
class ChoiceDisplayField(serializers.ChoiceField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ChoiceDisplayField, self).__init__(*args, **kwargs)
|
||||
self.choice_strings_to_display = {
|
||||
six.text_type(key): value for key, value in self.choices.items()
|
||||
}
|
||||
|
||||
def to_representation(self, value):
|
||||
if value is None:
|
||||
return value
|
||||
return {
|
||||
'value': self.choice_strings_to_values.get(six.text_type(value),
|
||||
value),
|
||||
'display': self.choice_strings_to_display.get(six.text_type(value),
|
||||
value),
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Jumpserver 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-09-07 12:00+0800\n"
|
||||
"POT-Creation-Date: 2018-10-10 15:11+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
|
||||
|
@ -33,7 +33,7 @@ msgstr "更新节点资产硬件信息: {}"
|
|||
msgid "Test if the assets under the node are connectable: {}"
|
||||
msgstr "测试节点下资产是否可连接: {}"
|
||||
|
||||
#: assets/forms/asset.py:27 assets/models/asset.py:82 assets/models/user.py:113
|
||||
#: assets/forms/asset.py:27 assets/models/asset.py:82 assets/models/user.py:112
|
||||
#: assets/templates/assets/asset_detail.html:183
|
||||
#: assets/templates/assets/asset_detail.html:191
|
||||
#: assets/templates/assets/system_user_asset.html:94 perms/models.py:32
|
||||
|
@ -42,7 +42,7 @@ msgstr "节点管理"
|
|||
|
||||
#: assets/forms/asset.py:30 assets/forms/asset.py:69 assets/forms/asset.py:112
|
||||
#: assets/forms/asset.py:116 assets/models/asset.py:87
|
||||
#: assets/models/cluster.py:19 assets/models/user.py:73
|
||||
#: assets/models/cluster.py:19 assets/models/user.py:72
|
||||
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:24
|
||||
#: xpack/plugins/orgs/templates/orgs/org_list.html:18
|
||||
msgid "Admin user"
|
||||
|
@ -129,11 +129,14 @@ msgstr "资产"
|
|||
msgid "Password should not contain special characters"
|
||||
msgstr "不能包含特殊字符"
|
||||
|
||||
#: assets/forms/domain.py:59 assets/forms/user.py:79 assets/forms/user.py:142
|
||||
#: assets/forms/domain.py:59 assets/forms/user.py:80 assets/forms/user.py:143
|
||||
#: assets/models/base.py:22 assets/models/cluster.py:18
|
||||
#: assets/models/domain.py:18 assets/models/group.py:20
|
||||
#: assets/models/label.py:18 assets/templates/assets/admin_user_detail.html:56
|
||||
#: assets/models/cmd_filter.py:19 assets/models/domain.py:18
|
||||
#: assets/models/group.py:20 assets/models/label.py:18
|
||||
#: assets/templates/assets/admin_user_detail.html:56
|
||||
#: assets/templates/assets/admin_user_list.html:26
|
||||
#: assets/templates/assets/cmd_filter_detail.html:61
|
||||
#: assets/templates/assets/cmd_filter_list.html:14
|
||||
#: assets/templates/assets/domain_detail.html:56
|
||||
#: assets/templates/assets/domain_gateway_list.html:56
|
||||
#: assets/templates/assets/domain_list.html:25
|
||||
|
@ -162,7 +165,7 @@ msgstr "不能包含特殊字符"
|
|||
msgid "Name"
|
||||
msgstr "名称"
|
||||
|
||||
#: assets/forms/domain.py:60 assets/forms/user.py:80 assets/forms/user.py:143
|
||||
#: assets/forms/domain.py:60 assets/forms/user.py:81 assets/forms/user.py:144
|
||||
#: assets/models/base.py:23 assets/templates/assets/admin_user_detail.html:60
|
||||
#: assets/templates/assets/admin_user_list.html:27
|
||||
#: assets/templates/assets/domain_gateway_list.html:60
|
||||
|
@ -179,11 +182,11 @@ msgstr "名称"
|
|||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
#: assets/forms/user.py:24
|
||||
#: assets/forms/user.py:25
|
||||
msgid "Password or private key passphrase"
|
||||
msgstr "密码或密钥密码"
|
||||
|
||||
#: assets/forms/user.py:25 assets/models/base.py:24 common/forms.py:104
|
||||
#: assets/forms/user.py:26 assets/models/base.py:24 common/forms.py:104
|
||||
#: users/forms.py:17 users/forms.py:35 users/forms.py:47
|
||||
#: users/templates/users/login.html:65
|
||||
#: users/templates/users/reset_password.html:53
|
||||
|
@ -195,33 +198,39 @@ msgstr "密码或密钥密码"
|
|||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: assets/forms/user.py:28 users/models/user.py:78
|
||||
#: assets/forms/user.py:29 users/models/user.py:78
|
||||
msgid "Private key"
|
||||
msgstr "ssh私钥"
|
||||
|
||||
#: assets/forms/user.py:38
|
||||
#: assets/forms/user.py:39
|
||||
msgid "Invalid private key"
|
||||
msgstr "ssh密钥不合法"
|
||||
|
||||
#: assets/forms/user.py:47
|
||||
#: assets/forms/user.py:48
|
||||
msgid "Password and private key file must be input one"
|
||||
msgstr "密码和私钥, 必须输入一个"
|
||||
|
||||
#: assets/forms/user.py:128
|
||||
#: assets/forms/user.py:129
|
||||
msgid "* Automatic login mode, must fill in the username."
|
||||
msgstr "自动登录模式,必须填写用户名"
|
||||
|
||||
#: assets/forms/user.py:148
|
||||
#: assets/forms/user.py:146 assets/models/user.py:120
|
||||
#: assets/templates/assets/_system_user.html:66
|
||||
#: assets/templates/assets/system_user_detail.html:165
|
||||
msgid "Command filter"
|
||||
msgstr "命令过滤器"
|
||||
|
||||
#: assets/forms/user.py:152
|
||||
msgid "Auto push system user to asset"
|
||||
msgstr "自动推送系统用户到资产"
|
||||
|
||||
#: assets/forms/user.py:149
|
||||
#: assets/forms/user.py:153
|
||||
msgid ""
|
||||
"High level will be using login asset as default, if user was granted more "
|
||||
"than 2 system user"
|
||||
msgstr "高优先级的系统用户将会作为默认登录用户"
|
||||
|
||||
#: assets/forms/user.py:151
|
||||
#: assets/forms/user.py:155
|
||||
msgid ""
|
||||
"If you choose manual login mode, you do not need to fill in the username and "
|
||||
"password."
|
||||
|
@ -257,7 +266,7 @@ msgid "Hostname"
|
|||
msgstr "主机名"
|
||||
|
||||
#: assets/models/asset.py:74 assets/models/domain.py:49
|
||||
#: assets/models/user.py:116
|
||||
#: assets/models/user.py:115
|
||||
#: assets/templates/assets/domain_gateway_list.html:59
|
||||
#: assets/templates/assets/system_user_detail.html:70
|
||||
#: assets/templates/assets/system_user_list.html:31
|
||||
|
@ -271,8 +280,9 @@ msgstr "协议"
|
|||
msgid "Platform"
|
||||
msgstr "系统平台"
|
||||
|
||||
#: assets/models/asset.py:83 assets/models/domain.py:52
|
||||
#: assets/models/label.py:21 assets/templates/assets/asset_detail.html:105
|
||||
#: assets/models/asset.py:83 assets/models/cmd_filter.py:20
|
||||
#: assets/models/domain.py:52 assets/models/label.py:21
|
||||
#: assets/templates/assets/asset_detail.html:105
|
||||
#: assets/templates/assets/user_asset_list.html:169
|
||||
msgid "Is active"
|
||||
msgstr "激活"
|
||||
|
@ -349,9 +359,11 @@ msgid "Labels"
|
|||
msgstr "标签管理"
|
||||
|
||||
#: assets/models/asset.py:126 assets/models/base.py:30
|
||||
#: assets/models/cluster.py:28 assets/models/group.py:21
|
||||
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:24
|
||||
#: assets/models/cmd_filter.py:54 assets/models/group.py:21
|
||||
#: assets/templates/assets/admin_user_detail.html:68
|
||||
#: assets/templates/assets/asset_detail.html:117
|
||||
#: assets/templates/assets/cmd_filter_detail.html:77
|
||||
#: assets/templates/assets/domain_detail.html:72
|
||||
#: assets/templates/assets/system_user_detail.html:100
|
||||
#: ops/templates/ops/adhoc_detail.html:86 orgs/models.py:15 perms/models.py:37
|
||||
|
@ -363,6 +375,7 @@ msgstr "创建者"
|
|||
#: assets/models/asset.py:129 assets/models/cluster.py:26
|
||||
#: assets/models/domain.py:21 assets/models/group.py:22
|
||||
#: assets/models/label.py:24 assets/templates/assets/admin_user_detail.html:64
|
||||
#: assets/templates/assets/cmd_filter_detail.html:69
|
||||
#: assets/templates/assets/domain_detail.html:68
|
||||
#: assets/templates/assets/system_user_detail.html:96
|
||||
#: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:63
|
||||
|
@ -375,11 +388,15 @@ msgid "Date created"
|
|||
msgstr "创建日期"
|
||||
|
||||
#: assets/models/asset.py:131 assets/models/base.py:27
|
||||
#: assets/models/cluster.py:29 assets/models/domain.py:19
|
||||
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:21
|
||||
#: assets/models/cmd_filter.py:51 assets/models/domain.py:19
|
||||
#: assets/models/domain.py:51 assets/models/group.py:23
|
||||
#: assets/models/label.py:22 assets/templates/assets/admin_user_detail.html:72
|
||||
#: assets/templates/assets/admin_user_list.html:32
|
||||
#: assets/templates/assets/asset_detail.html:125
|
||||
#: assets/templates/assets/cmd_filter_detail.html:65
|
||||
#: assets/templates/assets/cmd_filter_list.html:17
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:62
|
||||
#: assets/templates/assets/domain_detail.html:76
|
||||
#: assets/templates/assets/domain_gateway_list.html:61
|
||||
#: assets/templates/assets/domain_list.html:28
|
||||
|
@ -466,6 +483,77 @@ msgstr "北京电信"
|
|||
msgid "BGP full netcom"
|
||||
msgstr "BGP全网通"
|
||||
|
||||
#: assets/models/cmd_filter.py:34
|
||||
msgid "Regex"
|
||||
msgstr "正则表达式"
|
||||
|
||||
#: assets/models/cmd_filter.py:35 terminal/models.py:139
|
||||
#: terminal/templates/terminal/command_list.html:55
|
||||
#: terminal/templates/terminal/command_list.html:71
|
||||
#: terminal/templates/terminal/session_detail.html:48
|
||||
#: terminal/templates/terminal/session_list.html:77
|
||||
msgid "Command"
|
||||
msgstr "命令"
|
||||
|
||||
#: assets/models/cmd_filter.py:41
|
||||
msgid "Deny"
|
||||
msgstr "拒绝"
|
||||
|
||||
#: assets/models/cmd_filter.py:42
|
||||
#: terminal/templates/terminal/terminal_list.html:76
|
||||
msgid "Accept"
|
||||
msgstr "接受"
|
||||
|
||||
#: assets/models/cmd_filter.py:46
|
||||
msgid "Filter"
|
||||
msgstr "过滤器"
|
||||
|
||||
#: assets/models/cmd_filter.py:47
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:58
|
||||
#: audits/templates/audits/login_log_list.html:50
|
||||
#: common/templates/common/terminal_setting.html:73
|
||||
#: common/templates/common/terminal_setting.html:91
|
||||
msgid "Type"
|
||||
msgstr "类型"
|
||||
|
||||
#: assets/models/cmd_filter.py:48 assets/models/user.py:114
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:60
|
||||
msgid "Priority"
|
||||
msgstr "优先级"
|
||||
|
||||
#: assets/models/cmd_filter.py:49
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:59
|
||||
msgid "Content"
|
||||
msgstr "内容"
|
||||
|
||||
#: assets/models/cmd_filter.py:49
|
||||
msgid "One line one command"
|
||||
msgstr "每行一个命令"
|
||||
|
||||
#: assets/models/cmd_filter.py:50
|
||||
#: assets/templates/assets/admin_user_list.html:33
|
||||
#: assets/templates/assets/asset_list.html:97
|
||||
#: assets/templates/assets/cmd_filter_list.html:18
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:63
|
||||
#: assets/templates/assets/domain_gateway_list.html:62
|
||||
#: assets/templates/assets/domain_list.html:29
|
||||
#: assets/templates/assets/label_list.html:17
|
||||
#: assets/templates/assets/system_user_asset.html:53
|
||||
#: assets/templates/assets/system_user_list.html:38 audits/models.py:37
|
||||
#: audits/templates/audits/operate_log_list.html:41
|
||||
#: audits/templates/audits/operate_log_list.html:67
|
||||
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64
|
||||
#: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42
|
||||
#: perms/templates/perms/asset_permission_list.html:60
|
||||
#: terminal/templates/terminal/session_list.html:81
|
||||
#: terminal/templates/terminal/terminal_list.html:36
|
||||
#: users/templates/users/user_group_list.html:15
|
||||
#: users/templates/users/user_list.html:29
|
||||
#: xpack/plugins/orgs/templates/orgs/org_list.html:23
|
||||
#: xpack/templates/orgs/org_list.html:15
|
||||
msgid "Action"
|
||||
msgstr "动作"
|
||||
|
||||
#: assets/models/domain.py:59 assets/templates/assets/domain_detail.html:21
|
||||
#: assets/templates/assets/domain_detail.html:64
|
||||
#: assets/templates/assets/domain_gateway_list.html:21
|
||||
|
@ -520,15 +608,15 @@ msgstr "分类"
|
|||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: assets/models/user.py:109
|
||||
#: assets/models/user.py:108
|
||||
msgid "Automatic login"
|
||||
msgstr "自动登录"
|
||||
|
||||
#: assets/models/user.py:110
|
||||
#: assets/models/user.py:109
|
||||
msgid "Manually login"
|
||||
msgstr "手动登录"
|
||||
|
||||
#: assets/models/user.py:114
|
||||
#: assets/models/user.py:113
|
||||
#: assets/templates/assets/_asset_group_bulk_update_modal.html:11
|
||||
#: assets/templates/assets/system_user_asset.html:21
|
||||
#: assets/templates/assets/system_user_detail.html:22
|
||||
|
@ -536,41 +624,40 @@ msgstr "手动登录"
|
|||
#: assets/views/admin_user.py:63 assets/views/admin_user.py:78
|
||||
#: assets/views/admin_user.py:102 assets/views/asset.py:53
|
||||
#: assets/views/asset.py:92 assets/views/asset.py:136 assets/views/asset.py:153
|
||||
#: assets/views/asset.py:177 assets/views/domain.py:29
|
||||
#: assets/views/domain.py:45 assets/views/domain.py:61
|
||||
#: assets/views/domain.py:74 assets/views/domain.py:98
|
||||
#: assets/views/domain.py:126 assets/views/domain.py:145
|
||||
#: assets/views/label.py:26 assets/views/label.py:42 assets/views/label.py:58
|
||||
#: assets/views/system_user.py:28 assets/views/system_user.py:44
|
||||
#: assets/views/system_user.py:60 assets/views/system_user.py:74
|
||||
#: templates/_nav.html:19
|
||||
#: assets/views/asset.py:177 assets/views/cmd_filter.py:30
|
||||
#: assets/views/cmd_filter.py:46 assets/views/cmd_filter.py:62
|
||||
#: assets/views/cmd_filter.py:78 assets/views/cmd_filter.py:97
|
||||
#: assets/views/cmd_filter.py:130 assets/views/cmd_filter.py:163
|
||||
#: assets/views/domain.py:29 assets/views/domain.py:45
|
||||
#: assets/views/domain.py:61 assets/views/domain.py:74
|
||||
#: assets/views/domain.py:98 assets/views/domain.py:126
|
||||
#: assets/views/domain.py:145 assets/views/label.py:26 assets/views/label.py:42
|
||||
#: assets/views/label.py:58 assets/views/system_user.py:28
|
||||
#: assets/views/system_user.py:44 assets/views/system_user.py:60
|
||||
#: assets/views/system_user.py:74 templates/_nav.html:19
|
||||
msgid "Assets"
|
||||
msgstr "资产管理"
|
||||
|
||||
#: assets/models/user.py:115
|
||||
msgid "Priority"
|
||||
msgstr "优先级"
|
||||
|
||||
#: assets/models/user.py:117 assets/templates/assets/_system_user.html:59
|
||||
#: assets/models/user.py:116 assets/templates/assets/_system_user.html:59
|
||||
#: assets/templates/assets/system_user_detail.html:122
|
||||
#: assets/templates/assets/system_user_update.html:10
|
||||
msgid "Auto push"
|
||||
msgstr "自动推送"
|
||||
|
||||
#: assets/models/user.py:118 assets/templates/assets/system_user_detail.html:74
|
||||
#: assets/models/user.py:117 assets/templates/assets/system_user_detail.html:74
|
||||
msgid "Sudo"
|
||||
msgstr "Sudo"
|
||||
|
||||
#: assets/models/user.py:119 assets/templates/assets/system_user_detail.html:79
|
||||
#: assets/models/user.py:118 assets/templates/assets/system_user_detail.html:79
|
||||
msgid "Shell"
|
||||
msgstr "Shell"
|
||||
|
||||
#: assets/models/user.py:120 assets/templates/assets/system_user_detail.html:66
|
||||
#: assets/models/user.py:119 assets/templates/assets/system_user_detail.html:66
|
||||
#: assets/templates/assets/system_user_list.html:32
|
||||
msgid "Login mode"
|
||||
msgstr "登录模式"
|
||||
|
||||
#: assets/models/user.py:181 assets/templates/assets/user_asset_list.html:167
|
||||
#: assets/models/user.py:189 assets/templates/assets/user_asset_list.html:167
|
||||
#: audits/models.py:19 audits/templates/audits/ftp_log_list.html:49
|
||||
#: audits/templates/audits/ftp_log_list.html:72 perms/forms.py:40
|
||||
#: perms/models.py:33 perms/models.py:81
|
||||
|
@ -648,6 +735,8 @@ msgid "Select Asset"
|
|||
msgstr "选择资产"
|
||||
|
||||
#: assets/templates/assets/_asset_group_bulk_update_modal.html:21
|
||||
#: assets/templates/assets/cmd_filter_detail.html:89
|
||||
#: assets/templates/assets/cmd_filter_list.html:16
|
||||
#: assets/templates/assets/user_asset_list.html:48
|
||||
#: users/templates/users/user_granted_asset.html:47
|
||||
msgid "System users"
|
||||
|
@ -708,7 +797,7 @@ msgstr "认证"
|
|||
msgid "Auto generate key"
|
||||
msgstr "自动生成密钥"
|
||||
|
||||
#: assets/templates/assets/_system_user.html:65
|
||||
#: assets/templates/assets/_system_user.html:69
|
||||
#: assets/templates/assets/asset_create.html:60
|
||||
#: assets/templates/assets/asset_update.html:64
|
||||
#: assets/templates/assets/gateway_create_update.html:53
|
||||
|
@ -717,11 +806,13 @@ msgstr "自动生成密钥"
|
|||
msgid "Other"
|
||||
msgstr "其它"
|
||||
|
||||
#: assets/templates/assets/_system_user.html:71
|
||||
#: assets/templates/assets/_system_user.html:75
|
||||
#: assets/templates/assets/admin_user_create_update.html:45
|
||||
#: assets/templates/assets/asset_bulk_update.html:23
|
||||
#: assets/templates/assets/asset_create.html:67
|
||||
#: assets/templates/assets/asset_update.html:71
|
||||
#: assets/templates/assets/cmd_filter_create_update.html:15
|
||||
#: assets/templates/assets/cmd_filter_rule_create_update.html:40
|
||||
#: assets/templates/assets/domain_create_update.html:16
|
||||
#: assets/templates/assets/gateway_create_update.html:58
|
||||
#: assets/templates/assets/label_create_update.html:18
|
||||
|
@ -743,12 +834,14 @@ msgstr "其它"
|
|||
msgid "Reset"
|
||||
msgstr "重置"
|
||||
|
||||
#: assets/templates/assets/_system_user.html:72
|
||||
#: assets/templates/assets/_system_user.html:76
|
||||
#: assets/templates/assets/admin_user_create_update.html:46
|
||||
#: assets/templates/assets/asset_bulk_update.html:24
|
||||
#: assets/templates/assets/asset_create.html:68
|
||||
#: assets/templates/assets/asset_list.html:114
|
||||
#: assets/templates/assets/asset_update.html:72
|
||||
#: assets/templates/assets/cmd_filter_create_update.html:16
|
||||
#: assets/templates/assets/cmd_filter_rule_create_update.html:41
|
||||
#: assets/templates/assets/domain_create_update.html:17
|
||||
#: assets/templates/assets/gateway_create_update.html:59
|
||||
#: assets/templates/assets/label_create_update.html:19
|
||||
|
@ -783,6 +876,8 @@ msgstr "关闭"
|
|||
|
||||
#: assets/templates/assets/admin_user_assets.html:18
|
||||
#: assets/templates/assets/admin_user_detail.html:18
|
||||
#: assets/templates/assets/cmd_filter_detail.html:19
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:19
|
||||
#: assets/templates/assets/domain_detail.html:18
|
||||
#: assets/templates/assets/domain_gateway_list.html:18
|
||||
#: assets/templates/assets/system_user_asset.html:17
|
||||
|
@ -838,6 +933,9 @@ msgstr "测试"
|
|||
#: assets/templates/assets/admin_user_list.html:88
|
||||
#: assets/templates/assets/asset_detail.html:24
|
||||
#: assets/templates/assets/asset_list.html:171
|
||||
#: assets/templates/assets/cmd_filter_detail.html:29
|
||||
#: assets/templates/assets/cmd_filter_list.html:47
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:86
|
||||
#: assets/templates/assets/domain_detail.html:24
|
||||
#: assets/templates/assets/domain_detail.html:103
|
||||
#: assets/templates/assets/domain_gateway_list.html:85
|
||||
|
@ -866,6 +964,9 @@ msgstr "更新"
|
|||
#: assets/templates/assets/admin_user_list.html:89
|
||||
#: assets/templates/assets/asset_detail.html:28
|
||||
#: assets/templates/assets/asset_list.html:172
|
||||
#: assets/templates/assets/cmd_filter_detail.html:33
|
||||
#: assets/templates/assets/cmd_filter_list.html:48
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:87
|
||||
#: assets/templates/assets/domain_detail.html:28
|
||||
#: assets/templates/assets/domain_detail.html:104
|
||||
#: assets/templates/assets/domain_gateway_list.html:86
|
||||
|
@ -900,8 +1001,9 @@ msgstr "选择节点"
|
|||
#: assets/templates/assets/admin_user_detail.html:100
|
||||
#: assets/templates/assets/asset_detail.html:200
|
||||
#: assets/templates/assets/asset_list.html:633
|
||||
#: assets/templates/assets/cmd_filter_detail.html:106
|
||||
#: assets/templates/assets/system_user_asset.html:111
|
||||
#: assets/templates/assets/system_user_detail.html:330
|
||||
#: assets/templates/assets/system_user_detail.html:182
|
||||
#: assets/templates/assets/system_user_list.html:143 templates/_modal.html:22
|
||||
#: terminal/templates/terminal/session_detail.html:108
|
||||
#: users/templates/users/user_detail.html:382
|
||||
|
@ -951,27 +1053,6 @@ msgstr "不可达"
|
|||
msgid "Ratio"
|
||||
msgstr "比例"
|
||||
|
||||
#: assets/templates/assets/admin_user_list.html:33
|
||||
#: assets/templates/assets/asset_list.html:97
|
||||
#: assets/templates/assets/domain_gateway_list.html:62
|
||||
#: assets/templates/assets/domain_list.html:29
|
||||
#: assets/templates/assets/label_list.html:17
|
||||
#: assets/templates/assets/system_user_asset.html:53
|
||||
#: assets/templates/assets/system_user_list.html:38 audits/models.py:37
|
||||
#: audits/templates/audits/operate_log_list.html:41
|
||||
#: audits/templates/audits/operate_log_list.html:67
|
||||
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64
|
||||
#: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42
|
||||
#: perms/templates/perms/asset_permission_list.html:60
|
||||
#: terminal/templates/terminal/session_list.html:81
|
||||
#: terminal/templates/terminal/terminal_list.html:36
|
||||
#: users/templates/users/user_group_list.html:15
|
||||
#: users/templates/users/user_list.html:29
|
||||
#: xpack/plugins/orgs/templates/orgs/org_list.html:23
|
||||
#: xpack/templates/orgs/org_list.html:15
|
||||
msgid "Action"
|
||||
msgstr "动作"
|
||||
|
||||
#: assets/templates/assets/asset_bulk_update.html:8
|
||||
#: users/templates/users/user_bulk_update.html:8
|
||||
msgid "Select properties that need to be modified"
|
||||
|
@ -1157,7 +1238,6 @@ msgid "This will delete the selected assets !!!"
|
|||
msgstr "删除选择资产"
|
||||
|
||||
#: assets/templates/assets/asset_list.html:631
|
||||
#: assets/templates/assets/system_user_detail.html:328
|
||||
#: assets/templates/assets/system_user_list.html:141
|
||||
#: users/templates/users/user_detail.html:380
|
||||
#: users/templates/users/user_detail.html:406
|
||||
|
@ -1186,6 +1266,37 @@ msgstr "删除失败"
|
|||
msgid "Configuration"
|
||||
msgstr "配置"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_detail.html:25
|
||||
#: assets/templates/assets/cmd_filter_list.html:15
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:23
|
||||
msgid "Rules"
|
||||
msgstr "规则"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_detail.html:73
|
||||
msgid "Date updated"
|
||||
msgstr "更新日期"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_detail.html:97
|
||||
msgid "Binding to system user"
|
||||
msgstr "绑定到系统用户"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_list.html:6 assets/views/cmd_filter.py:47
|
||||
msgid "Create command filter"
|
||||
msgstr "创建命令过滤器"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:33
|
||||
#: assets/views/cmd_filter.py:98
|
||||
msgid "Command filter rule list"
|
||||
msgstr "命令过滤器列表"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:50
|
||||
msgid "Create rule"
|
||||
msgstr "创建规则"
|
||||
|
||||
#: assets/templates/assets/cmd_filter_rule_list.html:61
|
||||
msgid "Strategy"
|
||||
msgstr "分类"
|
||||
|
||||
#: assets/templates/assets/delete_confirm.html:6
|
||||
#: perms/templates/perms/delete_confirm.html:6 templates/delete_confirm.html:6
|
||||
msgid "Confirm delete"
|
||||
|
@ -1273,17 +1384,9 @@ msgstr "家目录"
|
|||
msgid "Uid"
|
||||
msgstr "Uid"
|
||||
|
||||
#: assets/templates/assets/system_user_detail.html:324
|
||||
msgid "Are you sure to remove authentication information for the system user ?"
|
||||
msgstr "你确定清除该系统用户的认证信息吗 ?"
|
||||
|
||||
#: assets/templates/assets/system_user_detail.html:336
|
||||
msgid "Clear auth"
|
||||
msgstr "清除认证信息"
|
||||
|
||||
#: assets/templates/assets/system_user_detail.html:336
|
||||
msgid "success"
|
||||
msgstr "成功"
|
||||
#: assets/templates/assets/system_user_detail.html:173
|
||||
msgid "Binding command filters"
|
||||
msgstr "绑定命令过滤器"
|
||||
|
||||
#: assets/templates/assets/system_user_list.html:10
|
||||
msgid ""
|
||||
|
@ -1369,6 +1472,26 @@ msgstr "更新资产"
|
|||
msgid "already exists"
|
||||
msgstr "已经存在"
|
||||
|
||||
#: assets/views/cmd_filter.py:31
|
||||
msgid "Command filter list"
|
||||
msgstr "命令过滤器列表"
|
||||
|
||||
#: assets/views/cmd_filter.py:63
|
||||
msgid "Update command filter"
|
||||
msgstr "更新命令过滤器"
|
||||
|
||||
#: assets/views/cmd_filter.py:79
|
||||
msgid "Command filter detail"
|
||||
msgstr "命令过滤器详情"
|
||||
|
||||
#: assets/views/cmd_filter.py:131
|
||||
msgid "Create command filter rule"
|
||||
msgstr "创建命令过滤器规则"
|
||||
|
||||
#: assets/views/cmd_filter.py:164
|
||||
msgid "Update command filter rule"
|
||||
msgstr "更新命令过滤器规则"
|
||||
|
||||
#: assets/views/domain.py:30 templates/_nav.html:23
|
||||
msgid "Domain list"
|
||||
msgstr "网域列表"
|
||||
|
@ -1491,12 +1614,6 @@ msgstr "搜索"
|
|||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#: audits/templates/audits/login_log_list.html:50
|
||||
#: common/templates/common/terminal_setting.html:73
|
||||
#: common/templates/common/terminal_setting.html:91
|
||||
msgid "Type"
|
||||
msgstr "类型"
|
||||
|
||||
#: audits/templates/audits/login_log_list.html:51
|
||||
msgid "UA"
|
||||
msgstr "Agent"
|
||||
|
@ -1535,19 +1652,19 @@ msgid "Datetime"
|
|||
msgstr "日期"
|
||||
|
||||
#: audits/views.py:66 audits/views.py:110 audits/views.py:143
|
||||
#: templates/_nav.html:67
|
||||
#: templates/_nav.html:73
|
||||
msgid "Audits"
|
||||
msgstr "日志审计"
|
||||
|
||||
#: audits/views.py:67 templates/_nav.html:71
|
||||
#: audits/views.py:67 templates/_nav.html:77
|
||||
msgid "FTP log"
|
||||
msgstr "FTP日志"
|
||||
|
||||
#: audits/views.py:111 templates/_nav.html:72
|
||||
#: audits/views.py:111 templates/_nav.html:78
|
||||
msgid "Operate log"
|
||||
msgstr "操作日志"
|
||||
|
||||
#: audits/views.py:144 templates/_nav.html:73
|
||||
#: audits/views.py:144 templates/_nav.html:79
|
||||
msgid "Password change log"
|
||||
msgstr "改密日志"
|
||||
|
||||
|
@ -1559,7 +1676,7 @@ msgstr "改密日志"
|
|||
msgid "Users"
|
||||
msgstr "用户管理"
|
||||
|
||||
#: audits/views.py:184 templates/_nav.html:70
|
||||
#: audits/views.py:184 templates/_nav.html:76
|
||||
msgid "Login log"
|
||||
msgstr "登录日志"
|
||||
|
||||
|
@ -1881,7 +1998,7 @@ msgid "Special char not allowed"
|
|||
msgstr "不能包含特殊字符"
|
||||
|
||||
#: common/views.py:19 common/views.py:45 common/views.py:71 common/views.py:101
|
||||
#: common/views.py:129 templates/_nav.html:100
|
||||
#: common/views.py:129 templates/_nav.html:106
|
||||
msgid "Settings"
|
||||
msgstr "系统设置"
|
||||
|
||||
|
@ -1890,7 +2007,7 @@ msgstr "系统设置"
|
|||
msgid "Update setting successfully, please restart program"
|
||||
msgstr "更新设置成功, 请手动重启程序"
|
||||
|
||||
#: jumpserver/views.py:178
|
||||
#: jumpserver/views.py:180
|
||||
msgid ""
|
||||
"<div>Luna is a separately deployed program, you need to deploy Luna, coco, "
|
||||
"configure nginx for url distribution,</div> </div>If you see this page, "
|
||||
|
@ -1927,7 +2044,7 @@ msgstr "任务"
|
|||
#: ops/models/adhoc.py:157 ops/templates/ops/adhoc_detail.html:57
|
||||
#: ops/templates/ops/task_adhoc.html:60
|
||||
msgid "Pattern"
|
||||
msgstr ""
|
||||
msgstr "模式"
|
||||
|
||||
#: ops/models/adhoc.py:158 ops/templates/ops/adhoc_detail.html:61
|
||||
msgid "Options"
|
||||
|
@ -2136,7 +2253,7 @@ msgstr "任务开始: "
|
|||
msgid "Ops"
|
||||
msgstr "作业中心"
|
||||
|
||||
#: ops/views.py:37 templates/_nav.html:61
|
||||
#: ops/views.py:37 templates/_nav.html:67
|
||||
msgid "Task list"
|
||||
msgstr "任务列表"
|
||||
|
||||
|
@ -2174,7 +2291,7 @@ msgstr "资产和节点至少选一个"
|
|||
msgid "Date expired"
|
||||
msgstr "失效日期"
|
||||
|
||||
#: perms/models.py:45 perms/models.py:92 templates/_nav.html:33
|
||||
#: perms/models.py:45 perms/models.py:92 templates/_nav.html:34
|
||||
msgid "Asset permission"
|
||||
msgstr "资产授权"
|
||||
|
||||
|
@ -2262,7 +2379,7 @@ msgid "Select user groups"
|
|||
msgstr "选择用户组"
|
||||
|
||||
#: perms/views.py:23 perms/views.py:53 perms/views.py:68 perms/views.py:83
|
||||
#: perms/views.py:118 perms/views.py:150 templates/_nav.html:30
|
||||
#: perms/views.py:118 perms/views.py:150 templates/_nav.html:31
|
||||
#: xpack/plugins/orgs/templates/orgs/org_list.html:21
|
||||
msgid "Perms"
|
||||
msgstr "权限管理"
|
||||
|
@ -2365,38 +2482,46 @@ msgstr ""
|
|||
msgid "User list"
|
||||
msgstr "用户列表"
|
||||
|
||||
#: templates/_nav.html:39
|
||||
#: templates/_nav.html:27
|
||||
msgid "Command filters"
|
||||
msgstr "命令过滤"
|
||||
|
||||
#: templates/_nav.html:40
|
||||
msgid "Sessions"
|
||||
msgstr "会话管理"
|
||||
|
||||
#: templates/_nav.html:42
|
||||
#: templates/_nav.html:43
|
||||
msgid "Session online"
|
||||
msgstr "在线会话"
|
||||
|
||||
#: templates/_nav.html:43
|
||||
#: templates/_nav.html:44
|
||||
msgid "Session offline"
|
||||
msgstr "历史会话"
|
||||
|
||||
#: templates/_nav.html:44
|
||||
#: templates/_nav.html:45
|
||||
msgid "Commands"
|
||||
msgstr "命令记录"
|
||||
|
||||
#: templates/_nav.html:47 templates/_nav_user.html:14
|
||||
#: templates/_nav.html:48 templates/_nav_user.html:14
|
||||
msgid "Web terminal"
|
||||
msgstr "Web终端"
|
||||
|
||||
#: templates/_nav.html:51 terminal/views/command.py:50
|
||||
#: templates/_nav.html:53
|
||||
msgid "File manager"
|
||||
msgstr "文件管理"
|
||||
|
||||
#: templates/_nav.html:57 terminal/views/command.py:50
|
||||
#: terminal/views/session.py:75 terminal/views/session.py:93
|
||||
#: terminal/views/session.py:115 terminal/views/terminal.py:31
|
||||
#: terminal/views/terminal.py:46 terminal/views/terminal.py:58
|
||||
msgid "Terminal"
|
||||
msgstr "终端管理"
|
||||
|
||||
#: templates/_nav.html:58
|
||||
#: templates/_nav.html:64
|
||||
msgid "Job Center"
|
||||
msgstr "作业中心"
|
||||
|
||||
#: templates/_nav.html:88
|
||||
#: templates/_nav.html:94
|
||||
msgid "XPack"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2638,13 +2763,6 @@ msgstr "运行时间"
|
|||
msgid "Replay"
|
||||
msgstr "回放"
|
||||
|
||||
#: terminal/models.py:139 terminal/templates/terminal/command_list.html:55
|
||||
#: terminal/templates/terminal/command_list.html:71
|
||||
#: terminal/templates/terminal/session_detail.html:48
|
||||
#: terminal/templates/terminal/session_list.html:77
|
||||
msgid "Command"
|
||||
msgstr "命令"
|
||||
|
||||
#: terminal/models.py:142
|
||||
msgid "Date last active"
|
||||
msgstr "最后活跃日期"
|
||||
|
@ -2726,10 +2844,8 @@ msgid "Terminate task send, waiting ..."
|
|||
msgstr "终断任务已发送,请等待"
|
||||
|
||||
#: terminal/templates/terminal/session_list.html:156
|
||||
#, fuzzy
|
||||
#| msgid "MFA enable success"
|
||||
msgid "Finish session success"
|
||||
msgstr "MFA 绑定成功"
|
||||
msgstr "标记会话完成成功"
|
||||
|
||||
#: terminal/templates/terminal/terminal_detail.html:13
|
||||
#: terminal/views/terminal.py:59
|
||||
|
@ -2752,10 +2868,6 @@ msgstr "地址"
|
|||
msgid "Alive"
|
||||
msgstr "在线"
|
||||
|
||||
#: terminal/templates/terminal/terminal_list.html:76
|
||||
msgid "Accept"
|
||||
msgstr "接受"
|
||||
|
||||
#: terminal/templates/terminal/terminal_list.html:78
|
||||
msgid "Reject"
|
||||
msgstr "拒绝"
|
||||
|
@ -2784,36 +2896,36 @@ msgstr "终端列表"
|
|||
msgid "Update terminal"
|
||||
msgstr "更新终端"
|
||||
|
||||
#: terminal/views/terminal.py:102 terminal/views/terminal.py:103
|
||||
#: terminal/views/terminal.py:105 terminal/views/terminal.py:106
|
||||
msgid "Redirect to web terminal"
|
||||
msgstr "重定向到web terminal"
|
||||
|
||||
#: terminal/views/terminal.py:110
|
||||
#: terminal/views/terminal.py:113
|
||||
msgid "Connect ssh terminal"
|
||||
msgstr "连接ssh终端"
|
||||
|
||||
#: terminal/views/terminal.py:111
|
||||
#: terminal/views/terminal.py:114
|
||||
msgid ""
|
||||
"You should use your ssh client tools connect terminal: {} <br /> <br />{}"
|
||||
msgstr "你可以使用ssh客户端工具连接终端"
|
||||
|
||||
#: users/api/auth.py:38 users/templates/users/login.html:52
|
||||
#: users/api/auth.py:40 users/templates/users/login.html:52
|
||||
msgid "Log in frequently and try again later"
|
||||
msgstr "登录频繁, 稍后重试"
|
||||
|
||||
#: users/api/auth.py:77
|
||||
#: users/api/auth.py:79
|
||||
msgid "Please carry seed value and conduct MFA secondary certification"
|
||||
msgstr "请携带seed值, 进行MFA二次认证"
|
||||
|
||||
#: users/api/auth.py:190
|
||||
#: users/api/auth.py:192
|
||||
msgid "Please verify the user name and password first"
|
||||
msgstr "请先进行用户名和密码验证"
|
||||
|
||||
#: users/api/auth.py:202
|
||||
#: users/api/auth.py:204
|
||||
msgid "MFA certification failed"
|
||||
msgstr "MFA认证失败"
|
||||
|
||||
#: users/api/user.py:134
|
||||
#: users/api/user.py:135
|
||||
msgid "Could not reset self otp, use profile reset instead"
|
||||
msgstr "不能再该页面重置MFA, 请去个人信息页面重置"
|
||||
|
||||
|
@ -3133,7 +3245,7 @@ msgstr "上一步"
|
|||
#: users/templates/users/first_login.html:105
|
||||
#: users/templates/users/login_otp.html:67
|
||||
#: users/templates/users/user_otp_authentication.html:26
|
||||
#: users/templates/users/user_otp_enable_bind.html:23
|
||||
#: users/templates/users/user_otp_enable_bind.html:29
|
||||
#: users/templates/users/user_otp_enable_install_app.html:26
|
||||
#: users/templates/users/user_password_authentication.html:21
|
||||
msgid "Next"
|
||||
|
@ -3222,7 +3334,7 @@ msgstr "请打开手机Google Authenticator应用,输入6位动态码"
|
|||
|
||||
#: users/templates/users/login_otp.html:65
|
||||
#: users/templates/users/user_otp_authentication.html:23
|
||||
#: users/templates/users/user_otp_enable_bind.html:20
|
||||
#: users/templates/users/user_otp_enable_bind.html:26
|
||||
msgid "Six figures"
|
||||
msgstr "6位数字"
|
||||
|
||||
|
@ -3496,7 +3608,7 @@ msgstr "解绑 MFA"
|
|||
msgid "Bind"
|
||||
msgstr "绑定 MFA"
|
||||
|
||||
#: users/templates/users/user_otp_enable_bind.html:12
|
||||
#: users/templates/users/user_otp_enable_bind.html:14
|
||||
msgid ""
|
||||
"Use the mobile Google Authenticator application to scan the following qr "
|
||||
"code for a 6-bit verification code"
|
||||
|
@ -3737,7 +3849,7 @@ msgstr "用户组授权资产"
|
|||
msgid "Please enable cookies and try again."
|
||||
msgstr "设置你的浏览器支持cookie"
|
||||
|
||||
#: users/views/login.py:175 users/views/user.py:524 users/views/user.py:549
|
||||
#: users/views/login.py:175 users/views/user.py:526 users/views/user.py:551
|
||||
msgid "MFA code invalid, or ntp sync server time"
|
||||
msgstr "MFA验证码不正确,或者服务器端时间不对"
|
||||
|
||||
|
@ -3818,19 +3930,19 @@ msgstr "密钥更新"
|
|||
msgid "Password invalid"
|
||||
msgstr "用户名或密码无效"
|
||||
|
||||
#: users/views/user.py:579
|
||||
#: users/views/user.py:581
|
||||
msgid "MFA enable success"
|
||||
msgstr "MFA 绑定成功"
|
||||
|
||||
#: users/views/user.py:580
|
||||
#: users/views/user.py:582
|
||||
msgid "MFA enable success, return login page"
|
||||
msgstr "MFA 绑定成功,返回到登录页面"
|
||||
|
||||
#: users/views/user.py:582
|
||||
#: users/views/user.py:584
|
||||
msgid "MFA disable success"
|
||||
msgstr "MFA 解绑成功"
|
||||
|
||||
#: users/views/user.py:583
|
||||
#: users/views/user.py:585
|
||||
msgid "MFA disable success, return login page"
|
||||
msgstr "MFA 解绑成功,返回登录页面"
|
||||
|
||||
|
@ -3882,6 +3994,16 @@ msgstr "创建组织"
|
|||
msgid "Update org"
|
||||
msgstr "更新组织"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Are you sure to remove authentication information for the system user ?"
|
||||
#~ msgstr "你确定清除该系统用户的认证信息吗 ?"
|
||||
|
||||
#~ msgid "Clear auth"
|
||||
#~ msgstr "清除认证信息"
|
||||
|
||||
#~ msgid "success"
|
||||
#~ msgstr "成功"
|
||||
|
||||
#~ msgid "Task has been send, Go to ops task list seen result"
|
||||
#~ msgstr "任务已下发,查看ops任务列表"
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ class SwitchOrgView(DetailView):
|
|||
pk = kwargs.get('pk')
|
||||
self.object = Organization.get_instance(pk)
|
||||
request.session['oid'] = self.object.id.__str__()
|
||||
return redirect('index')
|
||||
referer = request.META.get('HTTP_REFERER', reverse('index'))
|
||||
return redirect(referer)
|
||||
|
||||
|
||||
class SwitchToAOrgView(View):
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<li id="admin-user"><a href="{% url 'assets:admin-user-list' %}">{% trans 'Admin user' %}</a></li>
|
||||
<li id="system-user"><a href="{% url 'assets:system-user-list' %}">{% trans 'System user' %}</a></li>
|
||||
<li id="label"><a href="{% url 'assets:label-list' %}">{% trans 'Labels' %}</a></li>
|
||||
<li id="cmd-filter"><a href="{% url 'assets:cmd-filter-list' %}">{% trans 'Command filters' %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li id="perms">
|
||||
|
@ -47,6 +48,11 @@
|
|||
<span class="nav-label">{% trans 'Web terminal' %}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'terminal:web-sftp' %}" target="_blank">
|
||||
<span class="nav-label">{% trans 'File manager' %}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li>
|
||||
{% endif %}
|
||||
|
|
|
@ -16,6 +16,7 @@ urlpatterns = [
|
|||
path('terminal/<uuid:pk>/update/', views.TerminalUpdateView.as_view(), name='terminal-update'),
|
||||
path('<uuid:pk>/accept/', views.TerminalAcceptView.as_view(), name='terminal-accept'),
|
||||
path('web-terminal/', views.WebTerminalView.as_view(), name='web-terminal'),
|
||||
path('web-sftp/', views.WebSFTPView.as_view(), name='web-sftp'),
|
||||
|
||||
# Session view
|
||||
path('session-online/', views.SessionOnlineListView.as_view(), name='session-online-list'),
|
||||
|
|
|
@ -16,7 +16,7 @@ from common.permissions import SuperUserRequiredMixin
|
|||
__all__ = [
|
||||
"TerminalListView", "TerminalUpdateView", "TerminalDetailView",
|
||||
"TerminalDeleteView", "TerminalConnectView", "TerminalAcceptView",
|
||||
"WebTerminalView",
|
||||
"WebTerminalView", 'WebSFTPView',
|
||||
]
|
||||
|
||||
|
||||
|
@ -124,3 +124,8 @@ class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView
|
|||
class WebTerminalView(LoginRequiredMixin, View):
|
||||
def get(self, request, *args, **kwargs):
|
||||
return redirect('/luna/?' + request.GET.urlencode())
|
||||
|
||||
|
||||
class WebSFTPView(LoginRequiredMixin, View):
|
||||
def get(self, request, *args, **kwargs):
|
||||
return redirect('/coco/elfinder/sftp/?' + request.GET.urlencode())
|
||||
|
|
|
@ -71,3 +71,4 @@ urllib3==1.22
|
|||
vine==1.1.4
|
||||
drf-yasg==1.9.1
|
||||
Werkzeug==0.14.1
|
||||
drf-nested-routers==0.90.2
|
||||
|
|
Loading…
Reference in New Issue