From 3e78d627f8260da8b7ea0f7db90af968e10d462c Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 17 Nov 2020 18:27:09 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix(perms):=20=E4=BD=9C=E4=B8=9A=E4=B8=AD?= =?UTF-8?q?=E5=BF=83-=E6=89=B9=E9=87=8F=E5=91=BD=E4=BB=A4-=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E5=B7=A6=E4=BE=A7=E8=B5=84=E4=BA=A7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=9C=AA=E7=AD=9B=E9=80=89=EF=BC=8C=E8=BF=98=E6=98=AF=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E8=B5=84=E4=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/models/favorite_asset.py | 8 +- .../user_permission/user_permission_nodes.py | 11 +- .../user_permission_nodes_with_assets.py | 111 ++++++++++++++++-- apps/perms/utils/asset/user_permission.py | 38 ++++-- 4 files changed, 139 insertions(+), 29 deletions(-) diff --git a/apps/assets/models/favorite_asset.py b/apps/assets/models/favorite_asset.py index 3497a075c..b176c8105 100644 --- a/apps/assets/models/favorite_asset.py +++ b/apps/assets/models/favorite_asset.py @@ -20,9 +20,13 @@ class FavoriteAsset(CommonModelMixin): return cls.objects.filter(user=user).values_list('asset', flat=True) @classmethod - def get_user_favorite_assets(cls, user): + def get_user_favorite_assets(cls, user, asset_perms_id=None): from assets.models import Asset from perms.utils.asset.user_permission import get_user_granted_all_assets - asset_ids = get_user_granted_all_assets(user).values_list('id', flat=True) + asset_ids = get_user_granted_all_assets( + user, + via_mapping_node=False, + asset_perms_id=asset_perms_id + ).values_list('id', flat=True) query_name = cls.asset.field.related_query_name() return Asset.org_objects.filter(**{f'{query_name}__user_id': user.id}, id__in=asset_ids).distinct() diff --git a/apps/perms/api/asset/user_permission/user_permission_nodes.py b/apps/perms/api/asset/user_permission/user_permission_nodes.py index 72e7d4e33..58af37090 100644 --- a/apps/perms/api/asset/user_permission/user_permission_nodes.py +++ b/apps/perms/api/asset/user_permission/user_permission_nodes.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # import abc +from django.conf import settings from rest_framework.generics import ( ListAPIView ) @@ -16,7 +17,8 @@ from perms.utils.asset.user_permission import ( get_indirect_granted_node_children, get_user_granted_nodes_list_via_mapping_node, get_top_level_granted_nodes, - rebuild_user_tree_if_need, + rebuild_user_tree_if_need, get_favorite_node, + get_ungrouped_node ) @@ -113,7 +115,12 @@ class UserGrantedNodesMixin: user: User def get_nodes(self): - return get_user_granted_nodes_list_via_mapping_node(self.user) + nodes = [] + if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: + nodes.append(get_ungrouped_node(self.user)) + nodes.append(get_favorite_node(self.user)) + nodes.extend(get_user_granted_nodes_list_via_mapping_node(self.user)) + return nodes # ------------------------------------------ diff --git a/apps/perms/api/asset/user_permission/user_permission_nodes_with_assets.py b/apps/perms/api/asset/user_permission/user_permission_nodes_with_assets.py index 63e46aefd..28491ca8a 100644 --- a/apps/perms/api/asset/user_permission/user_permission_nodes_with_assets.py +++ b/apps/perms/api/asset/user_permission/user_permission_nodes_with_assets.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- # +from itertools import chain + from rest_framework.generics import ListAPIView from rest_framework.request import Request from rest_framework.response import Response -from django.db.models import F +from django.db.models import F, Value, CharField, Q +from django.conf import settings from orgs.utils import tmp_to_root_org from common.permissions import IsValidUser @@ -14,9 +17,12 @@ from perms.utils.asset.user_permission import ( get_user_direct_granted_assets, get_top_level_granted_nodes, get_user_granted_nodes_list_via_mapping_node, get_user_granted_all_assets, rebuild_user_tree_if_need, - get_user_all_assetpermissions_id, + get_user_all_assetpermissions_id, get_favorite_node, + get_ungrouped_node, compute_tmp_mapping_node_from_perm, + TMP_GRANTED_FIELD, count_direct_granted_node_assets, + count_node_all_granted_assets ) - +from perms.models import AssetPermission from assets.models import Asset, FavoriteAsset from assets.api import SerializeToTreeNodeMixin from perms.hands import Node @@ -27,6 +33,78 @@ logger = get_logger(__name__) class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView): permission_classes = (IsValidUser,) + def add_ungrouped_resource(self, data: list, user, asset_perms_id): + if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: + return + + ungrouped_node = get_ungrouped_node(user, asset_perms_id=asset_perms_id) + direct_granted_assets = get_user_direct_granted_assets( + user, asset_perms_id=asset_perms_id + ).annotate( + parent_key=Value(ungrouped_node.key, output_field=CharField()) + ).prefetch_related('platform') + + data.extend(self.serialize_nodes([ungrouped_node], with_asset_amount=True)) + data.extend(self.serialize_assets(direct_granted_assets)) + + def add_favorite_resource(self, data: list, user, asset_perms_id): + favorite_node = get_favorite_node(user, asset_perms_id) + favorite_assets = FavoriteAsset.get_user_favorite_assets( + user, asset_perms_id=asset_perms_id + ).annotate( + parent_key=Value(favorite_node.key, output_field=CharField()) + ).prefetch_related('platform') + + data.extend(self.serialize_nodes([favorite_node], with_asset_amount=True)) + data.extend(self.serialize_assets(favorite_assets)) + + def add_node_filtered_by_system_user(self, data: list, user, asset_perms_id): + tmp_nodes = compute_tmp_mapping_node_from_perm(user, asset_perms_id=asset_perms_id) + granted_nodes_key = [] + for _node in tmp_nodes: + _granted = getattr(_node, TMP_GRANTED_FIELD, False) + if not _granted: + if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: + assets_amount = count_direct_granted_node_assets(user, _node.key, asset_perms_id) + else: + assets_amount = count_node_all_granted_assets(user, _node.key, asset_perms_id) + _node.assets_amount = assets_amount + else: + granted_nodes_key.append(_node.key) + + # 查询他们的子节点 + q = Q() + for _key in granted_nodes_key: + q |= Q(key__startswith=f'{_key}:') + + if q: + descendant_nodes = Node.objects.filter(q).distinct() + else: + descendant_nodes = Node.objects.none() + + data.extend(self.serialize_nodes(chain(tmp_nodes, descendant_nodes), with_asset_amount=True)) + + def add_assets(self, data: list, user, asset_perms_id): + if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: + all_assets = get_user_granted_all_assets( + user, + via_mapping_node=False, + include_direct_granted_assets=False, + asset_perms_id=asset_perms_id + ) + else: + all_assets = get_user_granted_all_assets( + user, + via_mapping_node=False, + include_direct_granted_assets=True, + asset_perms_id=asset_perms_id + ) + + all_assets = all_assets.annotate( + parent_key=F('nodes__key') + ).prefetch_related('platform') + data.extend(self.serialize_assets(all_assets)) + @tmp_to_root_org() def list(self, request: Request, *args, **kwargs): """ @@ -38,16 +116,25 @@ class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView): """ user = request.user - rebuild_user_tree_if_need(request, user) - all_nodes = get_user_granted_nodes_list_via_mapping_node(user) - all_assets = get_user_granted_all_assets(user) - all_assets = all_assets.annotate(parent_key=F('nodes__key')) - all_assets = all_assets.prefetch_related('platform') + data = [] + asset_perms_id = get_user_all_assetpermissions_id(user) - data = [ - *self.serialize_nodes(all_nodes, with_asset_amount=True), - *self.serialize_assets(all_assets) - ] + system_user_id = request.query_params.get('system_user') + if system_user_id: + asset_perms_id = list(AssetPermission.objects.valid().filter( + id__in=asset_perms_id, system_users__id=system_user_id, actions__gt=0 + ).values_list('id', flat=True).distinct()) + + self.add_ungrouped_resource(data, user, asset_perms_id) + self.add_favorite_resource(data, user, asset_perms_id) + + if system_user_id: + self.add_node_filtered_by_system_user(data, user, asset_perms_id) + else: + all_nodes = get_user_granted_nodes_list_via_mapping_node(user) + data.extend(self.serialize_nodes(all_nodes, with_asset_amount=True)) + + self.add_assets(data, user, asset_perms_id) return Response(data=data) diff --git a/apps/perms/utils/asset/user_permission.py b/apps/perms/utils/asset/user_permission.py index 91ad87143..274a27d4d 100644 --- a/apps/perms/utils/asset/user_permission.py +++ b/apps/perms/utils/asset/user_permission.py @@ -311,8 +311,12 @@ def get_user_granted_nodes_list_via_mapping_node(user): return all_nodes -def get_user_granted_all_assets(user, via_mapping_node=True): - asset_perms_id = get_user_all_assetpermissions_id(user) +def get_user_granted_all_assets( + user, via_mapping_node=True, + include_direct_granted_assets=True, asset_perms_id=None): + if asset_perms_id is None: + asset_perms_id = get_user_all_assetpermissions_id(user) + if via_mapping_node: granted_node_keys = UserGrantedMappingNode.objects.filter( user=user, granted=True, @@ -328,10 +332,16 @@ def get_user_granted_all_assets(user, via_mapping_node=True): granted_node_q |= Q(nodes__key__startswith=f'{_key}:') granted_node_q |= Q(nodes__key=_key) - assets__id = get_user_direct_granted_assets(user, asset_perms_id).values_list('id', flat=True) + if include_direct_granted_assets: + assets__id = get_user_direct_granted_assets(user, asset_perms_id).values_list('id', flat=True) + q = granted_node_q | Q(id__in=list(assets__id)) + else: + q = granted_node_q - q = granted_node_q | Q(id__in=list(assets__id)) - return Asset.org_objects.filter(q).distinct() + if q: + return Asset.org_objects.filter(q).distinct() + else: + return Asset.org_objects.none() def get_node_all_granted_assets(user: User, key): @@ -484,13 +494,15 @@ def get_user_direct_granted_assets(user, asset_perms_id=None): return assets -def count_user_direct_granted_assets(user): - count = get_user_direct_granted_assets(user).values_list('id').count() +def count_user_direct_granted_assets(user, asset_perms_id=None): + count = get_user_direct_granted_assets( + user, asset_perms_id=asset_perms_id + ).values_list('id').count() return count -def get_ungrouped_node(user): - assets_amount = count_user_direct_granted_assets(user) +def get_ungrouped_node(user, asset_perms_id=None): + assets_amount = count_user_direct_granted_assets(user, asset_perms_id) return Node( id=UNGROUPED_NODE_KEY, key=UNGROUPED_NODE_KEY, @@ -499,10 +511,10 @@ def get_ungrouped_node(user): ) -def get_favorite_node(user): - assets_amount = FavoriteAsset.get_user_favorite_assets(user)\ - .values_list('id')\ - .count() +def get_favorite_node(user, asset_perms_id=None): + assets_amount = FavoriteAsset.get_user_favorite_assets( + user, asset_perms_id=asset_perms_id + ).values_list('id').count() return Node( id=FAVORITE_NODE_KEY, key=FAVORITE_NODE_KEY, From d0b19f20c3bded350b43871123e293b6b0db3386 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 17 Nov 2020 17:48:28 +0800 Subject: [PATCH 2/5] =?UTF-8?q?perf(tickets):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=94=B3=E8=AF=B7=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/zh/LC_MESSAGES/django.mo | Bin 62498 -> 62514 bytes apps/locale/zh/LC_MESSAGES/django.po | 190 +++++++++++++------------ apps/tickets/api/request_asset_perm.py | 28 ++-- 3 files changed, 116 insertions(+), 102 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index be42b8acb01bcba33997dae0b6e34b35e0343571..801d192a25d63277c13e07a5f7992a9312c557b3 100644 GIT binary patch delta 13374 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 delta 13397 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 N=H=UXYfoC;{|DNFkX`@) diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index a4ab5ca13..cefa4bf2a 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/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: 2020-11-12 10:49+0800\n" +"POT-Creation-Date: 2020-11-17 17:24+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -35,7 +35,7 @@ msgstr "远程应用" #: applications/models/application.py:122 #: applications/models/database_app.py:18 applications/models/k8s_app.py:11 #: applications/models/remote_app.py:21 assets/models/asset.py:149 -#: assets/models/base.py:232 assets/models/cluster.py:18 +#: assets/models/base.py:234 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:21 assets/models/domain.py:21 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:23 perms/models/base.py:48 settings/models.py:27 @@ -54,7 +54,7 @@ msgstr "远程应用" #: users/templates/users/user_profile.html:51 #: users/templates/users/user_pubkey_update.html:57 #: users/templates/users/user_remote_app_permission.html:36 -#: xpack/plugins/cloud/models.py:37 +#: xpack/plugins/cloud/models.py:36 msgid "Name" msgstr "名称" @@ -87,7 +87,7 @@ msgstr "类型" #: applications/models/application.py:128 #: applications/models/database_app.py:33 applications/models/k8s_app.py:18 #: applications/models/remote_app.py:45 assets/models/asset.py:154 -#: assets/models/asset.py:230 assets/models/base.py:237 +#: assets/models/asset.py:230 assets/models/base.py:239 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:23 #: assets/models/cmd_filter.py:57 assets/models/domain.py:22 #: assets/models/domain.py:55 assets/models/group.py:23 @@ -101,8 +101,8 @@ msgstr "类型" #: users/templates/users/user_group_detail.html:62 #: users/templates/users/user_group_list.html:16 #: users/templates/users/user_profile.html:138 -#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:56 -#: xpack/plugins/cloud/models.py:151 xpack/plugins/gathered_user/models.py:26 +#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:54 +#: xpack/plugins/cloud/models.py:149 xpack/plugins/gathered_user/models.py:26 msgid "Comment" msgstr "备注" @@ -159,7 +159,7 @@ msgstr "Kubernetes应用" #: users/templates/users/user_asset_permission.html:70 #: users/templates/users/user_granted_remote_app.html:36 #: xpack/plugins/change_auth_plan/models.py:282 -#: xpack/plugins/cloud/models.py:280 +#: xpack/plugins/cloud/models.py:278 msgid "Asset" msgstr "资产" @@ -178,27 +178,27 @@ msgid "Parameters" msgstr "参数" #: applications/models/remote_app.py:39 assets/models/asset.py:228 -#: assets/models/base.py:240 assets/models/cluster.py:28 +#: assets/models/base.py:242 assets/models/cluster.py:28 #: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:60 #: assets/models/group.py:21 common/db/models.py:67 common/mixins/models.py:49 #: orgs/models.py:24 orgs/models.py:400 perms/models/base.py:54 #: users/models/user.py:546 users/serializers/group.py:35 #: users/templates/users/user_detail.html:97 -#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:59 -#: xpack/plugins/cloud/models.py:157 xpack/plugins/gathered_user/models.py:30 +#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:57 +#: xpack/plugins/cloud/models.py:155 xpack/plugins/gathered_user/models.py:30 msgid "Created by" msgstr "创建者" # msgid "Created by" # msgstr "创建者" #: applications/models/remote_app.py:42 assets/models/asset.py:229 -#: assets/models/base.py:238 assets/models/cluster.py:26 +#: assets/models/base.py:240 assets/models/cluster.py:26 #: assets/models/domain.py:24 assets/models/gathered_user.py:19 #: assets/models/group.py:22 assets/models/label.py:25 common/db/models.py:69 #: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27 #: orgs/models.py:25 orgs/models.py:398 perms/models/base.py:55 #: users/models/group.py:18 users/templates/users/user_group_detail.html:58 -#: xpack/plugins/cloud/models.py:62 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:60 xpack/plugins/cloud/models.py:158 msgid "Date created" msgstr "创建日期" @@ -232,7 +232,7 @@ msgstr "目标URL" #: applications/serializers/remote_app.py:60 #: applications/serializers/remote_app.py:70 #: applications/serializers/remote_app.py:78 -#: applications/serializers/remote_app.py:85 assets/models/base.py:233 +#: applications/serializers/remote_app.py:85 assets/models/base.py:235 #: assets/models/gathered_user.py:15 audits/models.py:99 #: authentication/forms.py:11 #: authentication/templates/authentication/login.html:21 @@ -250,7 +250,7 @@ msgstr "用户名" #: applications/serializers/remote_app.py:61 #: applications/serializers/remote_app.py:71 #: applications/serializers/remote_app.py:79 -#: applications/serializers/remote_app.py:86 assets/models/base.py:234 +#: applications/serializers/remote_app.py:86 assets/models/base.py:236 #: assets/serializers/asset_user.py:71 authentication/forms.py:13 #: authentication/templates/authentication/login.html:29 #: authentication/templates/authentication/xpack_login.html:109 @@ -334,6 +334,7 @@ msgstr "系统平台" #: assets/models/asset.py:191 assets/serializers/asset_user.py:45 #: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51 +#: tickets/api/request_asset_perm.py:63 #: tickets/serializers/request_asset_perm.py:25 #: users/templates/users/_granted_assets.html:25 #: users/templates/users/user_asset_permission.html:157 @@ -365,7 +366,7 @@ msgstr "激活" #: assets/models/asset.py:203 assets/models/cluster.py:19 #: assets/models/user.py:66 templates/_nav.html:44 -#: xpack/plugins/cloud/models.py:144 xpack/plugins/cloud/serializers.py:115 +#: xpack/plugins/cloud/models.py:142 xpack/plugins/cloud/serializers.py:84 msgid "Admin user" msgstr "管理用户" @@ -453,19 +454,19 @@ msgstr "版本" msgid "AuthBook" msgstr "" -#: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72 +#: assets/models/base.py:237 xpack/plugins/change_auth_plan/models.py:72 #: xpack/plugins/change_auth_plan/models.py:197 #: xpack/plugins/change_auth_plan/models.py:292 msgid "SSH private key" msgstr "SSH密钥" -#: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:75 +#: assets/models/base.py:238 xpack/plugins/change_auth_plan/models.py:75 #: xpack/plugins/change_auth_plan/models.py:193 #: xpack/plugins/change_auth_plan/models.py:288 msgid "SSH public key" msgstr "SSH公钥" -#: assets/models/base.py:239 assets/models/gathered_user.py:20 +#: assets/models/base.py:241 assets/models/gathered_user.py:20 #: common/db/models.py:70 common/mixins/models.py:51 ops/models/adhoc.py:39 #: orgs/models.py:399 msgid "Date updated" @@ -630,7 +631,7 @@ msgstr "默认资产组" msgid "User" msgstr "用户" -#: assets/models/label.py:19 assets/models/node.py:396 settings/models.py:28 +#: assets/models/label.py:19 assets/models/node.py:398 settings/models.py:28 msgid "Value" msgstr "值" @@ -638,28 +639,28 @@ msgstr "值" msgid "New node" msgstr "新节点" -#: assets/models/node.py:302 users/templates/users/_granted_assets.html:130 +#: assets/models/node.py:304 users/templates/users/_granted_assets.html:130 msgid "empty" msgstr "空" -#: assets/models/node.py:395 perms/models/asset_permission.py:144 +#: assets/models/node.py:397 perms/models/asset_permission.py:144 msgid "Key" msgstr "键" -#: assets/models/node.py:397 +#: assets/models/node.py:399 msgid "Full value" msgstr "全称" -#: assets/models/node.py:400 perms/models/asset_permission.py:148 +#: assets/models/node.py:402 perms/models/asset_permission.py:148 msgid "Parent key" msgstr "ssh私钥" -#: assets/models/node.py:409 assets/serializers/system_user.py:190 +#: assets/models/node.py:411 assets/serializers/system_user.py:190 #: perms/forms/asset_permission.py:92 perms/forms/asset_permission.py:99 #: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:158 -#: xpack/plugins/cloud/models.py:140 xpack/plugins/cloud/serializers.py:116 +#: xpack/plugins/cloud/models.py:138 xpack/plugins/cloud/serializers.py:85 msgid "Node" msgstr "节点" @@ -722,7 +723,7 @@ msgstr "家目录" msgid "System groups" msgstr "用户组" -#: assets/models/user.py:206 audits/models.py:39 +#: assets/models/user.py:211 audits/models.py:39 #: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49 #: perms/models/application_permission.py:22 #: perms/models/asset_permission.py:94 @@ -731,6 +732,7 @@ msgstr "用户组" #: perms/models/remote_app_permission.py:16 templates/_nav.html:45 #: terminal/backends/command/models.py:20 #: terminal/backends/command/serializers.py:14 terminal/models.py:194 +#: tickets/api/request_asset_perm.py:64 #: tickets/serializers/request_asset_perm.py:27 #: users/templates/users/_granted_assets.html:27 #: users/templates/users/user_asset_permission.html:42 @@ -930,25 +932,25 @@ msgstr "更新节点资产硬件信息: {}" msgid "Gather assets users" msgstr "收集资产上的用户" -#: assets/tasks/push_system_user.py:183 +#: assets/tasks/push_system_user.py:184 #: assets/tasks/system_user_connectivity.py:89 msgid "System user is dynamic: {}" msgstr "系统用户是动态的: {}" -#: assets/tasks/push_system_user.py:214 +#: assets/tasks/push_system_user.py:215 msgid "Start push system user for platform: [{}]" msgstr "推送系统用户到平台: [{}]" -#: assets/tasks/push_system_user.py:215 +#: assets/tasks/push_system_user.py:216 #: assets/tasks/system_user_connectivity.py:81 msgid "Hosts count: {}" msgstr "主机数量: {}" -#: assets/tasks/push_system_user.py:233 assets/tasks/push_system_user.py:251 +#: assets/tasks/push_system_user.py:235 assets/tasks/push_system_user.py:253 msgid "Push system users to assets: {}" msgstr "推送系统用户到入资产: {}" -#: assets/tasks/push_system_user.py:241 +#: assets/tasks/push_system_user.py:243 msgid "Push system users to asset: {}({}) => {}" msgstr "推送系统用户到入资产: {}({}) => {}" @@ -1103,7 +1105,7 @@ msgstr "启用" msgid "-" msgstr "" -#: audits/models.py:96 xpack/plugins/cloud/models.py:215 +#: audits/models.py:96 xpack/plugins/cloud/models.py:213 msgid "Failed" msgstr "失败" @@ -1133,13 +1135,13 @@ msgid "MFA" msgstr "多因子认证" #: audits/models.py:105 xpack/plugins/change_auth_plan/models.py:303 -#: xpack/plugins/cloud/models.py:228 +#: xpack/plugins/cloud/models.py:226 msgid "Reason" msgstr "原因" #: audits/models.py:106 tickets/serializers/request_asset_perm.py:64 -#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:225 -#: xpack/plugins/cloud/models.py:283 +#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:281 msgid "Status" msgstr "状态" @@ -1165,7 +1167,7 @@ msgid "Is success" msgstr "是否成功" #: audits/serializers.py:76 ops/models/command.py:24 -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:221 msgid "Result" msgstr "结果" @@ -1836,7 +1838,7 @@ msgid "The current organization cannot be deleted" msgstr "当前组织不能被删除" #: orgs/mixins/models.py:56 orgs/mixins/serializers.py:25 orgs/models.py:41 -#: orgs/models.py:395 +#: orgs/models.py:395 orgs/serializers.py:80 orgs/serializers.py:91 msgid "Organization" msgstr "组织" @@ -2847,32 +2849,46 @@ msgstr "" msgid "Ticket has %s" msgstr "工单已%s" -#: tickets/api/request_asset_perm.py:81 +#: tickets/api/request_asset_perm.py:62 +#: tickets/serializers/request_asset_perm.py:23 +msgid "IP group" +msgstr "IP组" + +#: tickets/api/request_asset_perm.py:65 +#: tickets/serializers/request_asset_perm.py:35 +msgid "Confirmed assets" +msgstr "确认的资产" + +#: tickets/api/request_asset_perm.py:66 +msgid "Confirmed system users" +msgstr "确认的系统用户" + +#: tickets/api/request_asset_perm.py:87 msgid "Confirm assets first" msgstr "请先确认资产" -#: tickets/api/request_asset_perm.py:84 +#: tickets/api/request_asset_perm.py:90 msgid "Confirmed assets changed" msgstr "确认的资产变更了" -#: tickets/api/request_asset_perm.py:88 +#: tickets/api/request_asset_perm.py:94 msgid "Confirm system-users first" msgstr "请先确认系统用户" -#: tickets/api/request_asset_perm.py:92 +#: tickets/api/request_asset_perm.py:98 msgid "Confirmed system-users changed" msgstr "确认的系统用户变更了" -#: tickets/api/request_asset_perm.py:98 tickets/api/request_asset_perm.py:105 -#: xpack/plugins/cloud/models.py:216 +#: tickets/api/request_asset_perm.py:104 tickets/api/request_asset_perm.py:111 +#: xpack/plugins/cloud/models.py:214 msgid "Succeed" msgstr "成功" -#: tickets/api/request_asset_perm.py:112 +#: tickets/api/request_asset_perm.py:118 msgid "From request ticket: {} {}" msgstr "来自工单申请: {} {}" -#: tickets/api/request_asset_perm.py:114 +#: tickets/api/request_asset_perm.py:120 msgid "{} request assets, approved by {}" msgstr "{} 申请资产,通过人 {}" @@ -2948,14 +2964,6 @@ msgstr "{} {} 这个工单" msgid "this ticket" msgstr "这个工单" -#: tickets/serializers/request_asset_perm.py:23 -msgid "IP group" -msgstr "IP组" - -#: tickets/serializers/request_asset_perm.py:35 -msgid "Confirmed assets" -msgstr "确认的资产" - #: tickets/serializers/request_asset_perm.py:39 msgid "Confirmed system user" msgstr "确认的系统用户" @@ -3290,7 +3298,7 @@ msgstr "安全令牌验证" #: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13 #: users/templates/users/user_profile_update.html:55 -#: xpack/plugins/cloud/models.py:126 xpack/plugins/cloud/serializers.py:114 +#: xpack/plugins/cloud/models.py:124 xpack/plugins/cloud/serializers.py:83 msgid "Account" msgstr "账户" @@ -3454,7 +3462,7 @@ msgstr "很强" #: users/templates/users/user_database_app_permission.html:41 #: users/templates/users/user_list.html:19 #: users/templates/users/user_remote_app_permission.html:41 -#: xpack/plugins/cloud/models.py:53 +#: xpack/plugins/cloud/models.py:51 msgid "Validity" msgstr "有效" @@ -4212,95 +4220,95 @@ msgstr "无法将数据发送到远程" msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:31 +#: xpack/plugins/cloud/models.py:30 msgid "Available" msgstr "有效" -#: xpack/plugins/cloud/models.py:32 +#: xpack/plugins/cloud/models.py:31 msgid "Unavailable" msgstr "无效" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:40 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:44 +#: xpack/plugins/cloud/models.py:43 msgid "Access key id" msgstr "" -#: xpack/plugins/cloud/models.py:48 +#: xpack/plugins/cloud/models.py:47 msgid "Access key secret" msgstr "" -#: xpack/plugins/cloud/models.py:67 +#: xpack/plugins/cloud/models.py:65 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:122 +#: xpack/plugins/cloud/models.py:120 msgid "Instance name" msgstr "实例名称" -#: xpack/plugins/cloud/models.py:123 +#: xpack/plugins/cloud/models.py:121 msgid "Instance name and Partial IP" msgstr "实例名称和部分IP" -#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/serializers.py:90 +#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/serializers.py:59 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:132 +#: xpack/plugins/cloud/models.py:130 msgid "Instances" msgstr "实例" -#: xpack/plugins/cloud/models.py:136 +#: xpack/plugins/cloud/models.py:134 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:148 xpack/plugins/cloud/serializers.py:118 +#: xpack/plugins/cloud/models.py:146 xpack/plugins/cloud/serializers.py:87 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:154 +#: xpack/plugins/cloud/models.py:152 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:165 xpack/plugins/cloud/models.py:221 +#: xpack/plugins/cloud/models.py:163 xpack/plugins/cloud/models.py:219 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:231 xpack/plugins/cloud/models.py:286 +#: xpack/plugins/cloud/models.py:229 xpack/plugins/cloud/models.py:284 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:259 +#: xpack/plugins/cloud/models.py:257 msgid "Unsync" msgstr "未同步" -#: xpack/plugins/cloud/models.py:260 +#: xpack/plugins/cloud/models.py:258 msgid "New Sync" msgstr "新同步" -#: xpack/plugins/cloud/models.py:261 +#: xpack/plugins/cloud/models.py:259 msgid "Synced" msgstr "已同步" -#: xpack/plugins/cloud/models.py:262 +#: xpack/plugins/cloud/models.py:260 msgid "Released" msgstr "已释放" -#: xpack/plugins/cloud/models.py:267 +#: xpack/plugins/cloud/models.py:265 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:271 +#: xpack/plugins/cloud/models.py:269 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:274 +#: xpack/plugins/cloud/models.py:272 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:277 +#: xpack/plugins/cloud/models.py:275 msgid "Region" msgstr "地域" @@ -4316,10 +4324,6 @@ msgstr "AWS (国际)" msgid "AWS (China)" msgstr "AWS (中国)" -#: xpack/plugins/cloud/providers/azure_.py:18 -msgid "Azure (China)" -msgstr "Azure (中国)" - #: xpack/plugins/cloud/providers/huaweicloud.py:20 msgid "Huawei Cloud" msgstr "华为云" @@ -4380,23 +4384,15 @@ msgstr "拉美-圣地亚哥" msgid "Tencent Cloud" msgstr "腾讯云" -#: xpack/plugins/cloud/serializers.py:26 -msgid "Tenant ID" -msgstr "" - -#: xpack/plugins/cloud/serializers.py:30 -msgid "Subscription ID" -msgstr "" - -#: xpack/plugins/cloud/serializers.py:88 +#: xpack/plugins/cloud/serializers.py:57 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers.py:89 +#: xpack/plugins/cloud/serializers.py:58 msgid "Instance count" msgstr "实例个数" -#: xpack/plugins/cloud/serializers.py:117 +#: xpack/plugins/cloud/serializers.py:86 #: xpack/plugins/gathered_user/serializers.py:20 msgid "Periodic display" msgstr "定时执行" @@ -4489,6 +4485,14 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#, fuzzy +#~| msgid "Confirmed system user" +#~ msgid "Confirmed systemusers" +#~ msgstr "确认的系统用户" + +#~ msgid "Azure (China)" +#~ msgstr "Azure (中国)" + #~ msgid "MFA level" #~ msgstr "多因子认证级别" diff --git a/apps/tickets/api/request_asset_perm.py b/apps/tickets/api/request_asset_perm.py index 81ee66e58..8bac63481 100644 --- a/apps/tickets/api/request_asset_perm.py +++ b/apps/tickets/api/request_asset_perm.py @@ -49,16 +49,26 @@ class RequestAssetPermTicketViewSet(JMSModelViewSet): def _get_extra_comment(self, instance): meta = instance.meta ips = ', '.join(meta.get('ips', [])) - confirmed_assets = ', '.join(meta.get('confirmed_assets', [])) - confirmed_system_users = ', '.join(meta.get('confirmed_system_users', [])) + confirmed_assets_id = meta.get('confirmed_assets', []) + confirmed_system_users_id = meta.get('confirmed_system_users', []) + confirmed_assets = Asset.objects.filter(id__in=confirmed_assets_id) + confirmed_system_users = SystemUser.objects.filter(id__in=confirmed_system_users_id) + confirmed_assets_display = ', '.join([str(i) for i in confirmed_assets]) + confirmed_system_users_display = ', '.join([str(i) for i in confirmed_system_users]) - return textwrap.dedent(f'''\ - {_('IP group')}: {ips} - {_('Hostname')}: {meta.get('hostname', '')} - {_('System user')}: {meta.get('system_user', '')} - {_('Confirmed assets')}: {confirmed_assets} - {_('Confirmed system users')}: {confirmed_system_users} - ''') + return textwrap.dedent(''' + {}: {} + {}: {} + {}: {} + {}: {} + {}: {} + '''.format( + _('IP group'), ips, + _('Hostname'), meta.get('hostname', ''), + _('System user'), meta.get('system_user', ''), + _('Confirmed assets'), confirmed_assets_display, + _('Confirmed system users'), confirmed_system_users_display + )) @action(detail=True, methods=[POST], permission_classes=[IsAssignee, IsValidUser]) def reject(self, request, *args, **kwargs): From b0dba35e5acbe6ff466a2562238d26da9f11a0c7 Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 17 Nov 2020 19:06:10 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix(public-api):=20=E7=BC=BA=E5=B0=91SECURI?= =?UTF-8?q?TY=5FPASSWORD=5FEXPIRATION=5FTIME=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/settings/api.py b/apps/settings/api.py index cf2f4ac5d..1fba03e6a 100644 --- a/apps/settings/api.py +++ b/apps/settings/api.py @@ -279,6 +279,7 @@ class PublicSettingApi(generics.RetrieveAPIView): "SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL, "SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION, "LOGIN_TITLE": settings.XPACK_INTERFACE_LOGIN_TITLE, + "SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME, "LOGO_URLS": settings.LOGO_URLS, "TICKETS_ENABLED": settings.TICKETS_ENABLED, "PASSWORD_RULE": { From 6e87b94789bfcf5b724f5a72875edc00cc97608e Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 17 Nov 2020 19:14:28 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix(command):=20=E7=B3=BB=E7=BB=9F=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE-=E5=AE=89=E5=85=A8=E8=AE=BE=E7=BD=AE-=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E6=8E=A5=E6=94=B6=E9=82=AE=E4=BB=B6=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E4=B8=BA=E7=A9=BA=EF=BC=8C=E5=88=99=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=B8=8D=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/serializers/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/settings/serializers/settings.py b/apps/settings/serializers/settings.py index 7038ba4d5..5d64d9e1a 100644 --- a/apps/settings/serializers/settings.py +++ b/apps/settings/serializers/settings.py @@ -83,7 +83,7 @@ class SecuritySettingSerializer(serializers.Serializer): SECURITY_PASSWORD_NUMBER = serializers.BooleanField(required=False) SECURITY_PASSWORD_SPECIAL_CHAR = serializers.BooleanField(required=False) SECURITY_INSECURE_COMMAND = serializers.BooleanField(required=False) - SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False) + SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False, allow_blank=True) class SettingsSerializer(serializers.Serializer): From f557c1dace22dc51dce58a97d77f265fdfb084bd Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 17 Nov 2020 19:30:10 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix(assets):=20model=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=20asset=20=E9=BB=98=E8=AE=A4=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0062_auto_20201117_1938.py | 17 +++++++++++++++++ apps/assets/models/asset.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 apps/assets/migrations/0062_auto_20201117_1938.py diff --git a/apps/assets/migrations/0062_auto_20201117_1938.py b/apps/assets/migrations/0062_auto_20201117_1938.py new file mode 100644 index 000000000..9764ede39 --- /dev/null +++ b/apps/assets/migrations/0062_auto_20201117_1938.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.13 on 2020-11-17 11:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0061_auto_20201116_1757'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['hostname', 'ip'], 'verbose_name': 'Asset'}, + ), + ] diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 4e3fff60f..d4c787bbc 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -361,4 +361,4 @@ class Asset(ProtocolsMixin, NodesRelationMixin, OrgModelMixin): class Meta: unique_together = [('org_id', 'hostname')] verbose_name = _("Asset") - ordering = ['-date_created'] + ordering = ["hostname", "ip"]