diff --git a/apps/__init__.py b/apps/__init__.py
index 6110e1346..7f7347e2e 100644
--- a/apps/__init__.py
+++ b/apps/__init__.py
@@ -2,4 +2,4 @@
# -*- coding: utf-8 -*-
#
-__version__ = "1.0.0"
+__version__ = "1.2.0"
diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py
index d7499760a..f123e4649 100644
--- a/apps/assets/api/node.py
+++ b/apps/assets/api/node.py
@@ -32,6 +32,7 @@ __all__ = [
'NodeViewSet', 'NodeChildrenApi',
'NodeAssetsApi', 'NodeWithAssetsApi',
'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
+ 'NodeReplaceAssetsApi',
'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
'TestNodeConnectiveApi'
]
@@ -191,6 +192,19 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView):
instance.assets.remove(*tuple(assets))
+class NodeReplaceAssetsApi(generics.UpdateAPIView):
+ serializer_class = serializers.NodeAssetsSerializer
+ queryset = Node.objects.all()
+ permission_classes = (IsSuperUser,)
+ instance = None
+
+ def perform_update(self, serializer):
+ assets = serializer.validated_data.get('assets')
+ instance = self.get_object()
+ for asset in assets:
+ asset.nodes.set([instance])
+
+
class RefreshNodeHardwareInfoApi(APIView):
permission_classes = (IsSuperUser,)
model = Node
diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py
index 1f42a2978..5b3009305 100644
--- a/apps/assets/models/asset.py
+++ b/apps/assets/models/asset.py
@@ -49,6 +49,7 @@ class Asset(models.Model):
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
port = models.IntegerField(default=22, verbose_name=_('Port'))
+ platform = models.CharField(max_length=128, choices=PLATFORM_CHOICES, default='Linux', verbose_name=_('Platform'))
domain = models.ForeignKey("assets.Domain", null=True, blank=True, related_name='assets', verbose_name=_("Domain"), on_delete=models.SET_NULL)
nodes = models.ManyToManyField('assets.Node', default=default_node, related_name='assets', verbose_name=_("Nodes"))
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
@@ -72,7 +73,6 @@ class Asset(models.Model):
disk_total = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk total'))
disk_info = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk info'))
- platform = models.CharField(max_length=128, choices=PLATFORM_CHOICES, default='Linux', verbose_name=_('Platform'))
os = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('OS'))
os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version'))
os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch'))
@@ -84,7 +84,7 @@ class Asset(models.Model):
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
def __str__(self):
- return self.hostname
+ return '{0.hostname}({0.ip})'.format(self)
@property
def is_valid(self):
diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py
index 99236f781..ad806342b 100644
--- a/apps/assets/models/node.py
+++ b/apps/assets/models/node.py
@@ -19,7 +19,7 @@ class Node(models.Model):
is_asset = False
def __str__(self):
- return self.value
+ return self.full_value
@property
def name(self):
@@ -30,7 +30,7 @@ class Node(models.Model):
if self == self.__class__.root():
return self.value
else:
- return '{}/{}'.format(self.value, self.parent.full_value)
+ return '{} / {}'.format(self.parent.full_value, self.value)
@property
def level(self):
@@ -72,7 +72,7 @@ class Node(models.Model):
assets = Asset.objects.all()
else:
nodes = self.get_family()
- assets = Asset.objects.filter(nodes__in=nodes)
+ assets = Asset.objects.filter(nodes__in=nodes).distinct()
return assets
def has_assets(self):
diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py
index e0de2cf49..bf31b8491 100644
--- a/apps/assets/models/user.py
+++ b/apps/assets/models/user.py
@@ -109,7 +109,7 @@ class SystemUser(AssetUser):
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
def __str__(self):
- return self.name
+ return '{0.name}({0.username})'.format(self)
def to_json(self):
return {
diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py
index 381e1a4cf..dd660bc42 100644
--- a/apps/assets/tasks.py
+++ b/apps/assets/tasks.py
@@ -96,6 +96,9 @@ def update_assets_hardware_info_util(assets, task_name=None):
task_name = _("更新资产硬件信息")
tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
hostname_list = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
+ if not hostname_list:
+ logger.info("Not hosts get, may be asset is not active or not unixlike platform")
+ return {}
task, created = update_or_create_ansible_task(
task_name, hosts=hostname_list, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
diff --git a/apps/assets/templates/assets/_asset_list_modal.html b/apps/assets/templates/assets/_asset_list_modal.html
index b68ab0378..c5cd48857 100644
--- a/apps/assets/templates/assets/_asset_list_modal.html
+++ b/apps/assets/templates/assets/_asset_list_modal.html
@@ -1,132 +1,125 @@
{% extends '_modal.html' %}
{% load i18n %}
+{% load static %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_id %}asset_list_modal{% endblock %}
-{#{% block modal_title%}{% trans "Please select assets" %}{% endblock %}#}
+{% block modal_title%}{% trans "Asset list" %}{% endblock %}
{% block modal_body %}
-{#
#}
-{# #}
-{# #}
-{#
#}
-
-
-
-
+{% include 'assets/_asset_list_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
{% endblock %}
\ No newline at end of file
diff --git a/apps/assets/templates/assets/domain_gateway_list.html b/apps/assets/templates/assets/domain_gateway_list.html
index 3dc82652f..581f6c08a 100644
--- a/apps/assets/templates/assets/domain_gateway_list.html
+++ b/apps/assets/templates/assets/domain_gateway_list.html
@@ -81,11 +81,6 @@ function initTable() {
var options = {
ele: $('#domain_list_table'),
columnDefs: [
- {targets: 1, createdCell: function (td, cellData, rowData) {
- var detail_btn = '
' + cellData + '';
- $(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
- }},
-
{targets: 7, createdCell: function (td, cellData, rowData) {
var update_btn = '
{% trans "Update" %}'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '
{% trans "Delete" %}'.replace('{{ DEFAULT_PK }}', cellData);
diff --git a/apps/assets/templates/assets/label_create_update.html b/apps/assets/templates/assets/label_create_update.html
index 358faaab8..b26ec6464 100644
--- a/apps/assets/templates/assets/label_create_update.html
+++ b/apps/assets/templates/assets/label_create_update.html
@@ -3,6 +3,8 @@
{% load bootstrap3 %}
{% load i18n %}
+
+
{% block form %}
+{% include 'assets/_asset_list_modal.html' %}
{% 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 3572cfd3d..a02bf1e44 100644
--- a/apps/assets/templates/assets/system_user_detail.html
+++ b/apps/assets/templates/assets/system_user_detail.html
@@ -173,7 +173,7 @@
|
@@ -187,7 +187,7 @@
{% for node in system_user.nodes.all %}
- {{ node.name }} |
+ {{ node }} |
|
diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py
index c4925059a..4429d0f24 100644
--- a/apps/assets/urls/api_urls.py
+++ b/apps/assets/urls/api_urls.py
@@ -40,6 +40,7 @@ urlpatterns = [
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'),
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$', api.NodeAssetsApi.as_view(), name='node-assets'),
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
+ url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/assets/replace/$', api.NodeReplaceAssetsApi.as_view(), name='node-replace-assets'),
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/refresh-hardware-info/$', api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'),
url(r'^v1/nodes/(?P[0-9a-zA-Z\-]{36})/test-connective/$', api.TestNodeConnectiveApi.as_view(), name='node-test-connective'),
diff --git a/apps/assets/views/asset.py b/apps/assets/views/asset.py
index 953f3c8ac..306a26a0a 100644
--- a/apps/assets/views/asset.py
+++ b/apps/assets/views/asset.py
@@ -49,6 +49,7 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
'app': _('Assets'),
'action': _('Asset list'),
'labels': Label.objects.all().order_by('name'),
+ 'nodes': Node.objects.all().order_by('-key'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
@@ -284,24 +285,26 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
if set(row) == {''}:
continue
- asset_dict = dict(zip(attr, row))
- id_ = asset_dict.pop('id', 0)
- for k, v in asset_dict.items():
+ asset_dict_raw = dict(zip(attr, row))
+ asset_dict = dict()
+ for k, v in asset_dict_raw.items():
v = v.strip()
if k == 'is_active':
- v = True if v in ['TRUE', 1, 'true'] else False
+ v = False if v in ['False', 0, 'false'] else True
elif k == 'admin_user':
v = get_object_or_none(AdminUser, name=v)
elif k in ['port', 'cpu_count', 'cpu_cores']:
try:
v = int(v)
except ValueError:
- v = 0
+ v = ''
elif k == 'domain':
v = get_object_or_none(Domain, name=v)
- asset_dict[k] = v
- asset = get_object_or_none(Asset, id=id_) if is_uuid(id_) else None
+ if v != '':
+ asset_dict[k] = v
+
+ asset = get_object_or_none(Asset, id=asset_dict.pop('id', 0))
if not asset:
try:
if len(Asset.objects.filter(hostname=asset_dict.get('hostname'))):
@@ -316,7 +319,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
failed.append('%s: %s' % (asset_dict['hostname'], str(e)))
else:
for k, v in asset_dict.items():
- if v:
+ if v != '':
setattr(asset, k, v)
try:
asset.save()
diff --git a/apps/common/fields.py b/apps/common/fields.py
index a06106cfa..355344cd9 100644
--- a/apps/common/fields.py
+++ b/apps/common/fields.py
@@ -2,11 +2,15 @@
#
import json
+from django.db import models
from django import forms
from django.utils import six
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from rest_framework import serializers
+from .utils import get_signer
+
+signer = get_signer()
class DictField(forms.Field):
@@ -46,4 +50,27 @@ class StringIDField(serializers.Field):
class StringManyToManyField(serializers.RelatedField):
def to_representation(self, value):
- return value.__str__()
\ No newline at end of file
+ return value.__str__()
+
+
+class EncryptMixin:
+ def from_db_value(self, value, expression, connection, context):
+ if value is not None:
+ return signer.unsign(value)
+ return super().from_db_value(self, value, expression, connection, context)
+
+ def get_prep_value(self, value):
+ if value is None:
+ return value
+ return signer.sign(value).decode('utf-8')
+
+
+class EncryptTextField(EncryptMixin, models.TextField):
+ description = _("Encrypt field using Secret Key")
+
+
+class EncryptCharField(EncryptMixin, models.CharField):
+ def __init__(self, *args, **kwargs):
+ kwargs['max_length'] = 2048
+ super().__init__(*args, **kwargs)
+
diff --git a/apps/i18n/zh/LC_MESSAGES/django.mo b/apps/i18n/zh/LC_MESSAGES/django.mo
index 61ef6ec21..a343d985a 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 fc8255313..5c559f24e 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-06 10:24+0800\n"
+"POT-Creation-Date: 2018-04-13 17:27+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler \n"
"Language-Team: Jumpserver team\n"
@@ -17,45 +17,57 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: assets/api/node.py:58
+#: assets/api/node.py:88
msgid "New node {}"
msgstr "新节点 {}"
-#: assets/api/node.py:133
+#: assets/api/node.py:216
msgid "更新节点资产硬件信息: {}"
msgstr ""
-#: assets/api/node.py:146
+#: assets/api/node.py:229
msgid "测试节点下资产是否可连接: {}"
msgstr ""
-#: assets/forms/asset.py:24 assets/forms/asset.py:60 assets/models/asset.py:53
-#: assets/models/user.py:102 assets/templates/assets/asset_detail.html:183
+#: assets/forms/asset.py:24 assets/models/asset.py:54 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
+#: assets/templates/assets/system_user_detail.html:166 perms/models.py:23
msgid "Nodes"
msgstr "节点管理"
-#: assets/forms/asset.py:27 assets/forms/asset.py:63 assets/forms/asset.py:103
-#: assets/forms/asset.py:107 assets/models/asset.py:57
-#: assets/models/cluster.py:19 assets/models/user.py:71
+#: 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/models/cluster.py:19 assets/models/user.py:72
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:25
msgid "Admin user"
msgstr "管理用户"
-#: assets/forms/asset.py:30 assets/forms/asset.py:66 assets/models/asset.py:81
-#: 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/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_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:70 assets/models/asset.py:52
+#: assets/forms/asset.py:34 assets/forms/asset.py:73 assets/models/asset.py:53
#: assets/models/domain.py:46
msgid "Domain"
msgstr "网域"
-#: assets/forms/asset.py:42 assets/forms/asset.py:79
+#: 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/templates/perms/asset_permission_list.html:57
+#: perms/templates/perms/asset_permission_list.html:142
+msgid "Node"
+msgstr "节点"
+
+#: assets/forms/asset.py:45 assets/forms/asset.py:85
msgid ""
"root or other NOPASSWD sudo privilege user existed in asset,If asset is "
"windows or other set any one, more see admin user left menu"
@@ -63,46 +75,41 @@ msgstr ""
"root或其他拥有NOPASSWD: ALL权限的用户, 如果是windows或其它硬件可以随意设置一"
"个, 更多信息查看左侧 `管理用户` 菜单"
-#: assets/forms/asset.py:45 assets/forms/asset.py:82
+#: assets/forms/asset.py:48 assets/forms/asset.py:88
msgid "* required Must set exact system platform, Windows, Linux ..."
msgstr "* required 必须准确设置操作系统平台,如Windows, Linux ..."
-#: assets/forms/asset.py:46 assets/forms/asset.py:83
+#: assets/forms/asset.py:49 assets/forms/asset.py:89
msgid ""
"If your have some network not connect with each other, you can set domain"
msgstr "如果有多个的互相隔离的网络,设置资产属于的网域,使用网域网关跳转登录"
-#: assets/forms/asset.py:90 assets/forms/asset.py:94 assets/forms/domain.py:16
+#: assets/forms/asset.py:96 assets/forms/asset.py:100 assets/forms/domain.py:16
#: assets/forms/label.py:15
-#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:272
+#: perms/templates/perms/asset_permission_asset.html:88
msgid "Select assets"
msgstr "选择资产"
-#: assets/forms/asset.py:99 assets/models/asset.py:51
+#: assets/forms/asset.py:105 assets/models/asset.py:51
#: 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
#: assets/templates/assets/system_user_asset.html:51
-#: assets/templates/assets/user_asset_list.html:21
msgid "Port"
msgstr "端口"
-#: assets/forms/asset.py:119 assets/templates/assets/asset_create.html:37
-msgid "Select labels"
-msgstr "选择标签"
-
-#: assets/forms/asset.py:122 assets/templates/assets/admin_user_detail.html:91
-msgid "Select nodes"
-msgstr "选择节点"
-
#: assets/forms/domain.py:14 assets/forms/label.py:13
-#: assets/models/asset.py:165 assets/templates/assets/admin_user_list.html:25
+#: assets/models/asset.py:169 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/models.py:17
+#: audits/templates/audits/ftp_log_list.html:72 perms/forms.py:37
+#: perms/models.py:22
+#: 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/templates/terminal/command_list.html:40
#: terminal/templates/terminal/command_list.html:73
@@ -125,11 +132,12 @@ 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:14 perms/templates/perms/asset_permission_detail.html:62
+#: perms/models.py:19 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/templates/terminal/terminal_list.html:29 users/models/group.py:14
-#: users/models/user.py:35 users/templates/users/_select_user_modal.html:13
+#: users/models/user.py:40 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_detail.html:63
#: users/templates/users/user_group_detail.html:55
#: users/templates/users/user_group_list.html:12
@@ -145,8 +153,8 @@ msgstr "名称"
#: 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:14
-#: users/models/authentication.py:45 users/models/user.py:34
+#: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13
+#: users/models/authentication.py:45 users/models/user.py:39
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/login.html:56
#: users/templates/users/login_log_list.html:49
@@ -161,7 +169,7 @@ msgid "Password or private key passphrase"
msgstr "密码或密钥密码"
#: assets/forms/user.py:25 assets/models/base.py:22 common/forms.py:113
-#: users/forms.py:16 users/forms.py:25 users/templates/users/login.html:59
+#: users/forms.py:15 users/forms.py:24 users/templates/users/login.html:59
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:11
#: users/templates/users/user_password_update.html:40
@@ -170,7 +178,7 @@ msgstr "密码或密钥密码"
msgid "Password"
msgstr "密码"
-#: assets/forms/user.py:28 users/models/user.py:45
+#: assets/forms/user.py:28 users/models/user.py:50
msgid "Private key"
msgstr "ssh私钥"
@@ -193,13 +201,13 @@ msgid ""
msgstr "高优先级的系统用户将会作为默认登录用户"
#: assets/models/asset.py:49 assets/models/domain.py:43
-#: assets/templates/assets/_asset_list_modal.html:21
+#: 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/domain_gateway_list.html:57
#: assets/templates/assets/system_user_asset.html:50
-#: assets/templates/assets/user_asset_list.html:20 common/forms.py:144
+#: assets/templates/assets/user_asset_list.html:46 common/forms.py:144
#: perms/templates/perms/asset_permission_asset.html:55
#: users/templates/users/login_log_list.html:52
#: users/templates/users/user_granted_asset.html:45
@@ -207,72 +215,71 @@ msgstr "高优先级的系统用户将会作为默认登录用户"
msgid "IP"
msgstr "IP"
-#: assets/models/asset.py:50 assets/templates/assets/_asset_list_modal.html:20
+#: assets/models/asset.py:50 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/system_user_asset.html:49
-#: assets/templates/assets/user_asset_list.html:19 common/forms.py:143
+#: assets/templates/assets/user_asset_list.html:45 common/forms.py:143
#: perms/templates/perms/asset_permission_asset.html:54
#: users/templates/users/user_granted_asset.html:44
#: users/templates/users/user_group_granted_asset.html:44
msgid "Hostname"
msgstr "主机名"
-#: assets/models/asset.py:54 assets/models/domain.py:48
+#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:97
+msgid "Platform"
+msgstr "系统平台"
+
+#: assets/models/asset.py:55 assets/models/domain.py:48
#: assets/models/label.py:20 assets/templates/assets/asset_detail.html:105
-#: perms/templates/perms/asset_permission_list.html:70
msgid "Is active"
msgstr "激活"
-#: assets/models/asset.py:60 assets/templates/assets/asset_detail.html:65
+#: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:65
msgid "Public IP"
msgstr "公网IP"
-#: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:113
+#: assets/models/asset.py:62 assets/templates/assets/asset_detail.html:113
msgid "Asset number"
msgstr "资产编号"
-#: assets/models/asset.py:64 assets/templates/assets/asset_detail.html:77
+#: assets/models/asset.py:65 assets/templates/assets/asset_detail.html:77
msgid "Vendor"
msgstr "制造商"
-#: assets/models/asset.py:65 assets/templates/assets/asset_detail.html:81
+#: assets/models/asset.py:66 assets/templates/assets/asset_detail.html:81
msgid "Model"
msgstr "型号"
-#: assets/models/asset.py:66 assets/templates/assets/asset_detail.html:109
+#: assets/models/asset.py:67 assets/templates/assets/asset_detail.html:109
msgid "Serial number"
msgstr "序列号"
-#: assets/models/asset.py:68
+#: assets/models/asset.py:69
msgid "CPU model"
msgstr "CPU型号"
-#: assets/models/asset.py:69
+#: assets/models/asset.py:70
msgid "CPU count"
msgstr "CPU数量"
-#: assets/models/asset.py:70
+#: assets/models/asset.py:71
msgid "CPU cores"
msgstr "CPU核数"
-#: assets/models/asset.py:71 assets/templates/assets/asset_detail.html:89
+#: assets/models/asset.py:72 assets/templates/assets/asset_detail.html:89
msgid "Memory"
msgstr "内存"
-#: assets/models/asset.py:72
+#: assets/models/asset.py:73
msgid "Disk total"
msgstr "硬盘大小"
-#: assets/models/asset.py:73
+#: assets/models/asset.py:74
msgid "Disk info"
msgstr "硬盘信息"
-#: assets/models/asset.py:75 assets/templates/assets/asset_detail.html:97
-msgid "Platform"
-msgstr "系统平台"
-
#: assets/models/asset.py:76 assets/templates/assets/asset_detail.html:101
msgid "OS"
msgstr "操作系统"
@@ -289,15 +296,21 @@ msgstr "系统架构"
msgid "Hostname raw"
msgstr "主机名原始"
+#: assets/models/asset.py:81 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/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:22 perms/models.py:79
-#: perms/templates/perms/asset_permission_detail.html:94
-#: users/models/user.py:50 users/templates/users/user_detail.html:99
+#: ops/templates/ops/adhoc_detail.html:86 perms/models.py:28 perms/models.py:72
+#: perms/templates/perms/asset_permission_detail.html:98
+#: users/models/user.py:55 users/templates/users/user_detail.html:99
msgid "Created by"
msgstr "创建者"
@@ -307,8 +320,8 @@ msgstr "创建者"
#: 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:23 perms/models.py:80
-#: perms/templates/perms/asset_permission_detail.html:90
+#: perms/models.py:29 perms/models.py:73
+#: 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"
@@ -325,10 +338,10 @@ 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:24 perms/models.py:81
-#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:26
+#: ops/models/adhoc.py:42 perms/models.py:30 perms/models.py:74
+#: 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:47 users/templates/users/user_detail.html:111
+#: users/models/user.py:52 users/templates/users/user_detail.html:111
#: users/templates/users/user_group_detail.html:67
#: users/templates/users/user_group_list.html:14
#: users/templates/users/user_profile.html:114
@@ -351,7 +364,7 @@ msgstr "带宽"
msgid "Contact"
msgstr "联系人"
-#: assets/models/cluster.py:22 users/models/user.py:41
+#: assets/models/cluster.py:22 users/models/user.py:46
#: users/templates/users/user_detail.html:76
msgid "Phone"
msgstr "手机"
@@ -377,7 +390,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:13
-#: users/models/user.py:266
+#: users/models/user.py:285
msgid "System"
msgstr "系统"
@@ -389,14 +402,14 @@ msgstr "默认Cluster"
msgid "Cluster"
msgstr "集群"
-#: assets/models/domain.py:45 assets/models/user.py:104
+#: assets/models/domain.py:45 assets/models/user.py:106
#: assets/templates/assets/domain_gateway_list.html:59
#: assets/templates/assets/system_user_detail.html:66
#: assets/templates/assets/system_user_list.html:28
msgid "Protocol"
msgstr "协议"
-#: assets/models/group.py:30 perms/models.py:18
+#: assets/models/group.py:30
msgid "Asset group"
msgstr "资产组"
@@ -406,15 +419,19 @@ 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/models.py:15
+#: audits/templates/audits/ftp_log_list.html:71 perms/forms.py:14
+#: perms/forms.py:31 perms/models.py:20
+#: 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/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:220
-#: users/models/user.py:30 users/models/user.py:254
+#: terminal/templates/terminal/session_list.html:71 users/forms.py:219
+#: users/models/user.py:30 users/models/user.py:273
#: users/templates/users/user_group_detail.html:78
-#: users/templates/users/user_group_list.html:13 users/views/user.py:334
+#: users/templates/users/user_group_list.html:13 users/views/user.py:335
msgid "User"
msgstr "用户"
@@ -431,30 +448,49 @@ msgstr "分类"
msgid "Key"
msgstr ""
-#: assets/models/user.py:103
+#: assets/models/user.py:104
+#: assets/templates/assets/_asset_group_bulk_update_modal.html:11
+#: assets/templates/assets/system_user_asset.html:21
+#: assets/views/admin_user.py:29 assets/views/admin_user.py:47
+#: assets/views/admin_user.py:63 assets/views/admin_user.py:78
+#: assets/views/admin_user.py:102 assets/views/asset.py:49
+#: assets/views/asset.py:96 assets/views/asset.py:156 assets/views/asset.py:173
+#: assets/views/asset.py:197 assets/views/domain.py:29
+#: assets/views/domain.py:45 assets/views/domain.py:61
+#: assets/views/domain.py:74 assets/views/domain.py:98
+#: assets/views/domain.py:126 assets/views/domain.py:150
+#: assets/views/label.py:26 assets/views/label.py:42 assets/views/label.py:58
+#: assets/views/system_user.py:28 assets/views/system_user.py:44
+#: assets/views/system_user.py:60 assets/views/system_user.py:74
+#: templates/_nav.html:20
+msgid "Assets"
+msgstr "资产管理"
+
+#: assets/models/user.py:105
msgid "Priority"
msgstr "优先级"
-#: assets/models/user.py:105 assets/templates/assets/_system_user.html:58
+#: assets/models/user.py:107 assets/templates/assets/_system_user.html:58
#: assets/templates/assets/system_user_detail.html:118
#: assets/templates/assets/system_user_update.html:11
msgid "Auto push"
msgstr "自动推送"
-#: assets/models/user.py:106 assets/templates/assets/system_user_detail.html:70
+#: assets/models/user.py:108 assets/templates/assets/system_user_detail.html:70
msgid "Sudo"
msgstr "Sudo"
-#: assets/models/user.py:107 assets/templates/assets/system_user_detail.html:75
+#: assets/models/user.py:109 assets/templates/assets/system_user_detail.html:75
msgid "Shell"
msgstr "Shell"
-#: assets/models/user.py:150 audits/models.py:12
+#: 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:25
-#: perms/models.py:19 perms/models.py:76
-#: perms/templates/perms/asset_permission_detail.html:136
-#: perms/templates/perms/asset_permission_list.html:69 templates/_nav.html:26
+#: audits/templates/audits/ftp_log_list.html:73 perms/forms.py:43
+#: perms/models.py:24 perms/models.py:69
+#: 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/templates/terminal/command_list.html:48
#: terminal/templates/terminal/command_list.html:74
@@ -468,41 +504,65 @@ msgstr "系统用户"
msgid "%(value)s is not an even number"
msgstr "%(value)s is not an even number"
-#: assets/tasks.py:96 assets/tasks.py:113
+#: assets/tasks.py:96 assets/tasks.py:116
msgid "更新资产硬件信息"
msgstr ""
-#: assets/tasks.py:132
+#: assets/tasks.py:135
msgid "定期更新资产硬件信息"
msgstr ""
-#: assets/tasks.py:210
+#: assets/tasks.py:213
msgid "定期测试管理账号可连接性: {}"
msgstr ""
-#: assets/tasks.py:217
+#: assets/tasks.py:220
msgid "测试管理行号可连接性: {}"
msgstr ""
-#: assets/tasks.py:227
+#: assets/tasks.py:230
msgid "测试资产可连接性"
msgstr ""
-#: assets/tasks.py:297
+#: assets/tasks.py:300
msgid "Test system user connectability: {}"
msgstr "测试系统用户可连接性: {}"
-#: assets/tasks.py:313
+#: assets/tasks.py:316
msgid "定期测试系统用户可连接性: {}"
msgstr ""
-#: assets/tasks.py:392
-msgid "推送系统用户到节点资产: {} => {}"
+#: assets/tasks.py:401
+msgid "推送系统用户到入资产: {}"
msgstr ""
-#: assets/tasks.py:433
-msgid "推送节点系统用户到新加入资产中: {}"
-msgstr ""
+#: assets/templates/assets/_admin_user_setting_modal.html:4
+#: users/templates/users/reset_password.html:57
+#: users/templates/users/user_profile.html:20
+msgid "Setting"
+msgstr "设置"
+
+#: assets/templates/assets/_admin_user_setting_modal.html:9
+#: assets/templates/assets/_asset_import_modal.html:9
+#: users/templates/users/_user_import_modal.html:10
+msgid "Template"
+msgstr "模板"
+
+#: assets/templates/assets/_admin_user_setting_modal.html:10
+#: assets/templates/assets/_asset_import_modal.html:10
+#: users/templates/users/_user_import_modal.html:11
+msgid "Download"
+msgstr "下载"
+
+#: assets/templates/assets/_admin_user_setting_modal.html:13
+#: assets/templates/assets/_asset_import_modal.html:13
+msgid "Asset csv file"
+msgstr "资产csv文件"
+
+#: assets/templates/assets/_admin_user_setting_modal.html:16
+#: assets/templates/assets/_asset_import_modal.html:16
+msgid "If set id, will use this id update asset existed"
+msgstr "如果设置了id,则会使用该行信息更新该id的资产"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:5
msgid "Update asset group"
@@ -512,28 +572,13 @@ msgstr "更新用户组"
msgid "Hint: only change the field you want to update."
msgstr "仅修改你需要更新的字段"
-#: assets/templates/assets/_asset_group_bulk_update_modal.html:11
-#: assets/templates/assets/system_user_asset.html:21
-#: assets/views/admin_user.py:29 assets/views/admin_user.py:47
-#: assets/views/admin_user.py:63 assets/views/admin_user.py:78
-#: assets/views/admin_user.py:102 assets/views/asset.py:49
-#: assets/views/asset.py:95 assets/views/asset.py:155 assets/views/asset.py:172
-#: assets/views/asset.py:196 assets/views/domain.py:29
-#: assets/views/domain.py:45 assets/views/domain.py:61
-#: assets/views/domain.py:74 assets/views/domain.py:98
-#: assets/views/domain.py:126 assets/views/domain.py:150
-#: assets/views/label.py:26 assets/views/label.py:42 assets/views/label.py:58
-#: assets/views/system_user.py:28 assets/views/system_user.py:44
-#: assets/views/system_user.py:60 assets/views/system_user.py:74
-#: templates/_nav.html:20
-msgid "Assets"
-msgstr "资产管理"
-
#: assets/templates/assets/_asset_group_bulk_update_modal.html:13
msgid "Select Asset"
msgstr "选择资产"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:21
+#: assets/templates/assets/user_asset_list.html:48
+#: users/templates/users/user_granted_asset.html:47
msgid "System users"
msgstr "系统用户"
@@ -549,181 +594,16 @@ msgstr "二次验证"
msgid "Import asset"
msgstr "导入资产"
-#: assets/templates/assets/_asset_import_modal.html:9
-#: users/templates/users/_user_import_modal.html:10
-msgid "Template"
-msgstr "模板"
-
-#: assets/templates/assets/_asset_import_modal.html:10
-#: users/templates/users/_user_import_modal.html:11
-msgid "Download"
-msgstr "下载"
-
-#: assets/templates/assets/_asset_import_modal.html:13
-msgid "Asset csv file"
-msgstr "资产csv文件"
-
-#: assets/templates/assets/_asset_import_modal.html:16
-msgid "If set id, will use this id update asset existed"
-msgstr "如果设置了id,则会使用该行信息更新该id的资产"
-
-#: assets/templates/assets/_asset_list_modal.html:22
-#: assets/templates/assets/asset_list.html:88
-#: assets/templates/assets/user_asset_list.html:22
-msgid "Hardware"
-msgstr "硬件"
-
-#: assets/templates/assets/_asset_list_modal.html:23
-#: assets/templates/assets/asset_detail.html:143
-#: assets/templates/assets/asset_list.html:89
-#: assets/templates/assets/user_asset_list.html:23 perms/models.py:20
-#: perms/models.py:77
-#: perms/templates/perms/asset_permission_create_update.html:51
-#: perms/templates/perms/asset_permission_detail.html:116
-#: terminal/templates/terminal/terminal_list.html:34
-#: users/templates/users/_select_user_modal.html:18
-#: users/templates/users/user_detail.html:128
-#: users/templates/users/user_granted_asset.html:46
-#: users/templates/users/user_group_granted_asset.html:46
-#: users/templates/users/user_list.html:27
-#: users/templates/users/user_profile.html:63
-msgid "Active"
-msgstr "激活中"
-
-#: assets/templates/assets/_asset_list_modal.html:24
-#: 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_granted_asset.html:47
-#: users/templates/users/user_group_granted_asset.html:47
-msgid "Reachable"
-msgstr "可连接"
-
-#: assets/templates/assets/_asset_list_modal.html:25
-#: assets/templates/assets/admin_user_list.html:30
-#: assets/templates/assets/asset_list.html:91
-#: assets/templates/assets/domain_gateway_list.html:62
-#: assets/templates/assets/domain_list.html:18
-#: assets/templates/assets/label_list.html:17
-#: assets/templates/assets/system_user_list.html:34
-#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64
-#: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42
-#: perms/templates/perms/asset_permission_list.html:72
-#: terminal/templates/terminal/session_list.html:80
-#: terminal/templates/terminal/terminal_list.html:36
-#: users/templates/users/user_group_list.html:15
-#: users/templates/users/user_list.html:28
-msgid "Action"
-msgstr "动作"
-
-#: assets/templates/assets/_asset_list_modal.html:34
-#: assets/templates/assets/asset_list.html:100
-#: users/templates/users/user_list.html:37
-msgid "Delete selected"
-msgstr "批量删除"
-
-#: assets/templates/assets/_asset_list_modal.html:35
-#: assets/templates/assets/asset_list.html:101
-#: users/templates/users/user_list.html:38
-msgid "Update selected"
-msgstr "批量更新"
-
-#: assets/templates/assets/_asset_list_modal.html:36
-#: assets/templates/assets/asset_list.html:103
-#: users/templates/users/user_list.html:39
-msgid "Deactive selected"
-msgstr "禁用所选"
-
-#: assets/templates/assets/_asset_list_modal.html:37
-#: assets/templates/assets/asset_list.html:104
-#: users/templates/users/user_list.html:40
-msgid "Active selected"
-msgstr "激活所选"
-
-#: assets/templates/assets/_asset_list_modal.html:41
-#: assets/templates/assets/_system_user.html:71
-#: 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_update.html:71
-#: assets/templates/assets/domain_create_update.html:17
-#: assets/templates/assets/gateway_create_update.html:59
-#: assets/templates/assets/label_create_update.html:17
-#: common/templates/common/basic_setting.html:59
-#: common/templates/common/email_setting.html:60
-#: common/templates/common/ldap_setting.html:60
-#: common/templates/common/terminal_setting.html:103
-#: perms/templates/perms/asset_permission_create_update.html:72
-#: terminal/templates/terminal/session_list.html:120
-#: terminal/templates/terminal/terminal_update.html:48
-#: users/templates/users/_user.html:44
-#: users/templates/users/first_login.html:62
-#: users/templates/users/forgot_password.html:44
-#: users/templates/users/user_bulk_update.html:24
-#: users/templates/users/user_list.html:44
-#: users/templates/users/user_password_update.html:59
-#: users/templates/users/user_profile_update.html:64
-#: users/templates/users/user_pubkey_update.html:77
-msgid "Submit"
-msgstr "提交"
-
-#: assets/templates/assets/_asset_list_modal.html:79
-#: 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:168
-#: assets/templates/assets/domain_detail.html:24
-#: assets/templates/assets/domain_detail.html:103
-#: assets/templates/assets/domain_gateway_list.html:90
-#: assets/templates/assets/domain_list.html:42
-#: assets/templates/assets/label_list.html:38
-#: assets/templates/assets/system_user_detail.html:26
-#: assets/templates/assets/system_user_list.html:88
-#: perms/templates/perms/asset_permission_detail.html:30
-#: perms/templates/perms/asset_permission_list.html:121
-#: terminal/templates/terminal/terminal_detail.html:16
-#: terminal/templates/terminal/terminal_list.html:71
-#: users/templates/users/user_detail.html:25
-#: users/templates/users/user_group_detail.html:28
-#: users/templates/users/user_group_list.html:43
-#: users/templates/users/user_list.html:76
-#: users/templates/users/user_profile.html:135
-#: users/templates/users/user_profile.html:143
-msgid "Update"
-msgstr "更新"
-
-#: assets/templates/assets/_asset_list_modal.html:80
-#: 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:169
-#: assets/templates/assets/domain_detail.html:28
-#: assets/templates/assets/domain_detail.html:104
-#: assets/templates/assets/domain_gateway_list.html:91
-#: assets/templates/assets/domain_list.html:43
-#: assets/templates/assets/label_list.html:39
-#: assets/templates/assets/system_user_detail.html:30
-#: assets/templates/assets/system_user_list.html:89
-#: ops/templates/ops/task_list.html:72
-#: perms/templates/perms/asset_permission_detail.html:34
-#: perms/templates/perms/asset_permission_list.html:122
-#: terminal/templates/terminal/terminal_list.html:73
-#: users/templates/users/user_detail.html:30
-#: users/templates/users/user_group_detail.html:32
-#: users/templates/users/user_group_list.html:45
-#: users/templates/users/user_list.html:80
-#: users/templates/users/user_list.html:84
-msgid "Delete"
-msgstr "删除"
+#: assets/templates/assets/_asset_list_modal.html:7 assets/views/asset.py:50
+#: templates/_nav.html:23
+msgid "Asset list"
+msgstr "资产列表"
#: assets/templates/assets/_system_user.html:37
#: assets/templates/assets/asset_create.html:16
#: assets/templates/assets/asset_update.html:21
#: assets/templates/assets/gateway_create_update.html:37
-#: perms/templates/perms/asset_permission_create_update.html:38
+#: perms/templates/perms/asset_permission_create_update.html:33
msgid "Basic"
msgstr "基本"
@@ -745,7 +625,7 @@ msgstr "自动生成密钥"
#: assets/templates/assets/asset_create.html:59
#: assets/templates/assets/asset_update.html:63
#: assets/templates/assets/gateway_create_update.html:53
-#: perms/templates/perms/asset_permission_create_update.html:49
+#: perms/templates/perms/asset_permission_create_update.html:45
#: terminal/templates/terminal/terminal_update.html:42
msgid "Other"
msgstr "其它"
@@ -762,7 +642,7 @@ msgstr "其它"
#: common/templates/common/email_setting.html:59
#: common/templates/common/ldap_setting.html:59
#: common/templates/common/terminal_setting.html:101
-#: perms/templates/perms/asset_permission_create_update.html:71
+#: perms/templates/perms/asset_permission_create_update.html:69
#: terminal/templates/terminal/terminal_update.html:47
#: users/templates/users/_user.html:43
#: users/templates/users/user_bulk_update.html:23
@@ -774,6 +654,33 @@ msgstr "其它"
msgid "Reset"
msgstr "重置"
+#: assets/templates/assets/_system_user.html:71
+#: 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_update.html:71
+#: assets/templates/assets/domain_create_update.html:17
+#: assets/templates/assets/gateway_create_update.html:59
+#: assets/templates/assets/label_create_update.html:17
+#: common/templates/common/basic_setting.html:59
+#: common/templates/common/email_setting.html:60
+#: 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/terminal_update.html:48
+#: users/templates/users/_user.html:44
+#: users/templates/users/first_login.html:62
+#: users/templates/users/forgot_password.html:44
+#: users/templates/users/user_bulk_update.html:24
+#: users/templates/users/user_list.html:44
+#: users/templates/users/user_password_update.html:59
+#: users/templates/users/user_profile_update.html:64
+#: users/templates/users/user_pubkey_update.html:77
+msgid "Submit"
+msgstr "提交"
+
#: assets/templates/assets/admin_user_assets.html:18
#: assets/templates/assets/admin_user_detail.html:18
#: assets/templates/assets/domain_detail.html:18
@@ -799,10 +706,19 @@ msgstr "资产列表"
msgid "Asset list of "
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
+msgid "Reachable"
+msgstr "可连接"
+
#: assets/templates/assets/admin_user_assets.html:66
#: assets/templates/assets/system_user_asset.html:64
#: assets/templates/assets/system_user_detail.html:112
-#: perms/templates/perms/asset_permission_detail.html:110
+#: perms/templates/perms/asset_permission_detail.html:114
msgid "Quick update"
msgstr "快速更新"
@@ -818,15 +734,67 @@ msgstr "测试可连接性"
msgid "Test"
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/domain_detail.html:24
+#: assets/templates/assets/domain_detail.html:103
+#: assets/templates/assets/domain_gateway_list.html:90
+#: assets/templates/assets/domain_list.html:42
+#: assets/templates/assets/label_list.html:38
+#: assets/templates/assets/system_user_detail.html:26
+#: assets/templates/assets/system_user_list.html:88
+#: perms/templates/perms/asset_permission_detail.html:30
+#: perms/templates/perms/asset_permission_list.html:191
+#: terminal/templates/terminal/terminal_detail.html:16
+#: terminal/templates/terminal/terminal_list.html:71
+#: users/templates/users/user_detail.html:25
+#: users/templates/users/user_group_detail.html:28
+#: users/templates/users/user_group_list.html:43
+#: users/templates/users/user_list.html:76
+#: users/templates/users/user_profile.html:135
+#: users/templates/users/user_profile.html:143
+msgid "Update"
+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/domain_detail.html:28
+#: assets/templates/assets/domain_detail.html:104
+#: assets/templates/assets/domain_gateway_list.html:91
+#: assets/templates/assets/domain_list.html:43
+#: assets/templates/assets/label_list.html:39
+#: assets/templates/assets/system_user_detail.html:30
+#: assets/templates/assets/system_user_list.html:89
+#: ops/templates/ops/task_list.html:72
+#: perms/templates/perms/asset_permission_detail.html:34
+#: perms/templates/perms/asset_permission_list.html:192
+#: terminal/templates/terminal/terminal_list.html:73
+#: users/templates/users/user_detail.html:30
+#: users/templates/users/user_group_detail.html:32
+#: users/templates/users/user_group_list.html:45
+#: users/templates/users/user_list.html:80
+#: users/templates/users/user_list.html:84
+msgid "Delete"
+msgstr "删除"
+
#: assets/templates/assets/admin_user_detail.html:83
msgid "Replace node assets admin user with this"
msgstr "替换资产的管理员"
+#: assets/templates/assets/admin_user_detail.html:91
+#: perms/templates/perms/asset_permission_asset.html:116
+msgid "Select nodes"
+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/system_user_list.html:138 templates/_modal.html:16
+#: 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:339
#: users/templates/users/user_detail.html:364
@@ -855,20 +823,23 @@ msgstr "不可达"
msgid "Ratio"
msgstr "比例"
-#: assets/templates/assets/asset_create.html:29
-#: assets/templates/assets/asset_update.html:34 perms/models.py:74
-#: perms/templates/perms/asset_permission_create_update.html:40
-#: perms/templates/perms/asset_permission_list.html:67
-msgid "Node"
-msgstr "节点"
+#: assets/templates/assets/admin_user_list.html:30
+#: assets/templates/assets/asset_list.html:91
+#: assets/templates/assets/domain_gateway_list.html:62
+#: assets/templates/assets/domain_list.html:18
+#: assets/templates/assets/label_list.html:17
+#: assets/templates/assets/system_user_list.html:34
+#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64
+#: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42
+#: perms/templates/perms/asset_permission_list.html:60
+#: terminal/templates/terminal/session_list.html:80
+#: terminal/templates/terminal/terminal_list.html:36
+#: users/templates/users/user_group_list.html:15
+#: users/templates/users/user_list.html:28
+msgid "Action"
+msgstr "动作"
-#: assets/templates/assets/asset_create.html:35
-#: assets/templates/assets/asset_list.html:75
-#: assets/templates/assets/asset_update.html:40
-msgid "Label"
-msgstr "标签"
-
-#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:197
+#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:198
msgid "Asset detail"
msgstr "资产详情"
@@ -893,6 +864,23 @@ msgstr "创建日期"
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
+#: 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
+#: terminal/templates/terminal/terminal_list.html:34
+#: users/templates/users/_select_user_modal.html:18
+#: users/templates/users/user_detail.html:128
+#: users/templates/users/user_granted_asset.html:46
+#: users/templates/users/user_group_granted_asset.html:46
+#: users/templates/users/user_list.html:27
+#: users/templates/users/user_profile.html:63
+msgid "Active"
+msgstr "激活中"
+
#: assets/templates/assets/asset_detail.html:160
msgid "Refresh hardware"
msgstr "更新硬件信息"
@@ -906,8 +894,7 @@ msgstr "刷新"
msgid "Update successfully!"
msgstr "更新成功"
-#: assets/templates/assets/asset_list.html:63
-#: assets/templates/assets/asset_list.html:120 assets/views/asset.py:96
+#: assets/templates/assets/asset_list.html:63 assets/views/asset.py:97
msgid "Create asset"
msgstr "创建资产"
@@ -921,35 +908,63 @@ msgstr "导入"
msgid "Export"
msgstr "导出"
+#: assets/templates/assets/asset_list.html:88
+msgid "Hardware"
+msgstr "硬件"
+
+#: assets/templates/assets/asset_list.html:100
+#: users/templates/users/user_list.html:37
+msgid "Delete selected"
+msgstr "批量删除"
+
+#: assets/templates/assets/asset_list.html:101
+#: users/templates/users/user_list.html:38
+msgid "Update selected"
+msgstr "批量更新"
+
#: assets/templates/assets/asset_list.html:102
msgid "Remove from this node"
msgstr "从节点移除"
+#: assets/templates/assets/asset_list.html:103
+#: users/templates/users/user_list.html:39
+msgid "Deactive selected"
+msgstr "禁用所选"
+
+#: assets/templates/assets/asset_list.html:104
+#: users/templates/users/user_list.html:40
+msgid "Active selected"
+msgstr "激活所选"
+
#: assets/templates/assets/asset_list.html:121
-msgid "Add asset"
-msgstr "添加资产到节点"
-
-#: assets/templates/assets/asset_list.html:122
-msgid "Refresh node hardware info"
-msgstr "更新节点资产硬件信息"
-
-#: assets/templates/assets/asset_list.html:123
-msgid "Test node connective"
-msgstr "测试节点资产可连接性"
-
-#: assets/templates/assets/asset_list.html:125
msgid "Add node"
msgstr "新建节点"
-#: assets/templates/assets/asset_list.html:126
+#: assets/templates/assets/asset_list.html:122
msgid "Rename node"
msgstr "重命名节点"
-#: assets/templates/assets/asset_list.html:128
+#: assets/templates/assets/asset_list.html:123
msgid "Delete node"
msgstr "删除节点"
-#: assets/templates/assets/asset_list.html:203
+#: assets/templates/assets/asset_list.html:125
+msgid "Add assets to node"
+msgstr "添加资产到节点"
+
+#: assets/templates/assets/asset_list.html:126
+msgid "Move assets to node"
+msgstr "移动资产到节点"
+
+#: assets/templates/assets/asset_list.html:128
+msgid "Refresh node hardware info"
+msgstr "更新节点资产硬件信息"
+
+#: assets/templates/assets/asset_list.html:129
+msgid "Test node connective"
+msgstr "测试节点资产可连接性"
+
+#: assets/templates/assets/asset_list.html:204
msgid "Create node failed"
msgstr "创建节点失败"
@@ -957,6 +972,10 @@ msgstr "创建节点失败"
msgid "Have child node, cancel"
msgstr "存在子节点,不能删除"
+#: assets/templates/assets/asset_list.html:218
+msgid "Have assets, cancel"
+msgstr "存在资产,不能删除"
+
#: assets/templates/assets/asset_list.html:595
#: assets/templates/assets/system_user_list.html:133
#: users/templates/users/user_detail.html:334
@@ -1088,10 +1107,6 @@ msgstr "删除系统用户"
msgid "System Users Deleting failed."
msgstr "系统用户删除失败"
-#: assets/templates/assets/user_asset_list.html:24
-msgid "Connective"
-msgstr "连接性"
-
#: assets/views/admin_user.py:30
msgid "Admin user list"
msgstr "管理用户列表"
@@ -1104,23 +1119,19 @@ msgstr "更新管理用户"
msgid "Admin user detail"
msgstr "管理用户详情"
-#: assets/views/asset.py:50 templates/_nav.html:23
-msgid "Asset list"
-msgstr "资产列表"
-
-#: assets/views/asset.py:62 templates/_nav_user.html:4
+#: assets/views/asset.py:63 templates/_nav_user.html:4
msgid "My assets"
msgstr "我的资产"
-#: assets/views/asset.py:156
+#: assets/views/asset.py:157
msgid "Bulk update asset"
msgstr "批量更新资产"
-#: assets/views/asset.py:173
+#: assets/views/asset.py:174
msgid "Update asset"
msgstr "更新资产"
-#: assets/views/asset.py:300
+#: assets/views/asset.py:311
msgid "already exists"
msgstr "已经存在"
@@ -1182,18 +1193,33 @@ msgstr "远端地址"
msgid "Operate"
msgstr "操作"
-#: audits/models.py:14 audits/templates/audits/ftp_log_list.html:76
+#: audits/models.py:14 audits/templates/audits/ftp_log_list.html:56
+#: audits/templates/audits/ftp_log_list.html:76
msgid "Filename"
msgstr "文件名"
-#: audits/templates/audits/ftp_log_list.html:77
+#: audits/models.py:15 audits/templates/audits/ftp_log_list.html:77
+#: ops/templates/ops/task_list.html:39
+msgid "Success"
+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 terminal/models.py:132
+#: ops/templates/ops/task_history.html:58 perms/models.py:26
+#: perms/templates/perms/asset_permission_detail.html:86 terminal/models.py:132
#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
+#: audits/views.py:50 templates/_nav.html:64
+msgid "Audits"
+msgstr "日志审计"
+
+#: audits/views.py:51 templates/_nav.html:67
+msgid "FTP log"
+msgstr "FTP日志"
+
#: common/api.py:18
msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查"
@@ -1655,10 +1681,6 @@ msgstr "搜索"
msgid "Versions"
msgstr "版本"
-#: ops/templates/ops/task_list.html:39
-msgid "Success"
-msgstr "成功"
-
#: ops/templates/ops/task_list.html:40
#: users/templates/users/login_log_list.html:54
msgid "Date"
@@ -1685,24 +1707,37 @@ msgstr "任务列表"
msgid "Task run history"
msgstr "执行历史"
-#: perms/forms.py:22 perms/models.py:16 perms/models.py:75
-#: perms/templates/perms/asset_permission_list.html:68 templates/_nav.html:14
-#: users/models/group.py:25 users/models/user.py:37
+#: perms/forms.py:18 users/forms.py:176 users/forms.py:181 users/forms.py:193
+#: users/forms.py:223
+msgid "Select users"
+msgstr "选择用户"
+
+#: perms/forms.py:34 perms/models.py:21 perms/models.py:68
+#: 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:42
#: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_detail.html:179
#: users/templates/users/user_list.html:26
msgid "User group"
msgstr "用户组"
-#: perms/models.py:21 perms/models.py:78
-#: perms/templates/perms/asset_permission_detail.html:86
-#: perms/templates/perms/asset_permission_list.html:71 users/models/user.py:49
-#: users/templates/users/user_detail.html:95
+#: perms/forms.py:56
+msgid "User or group at least one required"
+msgstr ""
+
+#: perms/forms.py:65
+msgid "Asset or group at least one required"
+msgstr ""
+
+#: perms/models.py:27 perms/models.py:71
+#: perms/templates/perms/asset_permission_detail.html:90
+#: users/models/user.py:54 users/templates/users/user_detail.html:95
#: users/templates/users/user_profile.html:96
msgid "Date expired"
msgstr "失效日期"
-#: perms/models.py:88 templates/_nav.html:34
+#: perms/models.py:81 templates/_nav.html:34
msgid "Asset permission"
msgstr "资产授权"
@@ -1723,7 +1758,7 @@ msgid "Add asset to this permission"
msgstr "添加资产"
#: perms/templates/perms/asset_permission_asset.html:97
-#: perms/templates/perms/asset_permission_detail.html:153
+#: perms/templates/perms/asset_permission_detail.html:157
#: perms/templates/perms/asset_permission_user.html:97
#: perms/templates/perms/asset_permission_user.html:125
#: users/templates/users/user_group_detail.html:95
@@ -1731,12 +1766,8 @@ msgid "Add"
msgstr "添加"
#: perms/templates/perms/asset_permission_asset.html:108
-msgid "Add asset group to this permission"
-msgstr "添加资产组"
-
-#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:275
-msgid "Select asset groups"
-msgstr "选择资产组"
+msgid "Add node to this permission"
+msgstr "添加节点"
#: perms/templates/perms/asset_permission_asset.html:125
#: users/templates/users/user_detail.html:196
@@ -1756,18 +1787,18 @@ msgid "Asset count"
msgstr "资产数量"
#: perms/templates/perms/asset_permission_detail.html:78
-msgid "Asset group count"
-msgstr "资产组数量"
+msgid "Node count"
+msgstr "节点数量"
#: perms/templates/perms/asset_permission_detail.html:82
msgid "System user count"
msgstr "系统用户数量"
-#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:278
+#: perms/templates/perms/asset_permission_detail.html:148
msgid "Select system users"
msgstr "选择系统用户"
-#: perms/templates/perms/asset_permission_list.html:58
+#: perms/templates/perms/asset_permission_list.html:46
msgid "Create permission"
msgstr "创建授权规则"
@@ -1792,22 +1823,31 @@ msgstr "添加用户组"
msgid "Select user groups"
msgstr "选择用户组"
-#: perms/views.py:23 perms/views.py:47 perms/views.py:67 templates/_nav.html:31
+#: perms/views.py:25 perms/views.py:55 perms/views.py:70 perms/views.py:85
+#: perms/views.py:120 perms/views.py:151 templates/_nav.html:31
msgid "Perms"
msgstr "权限管理"
-#: perms/views.py:24
+#: perms/views.py:26
msgid "Asset permission list"
msgstr "资产授权列表"
-#: perms/views.py:48
+#: perms/views.py:56
msgid "Create asset permission"
msgstr "创建权限规则"
-#: perms/views.py:68
+#: perms/views.py:71 perms/views.py:86
msgid "Update asset permission"
msgstr "更新资产授权"
+#: perms/views.py:121
+msgid "Asset permission user list"
+msgstr "资产授权用户列表"
+
+#: perms/views.py:152
+msgid "Asset permission asset list"
+msgstr "资产授权资产列表"
+
#: templates/_header_bar.html:18
msgid "Supports"
msgstr "商业支持"
@@ -1816,13 +1856,13 @@ msgstr "商业支持"
msgid "Docs"
msgstr "文档"
-#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:94
+#: templates/_header_bar.html:37 templates/_nav_user.html:9 users/forms.py:93
#: users/templates/users/_user.html:36
#: users/templates/users/user_password_update.html:37
#: users/templates/users/user_profile.html:17
#: users/templates/users/user_profile_update.html:37
#: users/templates/users/user_profile_update.html:57
-#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:317
+#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:318
msgid "Profile"
msgstr "个人信息"
@@ -1873,15 +1913,15 @@ msgstr ""
"\"%(user_pubkey_update)s\"> 链接 更新\n"
" "
-#: templates/_modal.html:15
+#: templates/_modal.html:21
msgid "Close"
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:209 users/views/login.py:258 users/views/user.py:60
-#: users/views/user.py:75 users/views/user.py:94 users/views/user.py:150
-#: users/views/user.py:305 users/views/user.py:352 users/views/user.py:374
+#: users/views/login.py:205 users/views/login.py:254 users/views/user.py:60
+#: users/views/user.py:75 users/views/user.py:95 users/views/user.py:151
+#: users/views/user.py:306 users/views/user.py:353 users/views/user.py:375
msgid "Users"
msgstr "用户管理"
@@ -1925,14 +1965,6 @@ msgstr "终端管理"
msgid "Job Center"
msgstr "作业中心"
-#: templates/_nav.html:64
-msgid "Audits"
-msgstr "日志审计"
-
-#: templates/_nav.html:67
-msgid "FTP log"
-msgstr "FTP日志"
-
#: templates/captcha/image.html:3
msgid "Play CAPTCHA as audio file"
msgstr "语言播放验证码"
@@ -2199,7 +2231,7 @@ msgstr ""
msgid "Invalid token or cache refreshed."
msgstr ""
-#: users/forms.py:28 users/models/user.py:38
+#: users/forms.py:27 users/models/user.py:43
#: users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:87
#: users/templates/users/user_list.html:25
@@ -2207,55 +2239,55 @@ msgstr ""
msgid "Role"
msgstr "角色"
-#: users/forms.py:30 users/forms.py:140
+#: users/forms.py:29 users/forms.py:139
msgid "ssh public key"
msgstr "ssh公钥"
-#: users/forms.py:31 users/forms.py:141
+#: users/forms.py:30 users/forms.py:140
msgid "ssh-rsa AAAA..."
msgstr ""
-#: users/forms.py:32
+#: users/forms.py:31
msgid "Paste user id_rsa.pub here."
msgstr "复制用户公钥到这里"
-#: users/forms.py:50 users/templates/users/user_detail.html:187
+#: users/forms.py:49 users/templates/users/user_detail.html:187
msgid "Join user groups"
msgstr "添加到用户组"
-#: users/forms.py:60 users/forms.py:155
+#: users/forms.py:59 users/forms.py:154
msgid "Public key should not be the same as your old one."
msgstr "不能和原来的密钥相同"
-#: users/forms.py:64 users/forms.py:159 users/serializers.py:42
+#: users/forms.py:63 users/forms.py:158 users/serializers.py:42
msgid "Not a valid ssh public key"
msgstr "ssh密钥不合法"
-#: users/forms.py:100
+#: users/forms.py:99
msgid "Old password"
msgstr "原来密码"
-#: users/forms.py:105
+#: users/forms.py:104
msgid "New password"
msgstr "新密码"
-#: users/forms.py:110
+#: users/forms.py:109
msgid "Confirm password"
msgstr "确认密码"
-#: users/forms.py:120
+#: users/forms.py:119
msgid "Old password error"
msgstr "原来密码错误"
-#: users/forms.py:128
+#: users/forms.py:127
msgid "Password does not match"
msgstr "密码不一致"
-#: users/forms.py:142
+#: users/forms.py:141
msgid "Paste your id_rsa.pub here."
msgstr "复制你的公钥到这里"
-#: users/forms.py:170 users/models/user.py:46
+#: users/forms.py:169 users/models/user.py:51
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_profile.html:71
#: users/templates/users/user_profile_update.html:43
@@ -2263,10 +2295,6 @@ msgstr "复制你的公钥到这里"
msgid "Public key"
msgstr "ssh公钥"
-#: users/forms.py:177 users/forms.py:182 users/forms.py:194 users/forms.py:224
-msgid "Select users"
-msgstr "选择用户"
-
#: users/models/authentication.py:36
msgid "Private Token"
msgstr "ssh密钥"
@@ -2291,7 +2319,7 @@ msgstr "Agent"
msgid "Date login"
msgstr "登录日期"
-#: users/models/user.py:29 users/models/user.py:262
+#: users/models/user.py:29 users/models/user.py:281
msgid "Administrator"
msgstr "管理员"
@@ -2299,24 +2327,36 @@ msgstr "管理员"
msgid "Application"
msgstr "应用程序"
-#: users/models/user.py:36 users/templates/users/user_detail.html:71
+#: users/models/user.py:34
+msgid "Disable"
+msgstr "禁用"
+
+#: users/models/user.py:35
+msgid "Enable"
+msgstr "启用"
+
+#: users/models/user.py:36
+msgid "Force enable"
+msgstr "强制启用"
+
+#: users/models/user.py:41 users/templates/users/user_detail.html:71
#: users/templates/users/user_profile.html:59
msgid "Email"
msgstr "邮件"
-#: users/models/user.py:39
+#: users/models/user.py:44
msgid "Avatar"
msgstr "头像"
-#: users/models/user.py:40 users/templates/users/user_detail.html:82
+#: users/models/user.py:45 users/templates/users/user_detail.html:82
msgid "Wechat"
msgstr "微信"
-#: users/models/user.py:42
+#: users/models/user.py:47
msgid "Enable OTP"
msgstr "二次验证"
-#: users/models/user.py:265
+#: users/models/user.py:284
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
@@ -2416,11 +2456,6 @@ msgstr "重置密码"
msgid "Password again"
msgstr "再次输入密码"
-#: users/templates/users/reset_password.html:57
-#: users/templates/users/user_profile.html:20
-msgid "Setting"
-msgstr "设置"
-
#: users/templates/users/user_create.html:4
#: users/templates/users/user_list.html:16 users/views/user.py:75
msgid "Create user"
@@ -2431,7 +2466,7 @@ msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_detail.html:19
-#: users/templates/users/user_granted_asset.html:18 users/views/user.py:151
+#: users/templates/users/user_granted_asset.html:18 users/views/user.py:152
msgid "User detail"
msgstr "用户详情"
@@ -2550,8 +2585,8 @@ msgstr "用户删除失败"
msgid "OTP"
msgstr ""
-#: users/templates/users/user_profile.html:100 users/views/user.py:180
-#: users/views/user.py:234
+#: users/templates/users/user_profile.html:100 users/views/user.py:181
+#: users/views/user.py:235
msgid "User groups"
msgstr "用户组"
@@ -2587,7 +2622,7 @@ msgstr "更新密钥"
msgid "Or reset by server"
msgstr "或者重置并下载密钥"
-#: users/templates/users/user_update.html:4 users/views/user.py:94
+#: users/templates/users/user_update.html:4 users/views/user.py:95
msgid "Update user"
msgstr "更新用户"
@@ -2733,78 +2768,78 @@ msgstr "更新用户组"
msgid "User group granted asset"
msgstr "用户组授权资产"
-#: users/views/login.py:57
+#: users/views/login.py:55
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
-#: users/views/login.py:99
+#: users/views/login.py:97
msgid "Logout success"
msgstr "退出登录成功"
-#: users/views/login.py:100
+#: users/views/login.py:98
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
-#: users/views/login.py:116
+#: users/views/login.py:114
msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入"
-#: users/views/login.py:129
+#: users/views/login.py:127
msgid "Send reset password message"
msgstr "发送重置密码邮件"
-#: users/views/login.py:130
+#: users/views/login.py:128
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
-#: users/views/login.py:144
+#: users/views/login.py:142
msgid "Reset password success"
msgstr "重置密码成功"
-#: users/views/login.py:145
+#: users/views/login.py:143
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
-#: users/views/login.py:162 users/views/login.py:175
+#: users/views/login.py:160 users/views/login.py:173
msgid "Token invalid or expired"
msgstr "Token错误或失效"
-#: users/views/login.py:171
+#: users/views/login.py:169
msgid "Password not same"
msgstr "密码不一致"
-#: users/views/login.py:209
+#: users/views/login.py:205
msgid "First login"
msgstr "首次登陆"
-#: users/views/login.py:259
+#: users/views/login.py:255
msgid "Login log list"
msgstr "登录日志"
-#: users/views/user.py:104
+#: users/views/user.py:105
msgid "Bulk update user success"
msgstr "批量更新用户成功"
-#: users/views/user.py:209
+#: users/views/user.py:210
msgid "Invalid file."
msgstr "文件不合法"
-#: users/views/user.py:306
+#: users/views/user.py:307
msgid "User granted assets"
msgstr "用户授权资产"
-#: users/views/user.py:335
+#: users/views/user.py:336
msgid "Profile setting"
msgstr "个人信息设置"
-#: users/views/user.py:353
+#: users/views/user.py:354
msgid "Password update"
msgstr "密码更新"
-#: users/views/user.py:375
+#: users/views/user.py:376
msgid "Public key update"
msgstr "密钥更新"
-#~ msgid "Task has been send, seen left asset status"
-#~ msgstr "任务已下发,查看左侧资产状态"
+#~ msgid "Add asset"
+#~ msgstr "添加资产到节点"
diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py
index ced4797d5..8300ebe06 100644
--- a/apps/jumpserver/urls.py
+++ b/apps/jumpserver/urls.py
@@ -36,9 +36,10 @@ urlpatterns = [
url(r'^captcha/', include('captcha.urls')),
]
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
+ + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+
if settings.DEBUG:
urlpatterns += [
url(r'^docs/', schema_view, name="docs"),
- ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) \
- + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
-
+ ]
diff --git a/apps/perms/api.py b/apps/perms/api.py
index 1303e4128..be69d6158 100644
--- a/apps/perms/api.py
+++ b/apps/perms/api.py
@@ -3,7 +3,7 @@
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView, Response
-from rest_framework.generics import ListAPIView, get_object_or_404
+from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView
from rest_framework import viewsets
from common.utils import set_or_append_attr_bulk
@@ -98,6 +98,11 @@ class UserGrantedNodesApi(ListAPIView):
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
return nodes.keys()
+ def get_permissions(self):
+ if self.kwargs.get('pk') is None:
+ self.permission_classes = (IsValidUser,)
+ return super().get_permissions()
+
class UserGrantedNodesWithAssetsApi(ListAPIView):
permission_classes = (IsSuperUserOrAppUser,)
@@ -246,3 +251,77 @@ class ValidateUserAssetPermissionView(APIView):
return Response({'msg': True}, status=200)
else:
return Response({'msg': False}, status=403)
+
+
+class AssetPermissionRemoveUserApi(RetrieveUpdateAPIView):
+ """
+ 将用户从授权中移除,Detail页面会调用
+ """
+ permission_classes = (IsSuperUser,)
+ serializer_class = serializers.AssetPermissionUpdateUserSerializer
+ queryset = AssetPermission.objects.all()
+
+ def update(self, request, *args, **kwargs):
+ perm = self.get_object()
+ serializer = self.serializer_class(data=request.data)
+ if serializer.is_valid():
+ users = serializer.validated_data.get('users')
+ if users:
+ perm.users.remove(*tuple(users))
+ return Response({"msg": "ok"})
+ else:
+ return Response({"error": serializer.errors})
+
+
+class AssetPermissionAddUserApi(RetrieveUpdateAPIView):
+ permission_classes = (IsSuperUser,)
+ serializer_class = serializers.AssetPermissionUpdateUserSerializer
+ queryset = AssetPermission.objects.all()
+
+ def update(self, request, *args, **kwargs):
+ perm = self.get_object()
+ serializer = self.serializer_class(data=request.data)
+ if serializer.is_valid():
+ users = serializer.validated_data.get('users')
+ if users:
+ perm.users.add(*tuple(users))
+ return Response({"msg": "ok"})
+ else:
+ return Response({"error": serializer.errors})
+
+
+class AssetPermissionRemoveAssetApi(RetrieveUpdateAPIView):
+ """
+ 将用户从授权中移除,Detail页面会调用
+ """
+ permission_classes = (IsSuperUser,)
+ serializer_class = serializers.AssetPermissionUpdateAssetSerializer
+ queryset = AssetPermission.objects.all()
+
+ def update(self, request, *args, **kwargs):
+ perm = self.get_object()
+ serializer = self.serializer_class(data=request.data)
+ if serializer.is_valid():
+ assets = serializer.validated_data.get('assets')
+ if assets:
+ perm.assets.remove(*tuple(assets))
+ return Response({"msg": "ok"})
+ else:
+ return Response({"error": serializer.errors})
+
+
+class AssetPermissionAddAssetApi(RetrieveUpdateAPIView):
+ permission_classes = (IsSuperUser,)
+ serializer_class = serializers.AssetPermissionUpdateAssetSerializer
+ queryset = AssetPermission.objects.all()
+
+ def update(self, request, *args, **kwargs):
+ perm = self.get_object()
+ serializer = self.serializer_class(data=request.data)
+ if serializer.is_valid():
+ assets = serializer.validated_data.get('assets')
+ if assets:
+ perm.assets.add(*tuple(assets))
+ return Response({"msg": "ok"})
+ else:
+ return Response({"error": serializer.errors})
diff --git a/apps/perms/forms.py b/apps/perms/forms.py
index 060812d4a..c418160dd 100644
--- a/apps/perms/forms.py
+++ b/apps/perms/forms.py
@@ -4,10 +4,23 @@ from __future__ import absolute_import, unicode_literals
from django import forms
from django.utils.translation import ugettext_lazy as _
+from .hands import User
from .models import AssetPermission
class AssetPermissionForm(forms.ModelForm):
+ users = forms.ModelMultipleChoiceField(
+ queryset=User.objects.exclude(role=User.ROLE_APP),
+ label=_("User"),
+ widget=forms.SelectMultiple(
+ attrs={
+ 'class': 'select2',
+ 'data-placeholder': _('Select users')
+ }
+ ),
+ required=False,
+ )
+
class Meta:
model = AssetPermission
exclude = (
diff --git a/apps/perms/models.py b/apps/perms/models.py
index 6609cd8e2..954cbe5f6 100644
--- a/apps/perms/models.py
+++ b/apps/perms/models.py
@@ -4,7 +4,7 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
-from common.utils import date_expired_default
+from common.utils import date_expired_default, set_or_append_attr_bulk
class ValidManager(models.Manager):
@@ -45,6 +45,22 @@ class AssetPermission(models.Model):
return True
return False
+ def get_all_users(self):
+ users = set(self.users.all())
+ for group in self.user_groups.all():
+ _users = group.users.all()
+ set_or_append_attr_bulk(_users, 'inherit', group.name)
+ users.update(set(_users))
+ return users
+
+ def get_all_assets(self):
+ assets = set(self.assets.all())
+ for node in self.nodes.all():
+ _assets = node.get_all_assets()
+ set_or_append_attr_bulk(_assets, 'inherit', node.value)
+ assets.update(set(_assets))
+ return assets
+
class NodePermission(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
diff --git a/apps/perms/templates/perms/asset_permission_asset.html b/apps/perms/templates/perms/asset_permission_asset.html
index 12369574d..364d7e60f 100644
--- a/apps/perms/templates/perms/asset_permission_asset.html
+++ b/apps/perms/templates/perms/asset_permission_asset.html
@@ -57,12 +57,12 @@
- {% for asset in page_obj %}
+ {% for asset in object_list %}
{{ asset.hostname }} |
{{ asset.ip }} |
-
+
|
{% endfor %}
@@ -85,9 +85,9 @@
- {% for system_user in system_users %}
+ {% for system_user in object.system_users.all %}
- {{ system_user.name }} |
+ {{ system_user }} |
|
@@ -179,7 +183,7 @@
jumpserver.system_users_selected = {};
function updateSystemUser(system_users) {
- var the_url = "{% url 'api-perms:asset-permission-detail' pk=asset_permission.id %}";
+ var the_url = "{% url 'api-perms:asset-permission-detail' pk=object.id %}";
var body = {
system_users: Object.assign([], system_users)
};
@@ -203,7 +207,7 @@ $(document).ready(function () {
.on('click', '.btn-delete-perm', function () {
var $this = $(this);
var name = "{{ asset_permission.name }}";
- var uid = "{{ asset_permission.id }}";
+ var uid = "{{ object.id }}";
var the_url = '{% url "api-perms:asset-permission-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
var redirect_url = "{% url 'perms:asset-permission-list' %}";
objectDelete($this, name, the_url, redirect_url);
@@ -238,7 +242,7 @@ $(document).ready(function () {
updateSystemUser(system_users);
$tr.remove()
}).on('click', '#is_active', function () {
- var the_url = '{% url "api-perms:asset-permission-detail" pk=asset_permission.id %}';
+ var the_url = '{% url "api-perms:asset-permission-detail" pk=object.id %}';
var checked = $(this).prop('checked');
var body = {
'is_active': checked
diff --git a/apps/perms/templates/perms/asset_permission_user.html b/apps/perms/templates/perms/asset_permission_user.html
index bee5b0e35..5d490bc28 100644
--- a/apps/perms/templates/perms/asset_permission_user.html
+++ b/apps/perms/templates/perms/asset_permission_user.html
@@ -57,12 +57,12 @@
- {% for user in page_obj %}
+ {% for user in object_list %}
{{ user.name }} |
{{ user.username }} |
-
+
|
{% endfor %}
@@ -87,7 +87,7 @@
|
@@ -115,7 +115,7 @@
|
@@ -127,9 +127,9 @@
- {% for user_group in user_groups %}
+ {% for user_group in asset_permission.user_groups.all %}
- {{ user_group.name }} |
+ {{ user_group }} |
|
diff --git a/apps/perms/urls/api_urls.py b/apps/perms/urls/api_urls.py
index d114e4f0b..f15450141 100644
--- a/apps/perms/urls/api_urls.py
+++ b/apps/perms/urls/api_urls.py
@@ -11,20 +11,50 @@ router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'asset-permi
urlpatterns = [
# 查询某个用户授权的资产和资产组
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'),
- url(r'^v1/user/assets/$', api.UserGrantedAssetsApi.as_view(), name='my-assets'),
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes/$', api.UserGrantedNodesApi.as_view(), name='user-nodes'),
- url(r'^v1/user/nodes/$', api.UserGrantedNodesApi.as_view(), name='my-nodes'),
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedNodeAssetsApi.as_view(), name='user-node-assets'),
- url(r'^v1/user/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedNodeAssetsApi.as_view(), name='my-node-assets'),
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes-assets'),
- url(r'^v1/user/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='my-nodes-assets'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/assets/$',
+ api.UserGrantedAssetsApi.as_view(), name='user-assets'),
+ url(r'^v1/user/assets/$', api.UserGrantedAssetsApi.as_view(),
+ name='my-assets'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes/$',
+ api.UserGrantedNodesApi.as_view(), name='user-nodes'),
+ url(r'^v1/user/nodes/$', api.UserGrantedNodesApi.as_view(),
+ name='my-nodes'),
+ url(
+ r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$',
+ api.UserGrantedNodeAssetsApi.as_view(), name='user-node-assets'),
+ url(r'^v1/user/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$',
+ api.UserGrantedNodeAssetsApi.as_view(), name='my-node-assets'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/nodes-assets/$',
+ api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes-assets'),
+ url(r'^v1/user/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(),
+ name='my-nodes-assets'),
# 查询某个用户组授权的资产和资产组
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes/$', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'),
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGroupGrantedNodesWithAssetsApi.as_view(), name='user-group-nodes-assets'),
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedNodeAssetsApi.as_view(), name='user-group-node-assets'),
+ url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/assets/$',
+ api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
+ url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes/$',
+ api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'),
+ url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes-assets/$',
+ api.UserGroupGrantedNodesWithAssetsApi.as_view(),
+ name='user-group-nodes-assets'),
+ url(
+ r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes/(?P[0-9a-zA-Z\-]{36})/assets/$',
+ api.UserGroupGrantedNodeAssetsApi.as_view(),
+ name='user-group-node-assets'),
+
+ # 用户和资产授权变更
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/remove/$',
+ api.AssetPermissionRemoveUserApi.as_view(),
+ name='asset-permission-remove-user'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/add/$',
+ api.AssetPermissionAddUserApi.as_view(),
+ name='asset-permission-add-user'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/remove/$',
+ api.AssetPermissionRemoveAssetApi.as_view(),
+ name='asset-permission-remove-asset'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/add/$',
+ api.AssetPermissionAddAssetApi.as_view(),
+ name='asset-permission-add-asset'),
# 验证用户是否有某个资产和系统用户的权限
url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'),
diff --git a/apps/perms/urls/views_urls.py b/apps/perms/urls/views_urls.py
index a1acc570c..5c3fa3b48 100644
--- a/apps/perms/urls/views_urls.py
+++ b/apps/perms/urls/views_urls.py
@@ -11,8 +11,8 @@ urlpatterns = [
url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/update$', views.AssetPermissionUpdateView.as_view(), name='asset-permission-update'),
url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})$', views.AssetPermissionDetailView.as_view(),name='asset-permission-detail'),
url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/delete$', views.AssetPermissionDeleteView.as_view(), name='asset-permission-delete'),
- # url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/user$', views.AssetPermissionUserView.as_view(), name='asset-permission-user-list'),
- # url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/asset$', views.AssetPermissionAssetView.as_view(), name='asset-permission-asset-list'),
+ url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/user$', views.AssetPermissionUserView.as_view(), name='asset-permission-user-list'),
+ url(r'^asset-permission/(?P[0-9a-zA-Z\-]{36})/asset$', views.AssetPermissionAssetView.as_view(), name='asset-permission-asset-list'),
]
diff --git a/apps/perms/views.py b/apps/perms/views.py
index 2aa1ddd8b..8babf519f 100644
--- a/apps/perms/views.py
+++ b/apps/perms/views.py
@@ -4,12 +4,12 @@ from __future__ import unicode_literals, absolute_import
from django.utils.translation import ugettext as _
from django.views.generic import ListView, CreateView, UpdateView, DetailView
-from django.views.generic.edit import DeleteView
+from django.views.generic.edit import DeleteView, SingleObjectMixin
from django.urls import reverse_lazy
from django.conf import settings
-from common.utils import is_uuid
-from .hands import AdminUserRequiredMixin, Node, Asset
+from common.mixins import AdminUserRequiredMixin
+from .hands import Node, Asset, SystemUser, User, UserGroup
from .models import AssetPermission
from .forms import AssetPermissionForm
@@ -83,7 +83,11 @@ class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
context = {
'app': _('Perms'),
- 'action': _('Update asset permission')
+ 'action': _('Update asset permission'),
+ 'system_users_remain': SystemUser.objects.exclude(
+ granted_by_permissions=self.object
+ ),
+
}
kwargs.update(context)
return super().get_context_data(**kwargs)
@@ -95,3 +99,59 @@ class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView):
success_url = reverse_lazy('perms:asset-permission-list')
+class AssetPermissionUserView(AdminUserRequiredMixin,
+ SingleObjectMixin,
+ ListView):
+ template_name = 'perms/asset_permission_user.html'
+ context_object_name = 'asset_permission'
+ paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
+ object = None
+
+ def get(self, request, *args, **kwargs):
+ self.object = self.get_object(queryset=AssetPermission.objects.all())
+ return super().get(request, *args, **kwargs)
+
+ def get_queryset(self):
+ queryset = self.object.get_all_users()
+ return queryset
+
+ def get_context_data(self, **kwargs):
+ context = {
+ 'app': _('Perms'),
+ 'action': _('Asset permission user list'),
+ 'users_remain': User.objects.exclude(asset_permissions=self.object)
+ .exclude(role=User.ROLE_APP),
+ 'user_groups_remain': UserGroup.objects.exclude(
+ asset_permissions=self.object
+ )
+ }
+ kwargs.update(context)
+ return super().get_context_data(**kwargs)
+
+
+class AssetPermissionAssetView(AdminUserRequiredMixin,
+ SingleObjectMixin,
+ ListView):
+ template_name = 'perms/asset_permission_asset.html'
+ context_object_name = 'asset_permission'
+ paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
+ object = None
+
+ def get(self, request, *args, **kwargs):
+ self.object = self.get_object(queryset=AssetPermission.objects.all())
+ return super().get(request, *args, **kwargs)
+
+ def get_queryset(self):
+ queryset = self.object.get_all_assets()
+ return queryset
+
+ def get_context_data(self, **kwargs):
+ assets_granted = self.get_queryset()
+ context = {
+ 'app': _('Perms'),
+ 'action': _('Asset permission asset list'),
+ 'assets_remain': Asset.objects.exclude(id__in=[a.id for a in assets_granted]),
+ 'nodes_remain': Node.objects.exclude(granted_by_permissions=self.object),
+ }
+ kwargs.update(context)
+ return super().get_context_data(**kwargs)
\ No newline at end of file
diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js
index f2f8b8f55..461455085 100644
--- a/apps/static/js/jumpserver.js
+++ b/apps/static/js/jumpserver.js
@@ -307,7 +307,7 @@ jumpserver.initDataTable = function (options) {
last: "»"
}
},
- lengthMenu: [[15, 25, 50, -1], [15, 25, 50, "All"]]
+ lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]]
});
table.on('select', function(e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$();
@@ -446,22 +446,56 @@ jumpserver.initServerSideDataTable = function (options) {
last: "»"
}
},
- lengthMenu: [[15, 25, 50], [15, 25, 50]]
+ lengthMenu: [[10, 15, 25, 50], [10, 15, 25, 50]]
});
+ table.selected = [];
table.on('select', function(e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$();
$node.find('input.ipt_check').prop('checked', true);
- jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true
+ jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true;
+ if (type === 'row') {
+ var rows = table.rows(indexes).data();
+ $.each(rows, function (id, row) {
+ if (row.id){
+ table.selected.push(row.id)
+ }
+ })
+ }
}).on('deselect', function(e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$();
$node.find('input.ipt_check').prop('checked', false);
- jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false
+ jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false;
+ if (type === 'row') {
+ var rows = table.rows(indexes).data();
+ $.each(rows, function (id, row) {
+ if (row.id){
+ var index = table.selected.indexOf(row.id);
+ if (index > -1){
+ table.selected.splice(index, 1)
+ }
+ }
+ })
+ }
}).
on('draw', function(){
$('#op').html(options.op_html || '');
$('#uc').html(options.uc_html || '');
+ var table_data = [];
+ $.each(table.rows().data(), function (id, row) {
+ if (row.id) {
+ table_data.push(row.id)
+ }
+ });
+
+ $.each(table.selected, function (id, data) {
+ var index = table_data.indexOf(data);
+ if (index > -1){
+ table.rows(index).select()
+ }
+ });
});
- $('.ipt_check_all').on('click', function() {
+ var table_id = table.settings()[0].sTableId;
+ $('#' + table_id + ' .ipt_check_all').on('click', function() {
if ($(this).prop("checked")) {
$(this).closest('table').find('.ipt_check').prop('checked', true);
table.rows({search:'applied', page:'current'}).select();
diff --git a/apps/templates/_footer.html b/apps/templates/_footer.html
index c9641c4fa..dbe60e1bc 100644
--- a/apps/templates/_footer.html
+++ b/apps/templates/_footer.html
@@ -1,6 +1,6 @@