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
+
+ 
### 开始使用
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" %}
{% 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 @@
+
+ {% trans 'Display only current node assets' %}
+ {% trans 'Displays all child node assets' %}
@@ -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' %}
-
+
{% trans 'Auto push' %}: |
@@ -130,8 +130,8 @@
|
-
{% if system_user.auto_push %}
+
{% trans 'Push system user now' %}: |
@@ -139,8 +139,8 @@
|
-
{% endif %}
+
{% 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
+
+
- |