diff --git a/README.md b/README.md index e44a23f9c..df8324761 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,8 @@ Jumpserver采纳分布式架构,支持多机房跨区域部署,中心节点 ---- ### 功能 - - 统一认证 - - 资产管理 - - 统一授权 - - 审计 - - 支持LDAP认证 - - Web terminal - - SSH Server - - 支持Windows RDP + + ![Jumpserver功能](https://jumpserver-release.oss-cn-hangzhou.aliyuncs.com/Jumpserver13.jpg "Jumpserver功能") ### 开始使用 diff --git a/apps/__init__.py b/apps/__init__.py index def994bcd..c6491d9fa 100644 --- a/apps/__init__.py +++ b/apps/__init__.py @@ -2,4 +2,4 @@ # -*- coding: utf-8 -*- # -__version__ = "1.2.1" +__version__ = "1.3.1" diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 50c037df9..b3855eba1 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -43,6 +43,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): queryset = super().get_queryset() admin_user_id = self.request.query_params.get('admin_user_id') node_id = self.request.query_params.get("node_id") + show_current_asset = self.request.query_params.get("show_current_asset") if admin_user_id: admin_user = get_object_or_404(AdminUser, id=admin_user_id) @@ -51,8 +52,11 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): node = get_object_or_404(Node, id=node_id) if not node.is_root(): queryset = queryset.filter( - nodes__key__regex='{}(:[0-9]+)*$'.format(node.key), + nodes__key__regex='^{}(:[0-9]+)*$'.format(node.key), ).distinct() + if show_current_asset and node_id: + queryset = queryset.filter(nodes=node_id).distinct() + return queryset diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index f123e4649..b0e974f5c 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -14,6 +14,7 @@ # limitations under the License. from rest_framework import generics, mixins +from rest_framework.serializers import ValidationError from rest_framework.views import APIView from rest_framework.response import Response from rest_framework_bulk import BulkModelViewSet @@ -41,7 +42,14 @@ __all__ = [ class NodeViewSet(BulkModelViewSet): queryset = Node.objects.all() permission_classes = (IsSuperUser,) - serializer_class = serializers.NodeSerializer + # serializer_class = serializers.NodeSerializer + + def get_serializer_class(self): + show_current_asset = self.request.query_params.get('show_current_asset') + if show_current_asset: + return serializers.NodeCurrentSerializer + else: + return serializers.NodeSerializer def perform_create(self, serializer): child_key = Node.root().get_next_child_key() @@ -83,16 +91,29 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): serializer_class = serializers.NodeSerializer instance = None + def counter(self): + values = [ + child.value[child.value.rfind(' '):] + for child in self.get_object().get_children() + if child.value.startswith("新节点 ") + ] + values = [int(value) for value in values if value.strip().isdigit()] + count = max(values)+1 if values else 1 + return count + def post(self, request, *args, **kwargs): if not request.data.get("value"): - request.data["value"] = _("New node {}").format( - Node.root().get_next_child_key().split(":")[-1] - ) + request.data["value"] = _("New node {}").format(self.counter()) return super().post(request, *args, **kwargs) def create(self, request, *args, **kwargs): instance = self.get_object() value = request.data.get("value") + values = [child.value for child in instance.get_children()] + if value in values: + raise ValidationError( + 'The same level node name cannot be the same' + ) node = instance.create_child(value=value) return Response( {"id": node.id, "key": node.key, "value": node.value}, @@ -127,8 +148,9 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): node_fake.id = asset.id node_fake.parent = node node_fake.value = asset.hostname - node_fake.is_asset = True + node_fake.is_node = False queryset.append(node_fake) + queryset = sorted(queryset, key=lambda x: x.is_node, reverse=True) return queryset def get(self, request, *args, **kwargs): @@ -162,8 +184,9 @@ class NodeAddChildrenApi(generics.UpdateAPIView): for node in children: if not node: continue - node.parent = instance - node.save() + # node.parent = instance + # node.save() + node.set_parent(instance) return Response("OK") @@ -190,6 +213,9 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView): instance = self.get_object() if instance != Node.root(): instance.assets.remove(*tuple(assets)) + else: + assets = [asset for asset in assets if asset.nodes.count() > 1] + instance.assets.remove(*tuple(assets)) class NodeReplaceAssetsApi(generics.UpdateAPIView): diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index b4e46cc78..66d62232d 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -40,7 +40,7 @@ class SystemUserViewSet(BulkModelViewSet): permission_classes = (IsSuperUserOrAppUser,) -class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView): +class SystemUserAuthInfoApi(generics.RetrieveUpdateDestroyAPIView): """ Get system user auth info """ @@ -48,6 +48,11 @@ class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView): permission_classes = (IsSuperUserOrAppUser,) serializer_class = serializers.SystemUserAuthSerializer + def destroy(self, request, *args, **kwargs): + instance = self.get_object() + instance.clear_auth() + return Response(status=204) + class SystemUserPushApi(generics.RetrieveAPIView): """ @@ -58,6 +63,9 @@ class SystemUserPushApi(generics.RetrieveAPIView): def retrieve(self, request, *args, **kwargs): system_user = self.get_object() + nodes = system_user.nodes.all() + for node in nodes: + system_user.assets.add(*tuple(node.get_all_assets())) task = push_system_user_to_assets_manual.delay(system_user) return Response({"task": task.id}) diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 5b3009305..297d50dfc 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -4,7 +4,6 @@ import uuid import logging -import random from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -35,6 +34,19 @@ def default_node(): return None +class AssetQuerySet(models.QuerySet): + def active(self): + return self.filter(is_active=True) + + def valid(self): + return self.active() + + +class AssetManager(models.Manager): + def get_queryset(self): + return AssetQuerySet(self.model, using=self._db) + + class Asset(models.Model): # Important PLATFORM_CHOICES = ( @@ -83,6 +95,8 @@ class Asset(models.Model): date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) + objects = AssetManager() + def __str__(self): return '{0.hostname}({0.ip})'.format(self) @@ -103,7 +117,8 @@ class Asset(models.Model): def get_nodes(self): from .node import Node - return self.nodes.all() or [Node.root()] + nodes = self.nodes.all() or [Node.root()] + return nodes @property def hardware_info(self): diff --git a/apps/assets/models/base.py b/apps/assets/models/base.py index 2997b1b61..cb9bb96ae 100644 --- a/apps/assets/models/base.py +++ b/apps/assets/models/base.py @@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _ from django.conf import settings from common.utils import get_signer, ssh_key_string_to_obj, ssh_key_gen +from common.validators import alphanumeric from .utils import private_key_validator signer = get_signer() @@ -18,7 +19,7 @@ signer = get_signer() class AssetUser(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) - username = models.CharField(max_length=128, verbose_name=_('Username')) + username = models.CharField(max_length=32, verbose_name=_('Username'), validators=[alphanumeric]) _password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password')) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ]) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) @@ -103,10 +104,16 @@ class AssetUser(models.Model): if update_fields: self.save(update_fields=update_fields) + def clear_auth(self): + self._password = '' + self._private_key = '' + self._public_key = '' + self.save() + def auto_gen_auth(self): password = str(uuid.uuid4()) private_key, public_key = ssh_key_gen( - username=self.username, password=password + username=self.username ) self.set_auth(password=password, private_key=private_key, diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index ad806342b..5109f3d0a 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -2,7 +2,8 @@ # import uuid -from django.db import models +from django.db import models, transaction +from django.db.models import Q from django.utils.translation import ugettext_lazy as _ @@ -12,11 +13,14 @@ __all__ = ['Node'] class Node(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) key = models.CharField(unique=True, max_length=64, verbose_name=_("Key")) # '1:1:1:1' - value = models.CharField(max_length=128, unique=True, verbose_name=_("Value")) + # value = models.CharField( + # max_length=128, unique=True, verbose_name=_("Value") + # ) + value = models.CharField(max_length=128, verbose_name=_("Value")) child_mark = models.IntegerField(default=0) date_create = models.DateTimeField(auto_now_add=True) - is_asset = False + is_node = True def __str__(self): return self.full_value @@ -36,6 +40,16 @@ class Node(models.Model): def level(self): return len(self.key.split(':')) + def set_parent(self, instance): + children = self.get_all_children() + old_key = self.key + with transaction.atomic(): + self.parent = instance + for child in children: + child.key = child.key.replace(old_key, self.key, 1) + child.save() + self.save() + def get_next_child_key(self): mark = self.child_mark self.child_mark += 1 @@ -48,56 +62,77 @@ class Node(models.Model): return child def get_children(self): - return self.__class__.objects.filter(key__regex=r'{}:[0-9]+$'.format(self.key)) + return self.__class__.objects.filter( + key__regex=r'^{}:[0-9]+$'.format(self.key) + ) + + def get_children_with_self(self): + return self.__class__.objects.filter( + key__regex=r'^{0}$|^{0}:[0-9]+$'.format(self.key) + ) def get_all_children(self): - return self.__class__.objects.filter(key__startswith='{}:'.format(self.key)) + return self.__class__.objects.filter( + key__startswith='{}:'.format(self.key) + ) + + def get_all_children_with_self(self): + return self.__class__.objects.filter( + key__regex=r'^{0}$|^{0}:'.format(self.key) + ) def get_family(self): - children = list(self.get_all_children()) - children.append(self) - return children + ancestor = self.ancestor + children = self.get_all_children() + return [*tuple(ancestor), self, *tuple(children)] def get_assets(self): from .asset import Asset - assets = Asset.objects.filter(nodes__id=self.id) + if self.is_root(): + assets = Asset.objects.filter( + Q(nodes__id=self.id) | Q(nodes__isnull=True) + ) + else: + assets = Asset.objects.filter(nodes__id=self.id) return assets - def get_active_assets(self): - return self.get_assets().filter(is_active=True) + def get_valid_assets(self): + return self.get_assets().valid() def get_all_assets(self): from .asset import Asset if self.is_root(): assets = Asset.objects.all() else: - nodes = self.get_family() + nodes = self.get_all_children_with_self() assets = Asset.objects.filter(nodes__in=nodes).distinct() return assets + def get_current_assets(self): + from .asset import Asset + assets = Asset.objects.filter(nodes=self).distinct() + return assets + def has_assets(self): return self.get_all_assets() - def get_all_active_assets(self): - return self.get_all_assets().filter(is_active=True) + def get_all_valid_assets(self): + return self.get_all_assets().valid() def is_root(self): return self.key == '0' @property def parent(self): - if self.key == "0": - return self.__class__.root() - elif not self.key.startswith("0"): + if self.key == "0" or not self.key.startswith("0"): return self.__class__.root() parent_key = ":".join(self.key.split(":")[:-1]) try: parent = self.__class__.objects.get(key=parent_key) + return parent except Node.DoesNotExist: return self.__class__.root() - else: - return parent @parent.setter def parent(self, parent): @@ -105,14 +140,20 @@ class Node(models.Model): @property def ancestor(self): - if self.parent == self.__class__.root(): + _key = self.key.split(':') + ancestor_keys = [] + + if self.is_root(): return [self.__class__.root()] - else: - return [self.parent, *tuple(self.parent.ancestor)] + + for i in range(len(_key)-1): + _key.pop() + ancestor_keys.append(':'.join(_key)) + return self.__class__.objects.filter(key__in=ancestor_keys) @property - def ancestor_with_node(self): - ancestor = self.ancestor + def ancestor_with_self(self): + ancestor = list(self.ancestor) ancestor.insert(0, self) return ancestor diff --git a/apps/assets/serializers/asset.py b/apps/assets/serializers/asset.py index 8556be3bf..2c5aa253c 100644 --- a/apps/assets/serializers/asset.py +++ b/apps/assets/serializers/asset.py @@ -18,8 +18,7 @@ class NodeTMPSerializer(serializers.ModelSerializer): class Meta: model = Node - fields = ['id', 'key', 'value', 'parent', 'assets_amount', - 'is_asset'] + fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_node'] list_serializer_class = BulkListSerializer @staticmethod @@ -62,13 +61,13 @@ class AssetGrantedSerializer(serializers.ModelSerializer): """ system_users_granted = AssetSystemUserSerializer(many=True, read_only=True) system_users_join = serializers.SerializerMethodField() - nodes = NodeTMPSerializer(many=True, read_only=True) + # nodes = NodeTMPSerializer(many=True, read_only=True) class Meta: model = Asset fields = ( "id", "hostname", "ip", "port", "system_users_granted", - "is_active", "system_users_join", "os", 'domain', "nodes", + "is_active", "system_users_join", "os", 'domain', "platform", "comment" ) diff --git a/apps/assets/serializers/node.py b/apps/assets/serializers/node.py index 1c9c385e9..b191b0a4f 100644 --- a/apps/assets/serializers/node.py +++ b/apps/assets/serializers/node.py @@ -9,7 +9,7 @@ from .asset import AssetGrantedSerializer __all__ = [ 'NodeSerializer', "NodeGrantedSerializer", "NodeAddChildrenSerializer", - "NodeAssetsSerializer", + "NodeAssetsSerializer", "NodeCurrentSerializer", ] @@ -48,9 +48,20 @@ class NodeSerializer(serializers.ModelSerializer): class Meta: model = Node - fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_asset'] + fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_node'] list_serializer_class = BulkListSerializer + def validate(self, data): + value = data.get('value') + instance = self.instance if self.instance else Node.root() + children = instance.parent.get_children().exclude(key=instance.key) + values = [child.value for child in children] + if value in values: + raise serializers.ValidationError( + 'The same level node name cannot be the same' + ) + return data + @staticmethod def get_parent(obj): return obj.parent.id @@ -66,6 +77,12 @@ class NodeSerializer(serializers.ModelSerializer): return fields +class NodeCurrentSerializer(NodeSerializer): + @staticmethod + def get_assets_amount(obj): + return obj.get_current_assets().count() + + class NodeAssetsSerializer(serializers.ModelSerializer): assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py index dd660bc42..f1773df11 100644 --- a/apps/assets/tasks.py +++ b/apps/assets/tasks.py @@ -22,7 +22,7 @@ TIMEOUT = 60 logger = get_logger(__file__) CACHE_MAX_TIME = 60*60*60 disk_pattern = re.compile(r'^hd|sd|xvd|vd') -PERIOD_TASK = os.environ.get("PERIOD_TASK", "on") +PERIOD_TASK = os.environ.get("PERIOD_TASK", "off") @shared_task diff --git a/apps/assets/templates/assets/_asset_list_modal.html b/apps/assets/templates/assets/_asset_list_modal.html index c5cd48857..db7d165e0 100644 --- a/apps/assets/templates/assets/_asset_list_modal.html +++ b/apps/assets/templates/assets/_asset_list_modal.html @@ -98,7 +98,10 @@ function initTree2() { $.get("{% url 'api-assets:node-list' %}", function(data, status){ $.each(data, function (index, value) { value["pId"] = value["parent"]; - value["open"] = true; + {#value["open"] = true;#} + if (value["key"] === "0") { + value["open"] = true; + } value["name"] = value["value"] + ' (' + value['assets_amount'] + ')'; value['value'] = value['value']; }); diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html index 528e271e6..314967d22 100644 --- a/apps/assets/templates/assets/_system_user.html +++ b/apps/assets/templates/assets/_system_user.html @@ -55,7 +55,7 @@ {% bootstrap_field form.private_key_file layout="horizontal" %}
- +
{{ form.auto_push}}
@@ -79,43 +79,50 @@
{% endblock %} {% block custom_foot_js %} - +$(document).ready(function () { + $('.select2').select2(); + authFieldsDisplay(); + protocolChange(); +}) +.on('change', protocol_id, function(){ + protocolChange(); +}) +.on('change', auto_generate_key, function(){ + authFieldsDisplay(); +}); + + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/admin_user_assets.html b/apps/assets/templates/assets/admin_user_assets.html index 80ff0cd5f..31314392f 100644 --- a/apps/assets/templates/assets/admin_user_assets.html +++ b/apps/assets/templates/assets/admin_user_assets.html @@ -124,7 +124,7 @@ $(document).ready(function () { var success = function (data) { var task_id = data.task; var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id); - window.open(url, '', 'width=800,height=600') + window.open(url, '', 'width=800,height=600,left=400,top=400') }; APIUpdateAttr({ url: the_url, diff --git a/apps/assets/templates/assets/asset_detail.html b/apps/assets/templates/assets/asset_detail.html index 0b1b2865a..b07a7c348 100644 --- a/apps/assets/templates/assets/asset_detail.html +++ b/apps/assets/templates/assets/asset_detail.html @@ -190,7 +190,7 @@ @@ -204,7 +204,7 @@ {% for node in asset.nodes.all %} - {{ node.name }} + {{ node }} diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index 04ba11e57..ab08f7b67 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -17,20 +17,21 @@ position:absolute; visibility:hidden; text-align: left; - top: 100%; + {#top: 100%;#} + top: 0; left: 0; z-index: 1000; - float: left; - padding: 5px 0; + {#float: left;#} + padding: 0 0; margin: 2px 0 0; list-style: none; background-clip: padding-box; - } + } div#rMenu li{ margin: 1px 0; cursor: pointer; - {#list-style: none outside none;#} - } + list-style: none outside none; + } .dropdown a:hover { background-color: #f1f1f1 } @@ -47,7 +48,6 @@
-
@@ -87,7 +87,7 @@ {% trans 'IP' %} {% trans 'Hardware' %} {% trans 'Active' %} - {% trans 'Reachable' %} +{# {% trans 'Reachable' %}#} {% trans 'Action' %} @@ -127,6 +127,9 @@
  • +
  • + + @@ -157,26 +160,35 @@ function initTable() { $(td).html('') } }}, - {targets: 5, createdCell: function (td, cellData) { - if (cellData === 'Unknown'){ - $(td).html('') - } else if (!cellData) { - $(td).html('') - } else { - $(td).html('') - } - }}, - {targets: 6, createdCell: function (td, cellData, rowData) { + + {#{targets: 5, createdCell: function (td, cellData) {#} + {# if (cellData === 'Unknown'){#} + {# $(td).html('')#} + {# } else if (!cellData) {#} + {# $(td).html('')#} + {# } else {#} + {# $(td).html('')#} + {# }#} + {# }},#} + + {targets: 5, createdCell: function (td, cellData, rowData) { var update_btn = '{% trans "Update" %}'.replace("{{ DEFAULT_PK }}", cellData); var del_btn = '{% trans "Delete" %}'.replace('{{ DEFAULT_PK }}', cellData); $(td).html(update_btn + del_btn) }} ], ajax_url: '{% url "api-assets:asset-list" %}', + + {#columns: [#} + {# {data: "id"}, {data: "hostname" }, {data: "ip" },#} + {# {data: "cpu_cores"}, {data: "is_active", orderable: false },#} + {# {data: "is_connective", orderable: false}, {data: "id", orderable: false }#} + {#],#} + columns: [ {data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "cpu_cores"}, {data: "is_active", orderable: false }, - {data: "is_connective", orderable: false}, {data: "id", orderable: false } + {data: "id", orderable: false } ], op_html: $('#actions').html() }; @@ -200,6 +212,8 @@ function addTreeNode() { }; newNode.checked = zTree.getSelectedNodes()[0].checked; zTree.addNodes(parentNode, 0, newNode); + var node = zTree.getNodeByParam('id', newNode.id, parentNode) + zTree.editName(node); } else { alert("{% trans 'Create node failed' %}") } @@ -230,9 +244,9 @@ function removeTreeNode() { function editTreeNode() { hideRMenu(); - var current_node = zTree.getSelectedNodes()[0]; - if (!current_node){ - return + var current_node = zTree.getSelectedNodes()[0]; + if (!current_node){ + return } if (current_node.value) { current_node.name = current_node.value; @@ -253,6 +267,8 @@ function OnRightClick(event, treeId, treeNode) { function showRMenu(type, x, y) { $("#rMenu ul").show(); x -= 220; + x += document.body.scrollLeft; + y += document.body.scrollTop+document.documentElement.scrollTop; rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"}); $("body").bind("mousedown", onBodyMouseDown); @@ -290,6 +306,7 @@ function onRename(event, treeId, treeNode, isCancel){ function onSelected(event, treeNode) { var url = asset_table.ajax.url(); url = setUrlParam(url, "node_id", treeNode.id); + url = setUrlParam(url, "show_current_asset", getCookie('show_current_asset')); setCookie('node_selected', treeNode.id); asset_table.ajax.url(url); asset_table.ajax.reload(); @@ -382,12 +399,13 @@ function initTree() { }; var zNodes = []; - $.get("{% url 'api-assets:node-list' %}", function(data, status){ + var query_params = {'show_current_asset': getCookie('show_current_asset')}; + $.get("{% url 'api-assets:node-list' %}", query_params, function(data, status){ $.each(data, function (index, value) { value["pId"] = value["parent"]; - {#if (value["key"] === "0") {#} - value["open"] = true; - {# }#} + if (value["key"] === "0") { + value["open"] = true; + } value["name"] = value["value"] + ' (' + value['assets_amount'] + ')'; value['value'] = value['value']; }); @@ -417,6 +435,13 @@ function toggle() { $(document).ready(function(){ initTable(); initTree(); + + if(getCookie('show_current_asset') === 'yes'){ + $('#show_all_asset').css('display', 'inline-block'); + } + else{ + $('#show_current_asset').css('display', 'inline-block'); + } }) .on('click', '.labels li', function () { var val = $(this).text(); @@ -535,6 +560,20 @@ $(document).ready(function(){ flash_message: false }); }) +.on('click', '.btn-show-current-asset', function(){ + hideRMenu(); + $(this).css('display', 'none'); + $('#show_all_asset').css('display', 'inline-block'); + setCookie('show_current_asset', 'yes'); + location.reload(); +}) +.on('click', '.btn-show-all-asset', function(){ + hideRMenu(); + $(this).css('display', 'none'); + $('#show_current_asset').css('display', 'inline-block'); + setCookie('show_current_asset', ''); + location.reload(); +}) .on('click', '.btn_asset_delete', function () { var $this = $(this); var $data_table = $("#asset_list_table").DataTable(); diff --git a/apps/assets/templates/assets/domain_gateway_list.html b/apps/assets/templates/assets/domain_gateway_list.html index 581f6c08a..c2d5528ee 100644 --- a/apps/assets/templates/assets/domain_gateway_list.html +++ b/apps/assets/templates/assets/domain_gateway_list.html @@ -85,6 +85,9 @@ function initTable() { var update_btn = '{% trans "Update" %}'.replace('{{ DEFAULT_PK }}', cellData); var del_btn = '{% trans "Delete" %}'.replace('{{ DEFAULT_PK }}', cellData); var test_btn = '{% trans "Test connection" %}'.replace('{{ DEFAULT_PK }}', cellData); + if(rowData.protocol === 'rdp'){ + test_btn = '{% trans "Test connection" %}'.replace('{{ DEFAULT_PK }}', cellData); + } $(td).html(update_btn + test_btn + del_btn) }} ], @@ -120,7 +123,6 @@ $(document).ready(function(){ success_message: "可连接", fail_message: "连接失败" }) - -}) +}); {% endblock %} diff --git a/apps/assets/templates/assets/gateway_create_update.html b/apps/assets/templates/assets/gateway_create_update.html index 7d6800c41..e0b10ba73 100644 --- a/apps/assets/templates/assets/gateway_create_update.html +++ b/apps/assets/templates/assets/gateway_create_update.html @@ -66,3 +66,28 @@ {% endblock %} + +{% block custom_foot_js %} + +{% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/system_user_detail.html b/apps/assets/templates/assets/system_user_detail.html index a02bf1e44..9a7bc255a 100644 --- a/apps/assets/templates/assets/system_user_detail.html +++ b/apps/assets/templates/assets/system_user_detail.html @@ -64,14 +64,14 @@ {% trans 'Protocol' %}: - {{ system_user.protocol }} + {{ system_user.protocol }} - + {% trans 'Sudo' %}: {{ system_user.sudo }} {% if system_user.shell %} - + {% trans 'Shell' %}: {{ system_user.shell }} @@ -107,14 +107,14 @@
    -
    +
    {% trans 'Quick update' %}
    - + - {% if system_user.auto_push %} + - {% endif %} + + + + + + {# #} {# #} {#
    {% trans 'Auto push' %}: @@ -130,8 +130,8 @@
    {% trans 'Push system user now' %}: @@ -139,8 +139,8 @@
    {% trans 'Test assets connective' %}: @@ -149,6 +149,15 @@
    {% trans 'Clear auth' %}: + + + +
    {% trans 'Change auth period' %}:#} @@ -236,6 +245,10 @@ function updateSystemUserNode(nodes) { } 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; @@ -296,7 +309,7 @@ $(document).ready(function () { var success = function (data) { var task_id = data.task; var url = '{% url "ops:celery-task-log" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", task_id); - window.open(url, '', 'width=800,height=600') + window.open(url, '', 'width=800,height=600,left=400,top=400') }; APIUpdateAttr({ url: the_url, @@ -318,6 +331,13 @@ $(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 %}'; + APIUpdateAttr({ + url: the_url, + method: 'DELETE', + success_message: "{% trans 'Clear auth' %}" + " {% trans 'success' %}" + }); }) {% endblock %} diff --git a/apps/assets/templates/assets/system_user_update.html b/apps/assets/templates/assets/system_user_update.html index 46ef8d6a3..7e1590db5 100644 --- a/apps/assets/templates/assets/system_user_update.html +++ b/apps/assets/templates/assets/system_user_update.html @@ -15,10 +15,3 @@ {% endblock %} -{% block custom_foot_js %} - -{% endblock %} \ No newline at end of file diff --git a/apps/common/api.py b/apps/common/api.py index 4b74b6b0d..209d09747 100644 --- a/apps/common/api.py +++ b/apps/common/api.py @@ -96,14 +96,7 @@ class LDAPTestingAPI(APIView): class DjangoSettingsAPI(APIView): def get(self, request): - if not settings.DEBUG: - return Response('Only debug mode support') - - configs = {} - for i in dir(settings): - if i.isupper(): - configs[i] = str(getattr(settings, i)) - return Response(configs) + return Response('Danger, Close now') diff --git a/apps/common/validators.py b/apps/common/validators.py new file mode 100644 index 000000000..b273bd1de --- /dev/null +++ b/apps/common/validators.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# +from django.core.validators import RegexValidator +from django.utils.translation import ugettext_lazy as _ + + +alphanumeric = RegexValidator(r'^[0-9a-zA-Z_@\-\.]*$', _('Special char not allowed')) \ No newline at end of file diff --git a/apps/i18n/zh/LC_MESSAGES/django.mo b/apps/i18n/zh/LC_MESSAGES/django.mo index ebfffbfe7..b764117a2 100644 Binary files a/apps/i18n/zh/LC_MESSAGES/django.mo and b/apps/i18n/zh/LC_MESSAGES/django.mo differ diff --git a/apps/i18n/zh/LC_MESSAGES/django.po b/apps/i18n/zh/LC_MESSAGES/django.po index 627e44ed6..31654aa11 100644 --- a/apps/i18n/zh/LC_MESSAGES/django.po +++ b/apps/i18n/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Jumpserver 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-04-23 19:51+0800\n" +"POT-Creation-Date: 2018-05-25 18:11+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: Jumpserver team\n" @@ -17,27 +17,27 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: assets/api/node.py:88 +#: assets/api/node.py:106 msgid "New node {}" msgstr "新节点 {}" -#: assets/api/node.py:216 +#: assets/api/node.py:242 msgid "更新节点资产硬件信息: {}" msgstr "" -#: assets/api/node.py:229 +#: assets/api/node.py:255 msgid "测试节点下资产是否可连接: {}" msgstr "" -#: assets/forms/asset.py:24 assets/models/asset.py:54 assets/models/user.py:103 +#: assets/forms/asset.py:24 assets/models/asset.py:66 assets/models/user.py:103 #: assets/templates/assets/asset_detail.html:183 #: assets/templates/assets/asset_detail.html:191 -#: assets/templates/assets/system_user_detail.html:166 perms/models.py:23 +#: assets/templates/assets/system_user_detail.html:175 perms/models.py:33 msgid "Nodes" msgstr "节点管理" #: assets/forms/asset.py:27 assets/forms/asset.py:66 assets/forms/asset.py:109 -#: assets/forms/asset.py:113 assets/models/asset.py:58 +#: assets/forms/asset.py:113 assets/models/asset.py:70 #: assets/models/cluster.py:19 assets/models/user.py:72 #: assets/templates/assets/asset_detail.html:73 templates/_nav.html:25 msgid "Admin user" @@ -46,14 +46,14 @@ msgstr "管理用户" #: assets/forms/asset.py:30 assets/forms/asset.py:69 assets/forms/asset.py:125 #: assets/templates/assets/asset_create.html:35 #: assets/templates/assets/asset_create.html:37 -#: assets/templates/assets/asset_list.html:75 +#: assets/templates/assets/asset_list.html:74 #: assets/templates/assets/asset_update.html:40 #: assets/templates/assets/asset_update.html:42 #: assets/templates/assets/user_asset_list.html:34 msgid "Label" msgstr "标签" -#: assets/forms/asset.py:34 assets/forms/asset.py:73 assets/models/asset.py:53 +#: assets/forms/asset.py:34 assets/forms/asset.py:73 assets/models/asset.py:65 #: assets/models/domain.py:46 msgid "Domain" msgstr "网域" @@ -61,7 +61,7 @@ msgstr "网域" #: assets/forms/asset.py:38 assets/forms/asset.py:63 assets/forms/asset.py:77 #: assets/forms/asset.py:128 assets/templates/assets/asset_create.html:29 #: assets/templates/assets/asset_update.html:34 perms/forms.py:40 -#: perms/forms.py:47 perms/models.py:67 +#: perms/forms.py:47 perms/models.py:76 #: perms/templates/perms/asset_permission_list.html:57 #: perms/templates/perms/asset_permission_list.html:142 msgid "Node" @@ -90,7 +90,7 @@ msgstr "如果有多个的互相隔离的网络,设置资产属于的网域, msgid "Select assets" msgstr "选择资产" -#: assets/forms/asset.py:105 assets/models/asset.py:51 +#: assets/forms/asset.py:105 assets/models/asset.py:63 #: assets/models/domain.py:44 assets/templates/assets/admin_user_assets.html:53 #: assets/templates/assets/asset_detail.html:69 #: assets/templates/assets/domain_gateway_list.html:58 @@ -99,18 +99,18 @@ msgid "Port" msgstr "端口" #: assets/forms/domain.py:14 assets/forms/label.py:13 -#: assets/models/asset.py:169 assets/templates/assets/admin_user_list.html:25 +#: assets/models/asset.py:183 assets/templates/assets/admin_user_list.html:25 #: assets/templates/assets/domain_detail.html:60 #: assets/templates/assets/domain_list.html:15 #: assets/templates/assets/label_list.html:16 #: assets/templates/assets/system_user_list.html:29 audits/models.py:11 #: audits/templates/audits/ftp_log_list.html:41 #: audits/templates/audits/ftp_log_list.html:72 perms/forms.py:37 -#: perms/models.py:22 +#: perms/models.py:32 #: perms/templates/perms/asset_permission_create_update.html:40 #: perms/templates/perms/asset_permission_list.html:56 #: perms/templates/perms/asset_permission_list.html:139 -#: terminal/backends/command/models.py:11 terminal/models.py:123 +#: terminal/backends/command/models.py:11 terminal/models.py:127 #: terminal/templates/terminal/command_list.html:40 #: terminal/templates/terminal/command_list.html:73 #: terminal/templates/terminal/session_list.html:41 @@ -119,7 +119,7 @@ msgid "Asset" msgstr "资产" #: assets/forms/domain.py:54 assets/forms/user.py:79 assets/forms/user.py:120 -#: assets/models/base.py:20 assets/models/cluster.py:18 +#: assets/models/base.py:21 assets/models/cluster.py:18 #: assets/models/domain.py:17 assets/models/group.py:20 #: assets/models/label.py:17 assets/templates/assets/admin_user_detail.html:56 #: assets/templates/assets/admin_user_list.html:23 @@ -132,10 +132,10 @@ msgstr "资产" #: common/templates/common/terminal_setting.html:67 #: common/templates/common/terminal_setting.html:85 ops/models/adhoc.py:36 #: ops/templates/ops/task_detail.html:59 ops/templates/ops/task_list.html:35 -#: perms/models.py:19 perms/templates/perms/asset_permission_detail.html:62 +#: perms/models.py:29 perms/templates/perms/asset_permission_detail.html:62 #: perms/templates/perms/asset_permission_list.html:53 #: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:16 -#: terminal/models.py:149 terminal/templates/terminal/terminal_detail.html:43 +#: terminal/models.py:154 terminal/templates/terminal/terminal_detail.html:43 #: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14 #: users/models/user.py:42 users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_detail.html:63 @@ -148,14 +148,14 @@ msgid "Name" msgstr "名称" #: assets/forms/domain.py:55 assets/forms/user.py:80 assets/forms/user.py:121 -#: assets/models/base.py:21 assets/templates/assets/admin_user_detail.html:60 +#: assets/models/base.py:22 assets/templates/assets/admin_user_detail.html:60 #: assets/templates/assets/admin_user_list.html:24 #: assets/templates/assets/domain_gateway_list.html:60 #: assets/templates/assets/system_user_detail.html:62 #: assets/templates/assets/system_user_list.html:27 #: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13 -#: users/forms.py:22 users/models/authentication.py:45 users/models/user.py:40 -#: users/templates/users/_select_user_modal.html:14 +#: users/forms.py:21 users/forms.py:30 users/models/authentication.py:45 +#: users/models/user.py:40 users/templates/users/_select_user_modal.html:14 #: users/templates/users/login.html:56 #: users/templates/users/login_log_list.html:49 #: users/templates/users/user_detail.html:67 @@ -168,8 +168,8 @@ msgstr "用户名" msgid "Password or private key passphrase" msgstr "密码或密钥密码" -#: assets/forms/user.py:25 assets/models/base.py:22 common/forms.py:113 -#: users/forms.py:15 users/forms.py:24 users/forms.py:36 +#: assets/forms/user.py:25 assets/models/base.py:23 common/forms.py:113 +#: users/forms.py:15 users/forms.py:23 users/forms.py:32 users/forms.py:44 #: users/templates/users/login.html:59 #: users/templates/users/reset_password.html:52 #: users/templates/users/user_create.html:10 @@ -202,11 +202,11 @@ msgid "" "than 2 system user" msgstr "高优先级的系统用户将会作为默认登录用户" -#: assets/models/asset.py:49 assets/models/domain.py:43 +#: assets/models/asset.py:61 assets/models/domain.py:43 #: assets/templates/assets/_asset_list_modal.html:46 #: assets/templates/assets/admin_user_assets.html:52 #: assets/templates/assets/asset_detail.html:61 -#: assets/templates/assets/asset_list.html:87 +#: assets/templates/assets/asset_list.html:86 #: assets/templates/assets/domain_gateway_list.html:57 #: assets/templates/assets/system_user_asset.html:50 #: assets/templates/assets/user_asset_list.html:46 common/forms.py:144 @@ -217,10 +217,10 @@ msgstr "高优先级的系统用户将会作为默认登录用户" msgid "IP" msgstr "IP" -#: assets/models/asset.py:50 assets/templates/assets/_asset_list_modal.html:45 +#: assets/models/asset.py:62 assets/templates/assets/_asset_list_modal.html:45 #: assets/templates/assets/admin_user_assets.html:51 #: assets/templates/assets/asset_detail.html:57 -#: assets/templates/assets/asset_list.html:86 +#: assets/templates/assets/asset_list.html:85 #: assets/templates/assets/system_user_asset.html:49 #: assets/templates/assets/user_asset_list.html:45 common/forms.py:143 #: perms/templates/perms/asset_permission_asset.html:54 @@ -229,107 +229,107 @@ msgstr "IP" msgid "Hostname" msgstr "主机名" -#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:97 +#: assets/models/asset.py:64 assets/templates/assets/asset_detail.html:97 msgid "Platform" msgstr "系统平台" -#: assets/models/asset.py:55 assets/models/domain.py:48 +#: assets/models/asset.py:67 assets/models/domain.py:48 #: assets/models/label.py:20 assets/templates/assets/asset_detail.html:105 msgid "Is active" msgstr "激活" -#: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:65 +#: assets/models/asset.py:73 assets/templates/assets/asset_detail.html:65 msgid "Public IP" msgstr "公网IP" -#: assets/models/asset.py:62 assets/templates/assets/asset_detail.html:113 +#: assets/models/asset.py:74 assets/templates/assets/asset_detail.html:113 msgid "Asset number" msgstr "资产编号" -#: assets/models/asset.py:65 assets/templates/assets/asset_detail.html:77 +#: assets/models/asset.py:77 assets/templates/assets/asset_detail.html:77 msgid "Vendor" msgstr "制造商" -#: assets/models/asset.py:66 assets/templates/assets/asset_detail.html:81 +#: assets/models/asset.py:78 assets/templates/assets/asset_detail.html:81 msgid "Model" msgstr "型号" -#: assets/models/asset.py:67 assets/templates/assets/asset_detail.html:109 +#: assets/models/asset.py:79 assets/templates/assets/asset_detail.html:109 msgid "Serial number" msgstr "序列号" -#: assets/models/asset.py:69 +#: assets/models/asset.py:81 msgid "CPU model" msgstr "CPU型号" -#: assets/models/asset.py:70 +#: assets/models/asset.py:82 msgid "CPU count" msgstr "CPU数量" -#: assets/models/asset.py:71 +#: assets/models/asset.py:83 msgid "CPU cores" msgstr "CPU核数" -#: assets/models/asset.py:72 assets/templates/assets/asset_detail.html:89 +#: assets/models/asset.py:84 assets/templates/assets/asset_detail.html:89 msgid "Memory" msgstr "内存" -#: assets/models/asset.py:73 +#: assets/models/asset.py:85 msgid "Disk total" msgstr "硬盘大小" -#: assets/models/asset.py:74 +#: assets/models/asset.py:86 msgid "Disk info" msgstr "硬盘信息" -#: assets/models/asset.py:76 assets/templates/assets/asset_detail.html:101 +#: assets/models/asset.py:88 assets/templates/assets/asset_detail.html:101 msgid "OS" msgstr "操作系统" -#: assets/models/asset.py:77 +#: assets/models/asset.py:89 msgid "OS version" msgstr "系统版本" -#: assets/models/asset.py:78 +#: assets/models/asset.py:90 msgid "OS arch" msgstr "系统架构" -#: assets/models/asset.py:79 +#: assets/models/asset.py:91 msgid "Hostname raw" msgstr "主机名原始" -#: assets/models/asset.py:81 assets/templates/assets/asset_create.html:33 +#: assets/models/asset.py:93 assets/templates/assets/asset_create.html:33 #: assets/templates/assets/asset_detail.html:220 #: assets/templates/assets/asset_update.html:38 templates/_nav.html:27 msgid "Labels" msgstr "标签管理" -#: assets/models/asset.py:82 assets/models/base.py:28 +#: assets/models/asset.py:94 assets/models/base.py:29 #: assets/models/cluster.py:28 assets/models/group.py:21 #: assets/templates/assets/admin_user_detail.html:68 #: assets/templates/assets/asset_detail.html:117 #: assets/templates/assets/domain_detail.html:72 #: assets/templates/assets/system_user_detail.html:96 -#: ops/templates/ops/adhoc_detail.html:86 perms/models.py:28 perms/models.py:72 +#: ops/templates/ops/adhoc_detail.html:86 perms/models.py:38 perms/models.py:81 #: perms/templates/perms/asset_permission_detail.html:98 #: users/models/user.py:83 users/templates/users/user_detail.html:107 msgid "Created by" msgstr "创建者" -#: assets/models/asset.py:83 assets/models/cluster.py:26 +#: assets/models/asset.py:95 assets/models/cluster.py:26 #: assets/models/domain.py:20 assets/models/group.py:22 #: assets/models/label.py:23 assets/templates/assets/admin_user_detail.html:64 #: assets/templates/assets/domain_detail.html:68 #: assets/templates/assets/system_user_detail.html:92 #: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:63 -#: perms/models.py:29 perms/models.py:73 +#: perms/models.py:39 perms/models.py:82 #: perms/templates/perms/asset_permission_detail.html:94 #: terminal/templates/terminal/terminal_detail.html:59 users/models/group.py:17 #: users/templates/users/user_group_detail.html:63 msgid "Date created" msgstr "创建日期" -#: assets/models/asset.py:84 assets/models/base.py:25 +#: assets/models/asset.py:96 assets/models/base.py:26 #: assets/models/cluster.py:29 assets/models/domain.py:18 #: assets/models/domain.py:47 assets/models/group.py:23 #: assets/models/label.py:21 assets/templates/assets/admin_user_detail.html:72 @@ -340,7 +340,7 @@ msgstr "创建日期" #: assets/templates/assets/domain_list.html:17 #: assets/templates/assets/system_user_detail.html:100 #: assets/templates/assets/system_user_list.html:33 common/models.py:30 -#: ops/models/adhoc.py:42 perms/models.py:30 perms/models.py:74 +#: ops/models/adhoc.py:42 perms/models.py:40 perms/models.py:83 #: perms/templates/perms/asset_permission_detail.html:102 terminal/models.py:26 #: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15 #: users/models/user.py:75 users/templates/users/user_detail.html:119 @@ -350,11 +350,11 @@ msgstr "创建日期" msgid "Comment" msgstr "备注" -#: assets/models/base.py:23 +#: assets/models/base.py:24 msgid "SSH private key" msgstr "ssh密钥" -#: assets/models/base.py:24 +#: assets/models/base.py:25 msgid "SSH public key" msgstr "ssh公钥" @@ -408,6 +408,7 @@ msgstr "集群" #: assets/templates/assets/domain_gateway_list.html:59 #: assets/templates/assets/system_user_detail.html:66 #: assets/templates/assets/system_user_list.html:28 +#: terminal/templates/terminal/session_list.html:75 msgid "Protocol" msgstr "协议" @@ -422,22 +423,22 @@ msgstr "默认资产组" #: assets/models/label.py:14 audits/models.py:9 #: audits/templates/audits/ftp_log_list.html:33 #: audits/templates/audits/ftp_log_list.html:71 perms/forms.py:14 -#: perms/forms.py:31 perms/models.py:20 +#: perms/forms.py:31 perms/models.py:30 #: perms/templates/perms/asset_permission_create_update.html:36 #: perms/templates/perms/asset_permission_list.html:54 #: perms/templates/perms/asset_permission_list.html:133 -#: terminal/backends/command/models.py:10 terminal/models.py:122 +#: terminal/backends/command/models.py:10 terminal/models.py:126 #: terminal/templates/terminal/command_list.html:32 #: terminal/templates/terminal/command_list.html:72 #: terminal/templates/terminal/session_list.html:33 -#: terminal/templates/terminal/session_list.html:71 users/forms.py:273 +#: terminal/templates/terminal/session_list.html:71 users/forms.py:281 #: users/models/user.py:30 users/models/user.py:318 #: users/templates/users/user_group_detail.html:78 #: users/templates/users/user_group_list.html:13 users/views/user.py:339 msgid "User" msgstr "用户" -#: assets/models/label.py:18 assets/models/node.py:15 +#: assets/models/label.py:18 assets/models/node.py:18 #: assets/templates/assets/label_list.html:15 common/models.py:27 msgid "Value" msgstr "值" @@ -489,11 +490,11 @@ msgstr "Shell" #: assets/models/user.py:149 audits/models.py:12 #: audits/templates/audits/ftp_log_list.html:49 #: audits/templates/audits/ftp_log_list.html:73 perms/forms.py:43 -#: perms/models.py:24 perms/models.py:69 +#: perms/models.py:34 perms/models.py:78 #: perms/templates/perms/asset_permission_detail.html:140 #: perms/templates/perms/asset_permission_list.html:58 #: perms/templates/perms/asset_permission_list.html:145 templates/_nav.html:26 -#: terminal/backends/command/models.py:12 terminal/models.py:124 +#: terminal/backends/command/models.py:12 terminal/models.py:128 #: terminal/templates/terminal/command_list.html:48 #: terminal/templates/terminal/command_list.html:74 #: terminal/templates/terminal/session_list.html:49 @@ -561,7 +562,6 @@ msgid "Select System Users" msgstr "选择系统用户" #: assets/templates/assets/_asset_group_bulk_update_modal.html:34 -#, fuzzy msgid "Enable-MFA" msgstr "启用MFA" @@ -650,7 +650,7 @@ msgstr "重置" #: assets/templates/assets/admin_user_create_update.html:46 #: assets/templates/assets/asset_bulk_update.html:24 #: assets/templates/assets/asset_create.html:67 -#: assets/templates/assets/asset_list.html:108 +#: assets/templates/assets/asset_list.html:107 #: assets/templates/assets/asset_update.html:71 #: assets/templates/assets/domain_create_update.html:17 #: assets/templates/assets/gateway_create_update.html:59 @@ -660,7 +660,7 @@ msgstr "重置" #: common/templates/common/ldap_setting.html:60 #: common/templates/common/terminal_setting.html:103 #: perms/templates/perms/asset_permission_create_update.html:70 -#: terminal/templates/terminal/session_list.html:120 +#: terminal/templates/terminal/session_list.html:124 #: terminal/templates/terminal/terminal_update.html:48 #: users/templates/users/_user.html:47 #: users/templates/users/forgot_password.html:44 @@ -699,7 +699,6 @@ msgstr "资产列表" #: assets/templates/assets/admin_user_assets.html:54 #: assets/templates/assets/admin_user_list.html:26 -#: assets/templates/assets/asset_list.html:90 #: assets/templates/assets/system_user_asset.html:52 #: assets/templates/assets/system_user_list.html:30 #: users/templates/users/user_group_granted_asset.html:47 @@ -728,7 +727,7 @@ msgstr "测试" #: assets/templates/assets/admin_user_detail.html:24 #: assets/templates/assets/admin_user_list.html:85 #: assets/templates/assets/asset_detail.html:24 -#: assets/templates/assets/asset_list.html:170 +#: assets/templates/assets/asset_list.html:174 #: assets/templates/assets/domain_detail.html:24 #: assets/templates/assets/domain_detail.html:103 #: assets/templates/assets/domain_gateway_list.html:85 @@ -752,7 +751,7 @@ msgstr "更新" #: assets/templates/assets/admin_user_detail.html:28 #: assets/templates/assets/admin_user_list.html:86 #: assets/templates/assets/asset_detail.html:28 -#: assets/templates/assets/asset_list.html:171 +#: assets/templates/assets/asset_list.html:175 #: assets/templates/assets/domain_detail.html:28 #: assets/templates/assets/domain_detail.html:104 #: assets/templates/assets/domain_gateway_list.html:86 @@ -783,8 +782,8 @@ msgstr "选择节点" #: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/asset_detail.html:200 -#: assets/templates/assets/asset_list.html:600 -#: assets/templates/assets/system_user_detail.html:183 +#: assets/templates/assets/asset_list.html:636 +#: assets/templates/assets/system_user_detail.html:192 #: assets/templates/assets/system_user_list.html:138 templates/_modal.html:22 #: terminal/templates/terminal/session_detail.html:108 #: users/templates/users/user_detail.html:362 @@ -792,7 +791,7 @@ msgstr "选择节点" #: users/templates/users/user_detail.html:410 #: users/templates/users/user_group_create_update.html:32 #: users/templates/users/user_group_list.html:86 -#: users/templates/users/user_list.html:196 +#: users/templates/users/user_list.html:199 #: users/templates/users/user_profile.html:215 msgid "Confirm" msgstr "确认" @@ -815,7 +814,7 @@ msgid "Ratio" msgstr "比例" #: assets/templates/assets/admin_user_list.html:30 -#: assets/templates/assets/asset_list.html:91 +#: assets/templates/assets/asset_list.html:90 #: assets/templates/assets/domain_gateway_list.html:62 #: assets/templates/assets/domain_list.html:18 #: assets/templates/assets/label_list.html:17 @@ -856,9 +855,9 @@ msgid "Quick modify" msgstr "快速修改" #: assets/templates/assets/asset_detail.html:143 -#: assets/templates/assets/asset_list.html:89 -#: assets/templates/assets/user_asset_list.html:47 perms/models.py:25 -#: perms/models.py:70 +#: assets/templates/assets/asset_list.html:88 +#: assets/templates/assets/user_asset_list.html:47 perms/models.py:35 +#: perms/models.py:79 #: perms/templates/perms/asset_permission_create_update.html:47 #: perms/templates/perms/asset_permission_detail.html:120 #: perms/templates/perms/asset_permission_list.html:59 @@ -886,111 +885,119 @@ msgstr "刷新" msgid "Update successfully!" msgstr "更新成功" -#: assets/templates/assets/asset_list.html:63 assets/views/asset.py:97 +#: assets/templates/assets/asset_list.html:62 assets/views/asset.py:97 msgid "Create asset" msgstr "创建资产" -#: assets/templates/assets/asset_list.html:67 +#: assets/templates/assets/asset_list.html:66 #: users/templates/users/user_list.html:7 msgid "Import" msgstr "导入" -#: assets/templates/assets/asset_list.html:70 +#: assets/templates/assets/asset_list.html:69 #: users/templates/users/user_list.html:10 msgid "Export" msgstr "导出" -#: assets/templates/assets/asset_list.html:88 +#: assets/templates/assets/asset_list.html:87 msgid "Hardware" msgstr "硬件" -#: assets/templates/assets/asset_list.html:100 +#: assets/templates/assets/asset_list.html:99 #: users/templates/users/user_list.html:37 msgid "Delete selected" msgstr "批量删除" -#: assets/templates/assets/asset_list.html:101 +#: assets/templates/assets/asset_list.html:100 #: users/templates/users/user_list.html:38 msgid "Update selected" msgstr "批量更新" -#: assets/templates/assets/asset_list.html:102 +#: assets/templates/assets/asset_list.html:101 msgid "Remove from this node" msgstr "从节点移除" -#: assets/templates/assets/asset_list.html:103 +#: assets/templates/assets/asset_list.html:102 #: users/templates/users/user_list.html:39 msgid "Deactive selected" msgstr "禁用所选" -#: assets/templates/assets/asset_list.html:104 +#: assets/templates/assets/asset_list.html:103 #: users/templates/users/user_list.html:40 msgid "Active selected" msgstr "激活所选" -#: assets/templates/assets/asset_list.html:121 +#: assets/templates/assets/asset_list.html:120 msgid "Add node" msgstr "新建节点" -#: assets/templates/assets/asset_list.html:122 +#: assets/templates/assets/asset_list.html:121 msgid "Rename node" msgstr "重命名节点" -#: assets/templates/assets/asset_list.html:123 +#: assets/templates/assets/asset_list.html:122 msgid "Delete node" msgstr "删除节点" -#: assets/templates/assets/asset_list.html:125 +#: assets/templates/assets/asset_list.html:124 msgid "Add assets to node" msgstr "添加资产到节点" -#: assets/templates/assets/asset_list.html:126 +#: assets/templates/assets/asset_list.html:125 msgid "Move assets to node" msgstr "移动资产到节点" -#: assets/templates/assets/asset_list.html:128 +#: assets/templates/assets/asset_list.html:127 msgid "Refresh node hardware info" msgstr "更新节点资产硬件信息" -#: assets/templates/assets/asset_list.html:129 +#: assets/templates/assets/asset_list.html:128 msgid "Test node connective" msgstr "测试节点资产可连接性" -#: assets/templates/assets/asset_list.html:204 +#: assets/templates/assets/asset_list.html:130 +msgid "Display only current node assets" +msgstr "仅显示当前节点资产" + +#: assets/templates/assets/asset_list.html:131 +msgid "Displays all child node assets" +msgstr "显示所有子节点资产" + +#: assets/templates/assets/asset_list.html:217 msgid "Create node failed" msgstr "创建节点失败" -#: assets/templates/assets/asset_list.html:216 +#: assets/templates/assets/asset_list.html:229 msgid "Have child node, cancel" msgstr "存在子节点,不能删除" -#: assets/templates/assets/asset_list.html:218 +#: assets/templates/assets/asset_list.html:231 msgid "Have assets, cancel" msgstr "存在资产,不能删除" -#: assets/templates/assets/asset_list.html:595 +#: assets/templates/assets/asset_list.html:631 #: assets/templates/assets/system_user_list.html:133 #: users/templates/users/user_detail.html:357 #: users/templates/users/user_detail.html:382 #: users/templates/users/user_group_list.html:81 -#: users/templates/users/user_list.html:191 +#: users/templates/users/user_list.html:194 msgid "Are you sure?" msgstr "你确认吗?" -#: assets/templates/assets/asset_list.html:596 +#: assets/templates/assets/asset_list.html:632 msgid "This will delete the selected assets !!!" msgstr "删除选择资产" -#: assets/templates/assets/asset_list.html:604 +#: assets/templates/assets/asset_list.html:640 msgid "Asset Deleted." msgstr "已被删除" -#: assets/templates/assets/asset_list.html:605 -#: assets/templates/assets/asset_list.html:610 +#: assets/templates/assets/asset_list.html:641 +#: assets/templates/assets/asset_list.html:646 msgid "Asset Delete" msgstr "删除" -#: assets/templates/assets/asset_list.html:609 +#: assets/templates/assets/asset_list.html:645 msgid "Asset Deleting failed." msgstr "删除失败" @@ -1025,6 +1032,7 @@ msgid "Create gateway" msgstr "创建网关" #: assets/templates/assets/domain_gateway_list.html:87 +#: assets/templates/assets/domain_gateway_list.html:89 #: common/templates/common/email_setting.html:58 #: common/templates/common/ldap_setting.html:58 msgid "Test connection" @@ -1073,10 +1081,23 @@ msgstr "家目录" msgid "Uid" msgstr "Uid" -#: assets/templates/assets/system_user_detail.html:174 +#: assets/templates/assets/system_user_detail.html:153 +#: assets/templates/assets/system_user_detail.html:339 +msgid "Clear auth" +msgstr "清除认证信息" + +#: assets/templates/assets/system_user_detail.html:156 +msgid "Clear" +msgstr "清除" + +#: assets/templates/assets/system_user_detail.html:183 msgid "Add to node" msgstr "添加到节点" +#: assets/templates/assets/system_user_detail.html:339 +msgid "success" +msgstr "成功" + #: assets/templates/assets/system_user_list.html:18 #: assets/views/system_user.py:45 msgid "Create system user" @@ -1123,7 +1144,7 @@ msgstr "批量更新资产" msgid "Update asset" msgstr "更新资产" -#: assets/views/asset.py:311 +#: assets/views/asset.py:314 msgid "already exists" msgstr "已经存在" @@ -1176,7 +1197,7 @@ msgid "System user asset" msgstr "系统用户集群资产" #: audits/models.py:10 audits/templates/audits/ftp_log_list.html:74 -#: terminal/models.py:126 terminal/templates/terminal/session_list.html:74 +#: terminal/models.py:130 terminal/templates/terminal/session_list.html:74 #: terminal/templates/terminal/terminal_detail.html:47 msgid "Remote addr" msgstr "远端地址" @@ -1198,8 +1219,8 @@ msgstr "成功" #: audits/templates/audits/ftp_log_list.html:78 #: ops/templates/ops/adhoc_history.html:52 #: ops/templates/ops/adhoc_history_detail.html:61 -#: ops/templates/ops/task_history.html:58 perms/models.py:26 -#: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:132 +#: ops/templates/ops/task_history.html:58 perms/models.py:36 +#: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:137 #: terminal/templates/terminal/session_list.html:77 msgid "Date start" msgstr "开始日期" @@ -1424,6 +1445,10 @@ msgstr "终端设置" msgid "Type" msgstr "类型" +#: common/validators.py:7 +msgid "Special char not allowed" +msgstr "不能包含特殊字符" + #: common/views.py:21 common/views.py:47 common/views.py:73 common/views.py:103 #: templates/_nav.html:81 msgid "Settings" @@ -1703,12 +1728,12 @@ msgstr "任务列表" msgid "Task run history" msgstr "执行历史" -#: perms/forms.py:18 users/forms.py:230 users/forms.py:235 users/forms.py:247 -#: users/forms.py:277 +#: perms/forms.py:18 users/forms.py:238 users/forms.py:243 users/forms.py:255 +#: users/forms.py:285 msgid "Select users" msgstr "选择用户" -#: perms/forms.py:34 perms/models.py:21 perms/models.py:68 +#: perms/forms.py:34 perms/models.py:31 perms/models.py:77 #: perms/templates/perms/asset_permission_list.html:55 #: perms/templates/perms/asset_permission_list.html:136 templates/_nav.html:14 #: users/models/group.py:25 users/models/user.py:48 @@ -1726,14 +1751,14 @@ msgstr "" msgid "Asset or group at least one required" msgstr "" -#: perms/models.py:27 perms/models.py:71 +#: perms/models.py:37 perms/models.py:80 #: perms/templates/perms/asset_permission_detail.html:90 #: users/models/user.py:80 users/templates/users/user_detail.html:103 #: users/templates/users/user_profile.html:105 msgid "Date expired" msgstr "失效日期" -#: perms/models.py:81 templates/_nav.html:34 +#: perms/models.py:90 templates/_nav.html:34 msgid "Asset permission" msgstr "资产授权" @@ -1770,6 +1795,10 @@ msgstr "添加节点" msgid "Join" msgstr "加入" +#: perms/templates/perms/asset_permission_create_update.html:53 +msgid "Validity period" +msgstr "有效期" + #: perms/templates/perms/asset_permission_detail.html:66 msgid "User count" msgstr "用户数量" @@ -1852,7 +1881,7 @@ msgstr "商业支持" msgid "Docs" msgstr "文档" -#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:113 +#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:121 #: users/templates/users/_user.html:39 #: users/templates/users/first_login.html:39 #: users/templates/users/user_password_update.html:37 @@ -1916,7 +1945,7 @@ msgstr "关闭" #: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44 #: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95 -#: users/views/login.py:241 users/views/login.py:289 users/views/user.py:64 +#: users/views/login.py:263 users/views/login.py:321 users/views/user.py:64 #: users/views/user.py:79 users/views/user.py:99 users/views/user.py:155 #: users/views/user.py:310 users/views/user.py:357 users/views/user.py:379 msgid "Users" @@ -1950,11 +1979,10 @@ msgstr "命令记录" msgid "Web terminal" msgstr "Web终端" -#: templates/_nav.html:51 terminal/templates/terminal/session_list.html:75 -#: terminal/views/command.py:47 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 +#: templates/_nav.html:51 terminal/views/command.py:47 +#: 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 "终端管理" @@ -2033,26 +2061,26 @@ msgstr "线程数" msgid "Boot Time" msgstr "运行时间" -#: terminal/models.py:128 terminal/templates/terminal/session_list.html:102 +#: terminal/models.py:132 terminal/templates/terminal/session_list.html:102 msgid "Replay" msgstr "回放" -#: terminal/models.py:129 terminal/templates/terminal/command_list.html:55 +#: terminal/models.py:133 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:76 msgid "Command" msgstr "命令" -#: terminal/models.py:131 +#: terminal/models.py:136 msgid "Date last active" msgstr "最后活跃日期" -#: terminal/models.py:133 +#: terminal/models.py:138 msgid "Date end" msgstr "结束日期" -#: terminal/models.py:150 +#: terminal/models.py:155 msgid "Args" msgstr "参数" @@ -2099,15 +2127,16 @@ msgstr "时长" msgid "Monitor" msgstr "监控" -#: terminal/templates/terminal/session_list.html:105 +#: terminal/templates/terminal/session_list.html:106 +#: terminal/templates/terminal/session_list.html:108 msgid "Terminate" msgstr "终断" -#: terminal/templates/terminal/session_list.html:116 +#: terminal/templates/terminal/session_list.html:120 msgid "Terminate selected" msgstr "终断所选" -#: terminal/templates/terminal/session_list.html:136 +#: terminal/templates/terminal/session_list.html:140 msgid "Terminate task send, waiting ..." msgstr "终断任务已发送,请等待" @@ -2228,11 +2257,11 @@ msgstr "" msgid "Invalid token or cache refreshed." msgstr "" -#: users/forms.py:30 +#: users/forms.py:38 msgid "MFA code" msgstr "MFA 验证码" -#: users/forms.py:41 users/models/user.py:52 +#: users/forms.py:49 users/models/user.py:52 #: users/templates/users/_select_user_modal.html:15 #: users/templates/users/user_detail.html:87 #: users/templates/users/user_list.html:25 @@ -2240,31 +2269,31 @@ msgstr "MFA 验证码" msgid "Role" msgstr "角色" -#: users/forms.py:44 users/forms.py:193 +#: users/forms.py:52 users/forms.py:201 msgid "ssh public key" msgstr "ssh公钥" -#: users/forms.py:45 users/forms.py:194 +#: users/forms.py:53 users/forms.py:202 msgid "ssh-rsa AAAA..." msgstr "" -#: users/forms.py:46 +#: users/forms.py:54 msgid "Paste user id_rsa.pub here." msgstr "复制用户公钥到这里" -#: users/forms.py:64 users/templates/users/user_detail.html:196 +#: users/forms.py:72 users/templates/users/user_detail.html:196 msgid "Join user groups" msgstr "添加到用户组" -#: users/forms.py:75 users/forms.py:208 +#: users/forms.py:83 users/forms.py:216 msgid "Public key should not be the same as your old one." msgstr "不能和原来的密钥相同" -#: users/forms.py:79 users/forms.py:212 users/serializers.py:45 +#: users/forms.py:87 users/forms.py:220 users/serializers.py:45 msgid "Not a valid ssh public key" msgstr "ssh密钥不合法" -#: users/forms.py:119 +#: users/forms.py:127 msgid "" "Tip: when enabled, you will enter the MFA binding process the next time you " "log in. you can also directly bind in \"personal information -> quick " @@ -2273,16 +2302,16 @@ msgstr "" "提示:启用之后您将会在下次登录时进入MFA绑定流程;您也可以在(个人信息->快速修" "改->更改MFA设置)中直接绑定!" -#: users/forms.py:129 +#: users/forms.py:137 msgid "* Enable MFA authentication to make the account more secure." msgstr "* 启用MFA认证,使账号更加安全." -#: users/forms.py:134 users/models/user.py:64 +#: users/forms.py:142 users/models/user.py:64 #: users/templates/users/first_login.html:45 msgid "MFA" msgstr "MFA" -#: users/forms.py:139 +#: users/forms.py:147 msgid "" "In order to protect you and your company, please keep your account, password " "and key sensitive information properly. (for example: setting complex " @@ -2291,40 +2320,41 @@ msgstr "" "为了保护您和公司的安全,请妥善保管您的账户、密码和密钥等重要敏感信息;(如:" "设置复杂密码,启用MFA认证)" -#: users/forms.py:146 users/templates/users/first_login.html:48 -#: users/templates/users/first_login.html:110 +#: users/forms.py:154 users/templates/users/first_login.html:48 +#: users/templates/users/first_login.html:107 +#: users/templates/users/first_login.html:130 msgid "Finish" msgstr "完成" -#: users/forms.py:152 +#: users/forms.py:160 msgid "Old password" msgstr "原来密码" -#: users/forms.py:157 +#: users/forms.py:165 msgid "New password" msgstr "新密码" -#: users/forms.py:162 +#: users/forms.py:170 msgid "Confirm password" msgstr "确认密码" -#: users/forms.py:172 +#: users/forms.py:180 msgid "Old password error" msgstr "原来密码错误" -#: users/forms.py:180 +#: users/forms.py:188 msgid "Password does not match" msgstr "密码不一致" -#: users/forms.py:191 +#: users/forms.py:199 msgid "Automatically configure and download the SSH key" msgstr "自动配置并下载SSH密钥" -#: users/forms.py:195 +#: users/forms.py:203 msgid "Paste your id_rsa.pub here." msgstr "复制你的公钥到这里" -#: users/forms.py:223 users/models/user.py:72 +#: users/forms.py:231 users/models/user.py:72 #: users/templates/users/first_login.html:42 #: users/templates/users/user_password_update.html:43 #: users/templates/users/user_profile.html:68 @@ -2443,11 +2473,15 @@ msgstr "首次登陆" msgid "I agree with the terms and conditions." msgstr "我同意条款和条件" -#: users/templates/users/first_login.html:100 +#: users/templates/users/first_login.html:73 +msgid "Please choose the terms and conditions." +msgstr "请选择同意条款和条件" + +#: users/templates/users/first_login.html:101 msgid "Previous" msgstr "上一步" -#: users/templates/users/first_login.html:108 +#: users/templates/users/first_login.html:105 #: users/templates/users/login_otp.html:66 #: users/templates/users/user_otp_authentication.html:22 #: users/templates/users/user_otp_enable_bind.html:19 @@ -2506,7 +2540,7 @@ msgid "Can't provide security? Please contact the administrator!" msgstr "如果不能提供MFA验证码,请联系管理员!" #: users/templates/users/reset_password.html:45 -#: users/templates/users/user_detail.html:348 users/utils.py:73 +#: users/templates/users/user_detail.html:348 users/utils.py:76 msgid "Reset password" msgstr "重置密码" @@ -2643,20 +2677,20 @@ msgstr "用户组删除" msgid "UserGroup Deleting failed." msgstr "用户组删除失败" -#: users/templates/users/user_list.html:192 +#: users/templates/users/user_list.html:195 msgid "This will delete the selected users !!!" msgstr "删除选中用户 !!!" -#: users/templates/users/user_list.html:200 +#: users/templates/users/user_list.html:203 msgid "User Deleted." msgstr "已被删除" -#: users/templates/users/user_list.html:201 -#: users/templates/users/user_list.html:206 +#: users/templates/users/user_list.html:204 +#: users/templates/users/user_list.html:209 msgid "User Delete" msgstr "删除" -#: users/templates/users/user_list.html:205 +#: users/templates/users/user_list.html:208 msgid "User Deleting failed." msgstr "用户删除失败" @@ -2710,13 +2744,15 @@ msgid "Create account successfully" msgstr "创建账户成功" #: users/utils.py:39 -#, python-format +#, fuzzy, python-format msgid "" "\n" " Hello %(name)s:\n" "
    \n" " Your account has been created successfully\n" "
    \n" +" Username: %(username)s\n" +"
    \n" " click " "here to set your password\n" "
    \n" @@ -2736,6 +2772,8 @@ msgstr "" " 你好 %(name)s:\n" "
    \n" " 恭喜您,您的账号已经创建成功
    \n" +" 用户名: %(username)s\n" +"
    \n" " 请点击这" "里设置密码
    \n" " 这个链接有效期1小时, 超过时间您可以 \n" " " -#: users/utils.py:75 +#: users/utils.py:78 #, python-format msgid "" "\n" @@ -2794,11 +2832,11 @@ msgstr "" "
    \n" " " -#: users/utils.py:106 +#: users/utils.py:109 msgid "SSH Key Reset" msgstr "重置ssh密钥" -#: users/utils.py:108 +#: users/utils.py:111 #, python-format msgid "" "\n" @@ -2823,15 +2861,15 @@ msgstr "" "
    \n" " " -#: users/utils.py:141 +#: users/utils.py:144 msgid "User not exist" msgstr "用户不存在" -#: users/utils.py:143 +#: users/utils.py:146 msgid "Disabled or expired" msgstr "禁用或失效" -#: users/utils.py:156 +#: users/utils.py:159 msgid "Password or SSH public key invalid" msgstr "密码或密钥不合法" @@ -2847,56 +2885,56 @@ msgstr "更新用户组" msgid "User group granted asset" msgstr "用户组授权资产" -#: users/views/login.py:56 +#: users/views/login.py:59 msgid "Please enable cookies and try again." msgstr "设置你的浏览器支持cookie" -#: users/views/login.py:107 users/views/user.py:464 users/views/user.py:489 +#: users/views/login.py:125 users/views/user.py:464 users/views/user.py:489 msgid "MFA code invalid" msgstr "MFA码认证失败" -#: users/views/login.py:133 +#: users/views/login.py:151 msgid "Logout success" msgstr "退出登录成功" -#: users/views/login.py:134 +#: users/views/login.py:152 msgid "Logout success, return login page" msgstr "退出登录成功,返回到登录页面" -#: users/views/login.py:150 +#: users/views/login.py:168 msgid "Email address invalid, please input again" msgstr "邮箱地址错误,重新输入" -#: users/views/login.py:163 +#: users/views/login.py:181 msgid "Send reset password message" msgstr "发送重置密码邮件" -#: users/views/login.py:164 +#: users/views/login.py:182 msgid "Send reset password mail success, login your mail box and follow it " msgstr "" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" -#: users/views/login.py:177 +#: users/views/login.py:195 msgid "Reset password success" msgstr "重置密码成功" -#: users/views/login.py:178 +#: users/views/login.py:196 msgid "Reset password success, return to login page" msgstr "重置密码成功,返回到登录页面" -#: users/views/login.py:195 users/views/login.py:208 +#: users/views/login.py:213 users/views/login.py:226 msgid "Token invalid or expired" msgstr "Token错误或失效" -#: users/views/login.py:204 +#: users/views/login.py:222 msgid "Password not same" msgstr "密码不一致" -#: users/views/login.py:241 +#: users/views/login.py:263 msgid "First login" msgstr "首次登陆" -#: users/views/login.py:290 +#: users/views/login.py:322 msgid "Login log list" msgstr "登录日志" @@ -2943,9 +2981,3 @@ msgstr "MFA 解绑成功" #: users/views/user.py:519 msgid "MFA disable success, return login page" msgstr "MFA 解绑成功,返回登录页面" - -#~ msgid "Step" -#~ msgstr "Step" - -#~ msgid "Add asset" -#~ msgstr "添加资产到节点" diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 0afcd4e72..b81188b9d 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -229,7 +229,11 @@ LOGGING = { 'django_auth_ldap': { 'handlers': ['console', 'ansible_logs'], 'level': "INFO", - } + }, + # 'django.db': { + # 'handlers': ['console', 'file'], + # 'level': 'DEBUG' + # } } } @@ -329,6 +333,9 @@ AUTH_LDAP_GROUP_SEARCH_FILTER = CONFIG.AUTH_LDAP_GROUP_SEARCH_FILTER AUTH_LDAP_GROUP_SEARCH = LDAPSearch( AUTH_LDAP_GROUP_SEARCH_OU, ldap.SCOPE_SUBTREE, AUTH_LDAP_GROUP_SEARCH_FILTER ) +AUTH_LDAP_CONNECTION_OPTIONS = { + ldap.OPT_TIMEOUT: 5 +} AUTH_LDAP_ALWAYS_UPDATE_USER = True AUTH_LDAP_BACKEND = 'django_auth_ldap.backend.LDAPBackend' diff --git a/apps/ops/api.py b/apps/ops/api.py index 0134fbd4a..35c9b8dc5 100644 --- a/apps/ops/api.py +++ b/apps/ops/api.py @@ -72,7 +72,7 @@ class CeleryTaskLogApi(generics.RetrieveAPIView): def get(self, request, *args, **kwargs): mark = request.query_params.get("mark") or str(uuid.uuid4()) - task = super().get_object() + task = self.get_object() log_path = task.full_log_path if not log_path or not os.path.isfile(log_path): diff --git a/apps/ops/templates/ops/adhoc_history_detail.html b/apps/ops/templates/ops/adhoc_history_detail.html index 16adbc4e3..b8a48d4e5 100644 --- a/apps/ops/templates/ops/adhoc_history_detail.html +++ b/apps/ops/templates/ops/adhoc_history_detail.html @@ -19,7 +19,7 @@
    {% trans 'Run history detail' %}
  • - {% trans 'Output' %} + {% trans 'Output' %}
  • diff --git a/apps/ops/templates/ops/celery_task_log.html b/apps/ops/templates/ops/celery_task_log.html index 9b0826949..13885c2cc 100644 --- a/apps/ops/templates/ops/celery_task_log.html +++ b/apps/ops/templates/ops/celery_task_log.html @@ -2,38 +2,25 @@ term.js + + -
    -
    +
    -
    - -