From 82d866db7d16992ff843428cd2685c96a44332da Mon Sep 17 00:00:00 2001 From: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Date: Wed, 31 Oct 2018 15:31:09 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E8=B5=84=E4=BA=A7=E5=88=97=E8=A1=A8=E9=A1=B5?= =?UTF-8?q?=E7=9A=84=E5=88=86=E9=A1=B5=EF=BC=8C=E6=90=9C=E7=B4=A2=EF=BC=8C?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=20(#1963)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Update] 分页获取用户授权资产 * [Update] 修改前端-用户授权资产分页 * [Update] 用户授权资产支持搜索 * [Update] 用户授权资产支持排序 * [Update] 用户授权的节点with资产Api,对资产进行排序 * [Update] 获取用户授权的节点下的资产的api,进行分页、排序、查询 * [Update] 抽象用户授权资产列表的查询,排序 * [Update] 优化小细节 * [Update] 删除无用导入 * [Update] 修改AssetFilterMixins目录从common到perms * [Update] 资产授权规则列表: 添加分页、搜索 * [Update] 添加管理用户,系统用户列表分页、搜索 * [Update] 用户组列表添加分页,搜索 * [Update] 资产标签列表添加分页、搜索 * [Update] 网域网关列表添加分页、搜索 * [Update] 命令过滤列表添加分页、搜索,修改翻译小细节 * [Update] 删除前端注释initDataTable * [Update] 修改文案,资产组-节点 * [Update] 普通用户资产列表添加分页、搜索 --- apps/assets/api/admin_user.py | 9 +++++ apps/assets/api/cmd_filter.py | 7 ++++ apps/assets/api/domain.py | 9 ++++- apps/assets/api/label.py | 4 ++ apps/assets/api/system_user.py | 7 ++++ .../templates/assets/admin_user_list.html | 2 +- .../templates/assets/cmd_filter_list.html | 2 +- .../assets/cmd_filter_rule_list.html | 2 +- .../templates/assets/domain_gateway_list.html | 2 +- apps/assets/templates/assets/domain_list.html | 2 +- apps/assets/templates/assets/label_list.html | 2 +- .../templates/assets/system_user_list.html | 2 +- .../templates/assets/user_asset_list.html | 2 +- apps/common/mixins.py | 3 -- apps/locale/zh/LC_MESSAGES/django.mo | Bin 55532 -> 55527 bytes apps/locale/zh/LC_MESSAGES/django.po | 6 +-- apps/perms/api.py | 31 ++++++++++++--- apps/perms/mixins.py | 36 ++++++++++++++++++ .../perms/asset_permission_asset.html | 2 +- .../perms/asset_permission_detail.html | 2 +- .../perms/asset_permission_list.html | 2 +- .../perms/asset_permission_user.html | 2 +- apps/perms/utils.py | 19 +++++++++ apps/users/api/group.py | 4 ++ .../templates/users/user_granted_asset.html | 2 +- .../templates/users/user_group_list.html | 3 +- 26 files changed, 137 insertions(+), 27 deletions(-) create mode 100644 apps/perms/mixins.py diff --git a/apps/assets/api/admin_user.py b/apps/assets/api/admin_user.py index 7048ce461..8d30ee9d9 100644 --- a/apps/assets/api/admin_user.py +++ b/apps/assets/api/admin_user.py @@ -17,6 +17,7 @@ from django.db import transaction from rest_framework import generics from rest_framework.response import Response from rest_framework_bulk import BulkModelViewSet +from rest_framework.pagination import LimitOffsetPagination from common.mixins import IDInFilterMixin from common.utils import get_logger @@ -37,9 +38,17 @@ class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet): """ Admin user api set, for add,delete,update,list,retrieve resource """ + + filter_fields = ("name", "username") + search_fields = filter_fields queryset = AdminUser.objects.all() serializer_class = serializers.AdminUserSerializer permission_classes = (IsOrgAdmin,) + pagination_class = LimitOffsetPagination + + def get_queryset(self): + queryset = super().get_queryset().all() + return queryset class AdminUserAuthApi(generics.UpdateAPIView): diff --git a/apps/assets/api/cmd_filter.py b/apps/assets/api/cmd_filter.py index 14afc0ae3..cecdf2432 100644 --- a/apps/assets/api/cmd_filter.py +++ b/apps/assets/api/cmd_filter.py @@ -2,6 +2,7 @@ # from rest_framework_bulk import BulkModelViewSet +from rest_framework.pagination import LimitOffsetPagination from django.shortcuts import get_object_or_404 from ..hands import IsOrgAdmin @@ -13,14 +14,20 @@ __all__ = ['CommandFilterViewSet', 'CommandFilterRuleViewSet'] class CommandFilterViewSet(BulkModelViewSet): + filter_fields = ("name",) + search_fields = filter_fields permission_classes = (IsOrgAdmin,) queryset = CommandFilter.objects.all() serializer_class = serializers.CommandFilterSerializer + pagination_class = LimitOffsetPagination class CommandFilterRuleViewSet(BulkModelViewSet): + filter_fields = ("content",) + search_fields = filter_fields permission_classes = (IsOrgAdmin,) serializer_class = serializers.CommandFilterRuleSerializer + pagination_class = LimitOffsetPagination def get_queryset(self): fpk = self.kwargs.get('filter_pk') diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index 37bebfb84..2e24829dc 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -2,6 +2,7 @@ from rest_framework_bulk import BulkModelViewSet from rest_framework.views import APIView, Response +from rest_framework.pagination import LimitOffsetPagination from django.views.generic.detail import SingleObjectMixin @@ -20,6 +21,11 @@ class DomainViewSet(BulkModelViewSet): queryset = Domain.objects.all() permission_classes = (IsOrgAdmin,) serializer_class = serializers.DomainSerializer + pagination_class = LimitOffsetPagination + + def get_queryset(self): + queryset = super().get_queryset().all() + return queryset def get_serializer_class(self): if self.request.query_params.get('gateway'): @@ -33,11 +39,12 @@ class DomainViewSet(BulkModelViewSet): class GatewayViewSet(BulkModelViewSet): - filter_fields = ("domain",) + filter_fields = ("domain__name", "name", "username", "ip") search_fields = filter_fields queryset = Gateway.objects.all() permission_classes = (IsOrgAdmin,) serializer_class = serializers.GatewaySerializer + pagination_class = LimitOffsetPagination class GatewayTestConnectionApi(SingleObjectMixin, APIView): diff --git a/apps/assets/api/label.py b/apps/assets/api/label.py index e5391c76a..eb8594e4a 100644 --- a/apps/assets/api/label.py +++ b/apps/assets/api/label.py @@ -14,6 +14,7 @@ # limitations under the License. from rest_framework_bulk import BulkModelViewSet +from rest_framework.pagination import LimitOffsetPagination from django.db.models import Count from common.utils import get_logger @@ -27,8 +28,11 @@ __all__ = ['LabelViewSet'] class LabelViewSet(BulkModelViewSet): + filter_fields = ("name", "value") + search_fields = filter_fields permission_classes = (IsOrgAdmin,) serializer_class = serializers.LabelSerializer + pagination_class = LimitOffsetPagination def list(self, request, *args, **kwargs): if request.query_params.get("distinct"): diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index 16d475c35..3c1d0b3bd 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -42,9 +42,16 @@ class SystemUserViewSet(BulkModelViewSet): """ System user api set, for add,delete,update,list,retrieve resource """ + filter_fields = ("name", "username") + search_fields = filter_fields queryset = SystemUser.objects.all() serializer_class = serializers.SystemUserSerializer permission_classes = (IsOrgAdminOrAppUser,) + pagination_class = LimitOffsetPagination + + def get_queryset(self): + queryset = super().get_queryset().all() + return queryset class SystemUserAuthInfoApi(generics.RetrieveUpdateDestroyAPIView): diff --git a/apps/assets/templates/assets/admin_user_list.html b/apps/assets/templates/assets/admin_user_list.html index 16fcd1950..25ee56fba 100644 --- a/apps/assets/templates/assets/admin_user_list.html +++ b/apps/assets/templates/assets/admin_user_list.html @@ -93,7 +93,7 @@ $(document).ready(function(){ columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: "reachable_amount"}, {data: "unreachable_amount"}, {data: "id"}, {data: "comment" }, {data: "id" }] }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options) }) .on('click', '.btn_admin_user_delete', function () { diff --git a/apps/assets/templates/assets/cmd_filter_list.html b/apps/assets/templates/assets/cmd_filter_list.html index 78060177b..3a4feeae0 100644 --- a/apps/assets/templates/assets/cmd_filter_list.html +++ b/apps/assets/templates/assets/cmd_filter_list.html @@ -66,7 +66,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ initTable(); diff --git a/apps/assets/templates/assets/cmd_filter_rule_list.html b/apps/assets/templates/assets/cmd_filter_rule_list.html index 119b44fd4..78c3a36d5 100644 --- a/apps/assets/templates/assets/cmd_filter_rule_list.html +++ b/apps/assets/templates/assets/cmd_filter_rule_list.html @@ -95,7 +95,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ initTable(); diff --git a/apps/assets/templates/assets/domain_gateway_list.html b/apps/assets/templates/assets/domain_gateway_list.html index 43e8f43df..e7a3467e3 100644 --- a/apps/assets/templates/assets/domain_gateway_list.html +++ b/apps/assets/templates/assets/domain_gateway_list.html @@ -98,7 +98,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ initTable(); diff --git a/apps/assets/templates/assets/domain_list.html b/apps/assets/templates/assets/domain_list.html index 6913671f4..a0c6e869e 100644 --- a/apps/assets/templates/assets/domain_list.html +++ b/apps/assets/templates/assets/domain_list.html @@ -62,7 +62,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ initTable(); diff --git a/apps/assets/templates/assets/label_list.html b/apps/assets/templates/assets/label_list.html index 1c1b380d5..d2fa9958a 100644 --- a/apps/assets/templates/assets/label_list.html +++ b/apps/assets/templates/assets/label_list.html @@ -47,7 +47,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ initTable(); diff --git a/apps/assets/templates/assets/system_user_list.html b/apps/assets/templates/assets/system_user_list.html index 2d1358e46..f7c2a613b 100644 --- a/apps/assets/templates/assets/system_user_list.html +++ b/apps/assets/templates/assets/system_user_list.html @@ -100,7 +100,7 @@ function initTable() { ], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); } $(document).ready(function(){ diff --git a/apps/assets/templates/assets/user_asset_list.html b/apps/assets/templates/assets/user_asset_list.html index 2f03a361d..1b1a76e1d 100644 --- a/apps/assets/templates/assets/user_asset_list.html +++ b/apps/assets/templates/assets/user_asset_list.html @@ -102,7 +102,7 @@ function initTable() { {data: "system_users_granted", orderable: false} ] }; - asset_table = jumpserver.initDataTable(options); + asset_table = jumpserver.initServerSideDataTable(options); return asset_table } diff --git a/apps/common/mixins.py b/apps/common/mixins.py index ceeaed6c1..0a7d15fef 100644 --- a/apps/common/mixins.py +++ b/apps/common/mixins.py @@ -117,6 +117,3 @@ class DatetimeSearchMixin: def get(self, request, *args, **kwargs): self.get_date_range() return super().get(request, *args, **kwargs) - - - diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index b91198c4a60f99df3b260f584b3ef4661f0b65e4..1315c19c3dc03e3491612be772c9f56ef3dd5609 100644 GIT binary patch delta 12092 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 hb0>xcy*K&l9hNU{@PEx>7E%BJ delta 12100 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 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 402d71d67..9e3459248 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -1363,7 +1363,7 @@ msgstr "创建命令过滤器" #: assets/templates/assets/cmd_filter_rule_list.html:33 #: assets/views/cmd_filter.py:98 msgid "Command filter rule list" -msgstr "命令过滤器列表" +msgstr "命令过滤器规则列表" #: assets/templates/assets/cmd_filter_rule_list.html:50 msgid "Create rule" @@ -2477,8 +2477,8 @@ msgstr "用户或用户组" #: perms/templates/perms/asset_permission_asset.html:27 #: perms/templates/perms/asset_permission_detail.html:27 #: perms/templates/perms/asset_permission_user.html:27 -msgid "Assets and asset groups" -msgstr "资产或资产组" +msgid "Assets and node" +msgstr "资产或节点" #: perms/templates/perms/asset_permission_asset.html:80 msgid "Add asset to this permission" diff --git a/apps/perms/api.py b/apps/perms/api.py index 910ffb7f9..a1472d46a 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -5,6 +5,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, RetrieveUpdateAPIView from rest_framework import viewsets +from rest_framework.pagination import LimitOffsetPagination from common.utils import set_or_append_attr_bulk from common.permissions import IsValidUser, IsOrgAdmin, IsOrgAdminOrAppUser @@ -15,6 +16,7 @@ from .hands import AssetGrantedSerializer, User, UserGroup, Asset, Node, \ NodeGrantedSerializer, SystemUser, NodeSerializer from orgs.utils import set_to_root_org from . import serializers +from .mixins import AssetsFilterMixin class AssetPermissionViewSet(viewsets.ModelViewSet): @@ -23,6 +25,7 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): """ queryset = AssetPermission.objects.all() serializer_class = serializers.AssetPermissionCreateUpdateSerializer + pagination_class = LimitOffsetPagination permission_classes = (IsOrgAdmin,) def get_serializer_class(self): @@ -31,10 +34,15 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): return self.serializer_class def get_queryset(self): - queryset = super().get_queryset() + queryset = super().get_queryset().all() + search = self.request.query_params.get('search') asset_id = self.request.query_params.get('asset') node_id = self.request.query_params.get('node') inherit_nodes = set() + + if search: + queryset = queryset.filter(name__icontains=search) + if not asset_id and not node_id: return queryset @@ -53,15 +61,17 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): _permissions = queryset.filter(nodes=n) set_or_append_attr_bulk(_permissions, "inherit", n.value) permissions.update(_permissions) - return permissions + + return list(permissions) -class UserGrantedAssetsApi(ListAPIView): +class UserGrantedAssetsApi(AssetsFilterMixin, ListAPIView): """ 用户授权的所有资产 """ permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer + pagination_class = LimitOffsetPagination def change_org_if_need(self): if self.request.user.is_superuser or \ @@ -84,6 +94,7 @@ class UserGrantedAssetsApi(ListAPIView): system_users_granted = [s for s in v if s.protocol == k.protocol] k.system_users_granted = system_users_granted queryset.append(k) + return queryset def get_permissions(self): @@ -122,7 +133,7 @@ class UserGrantedNodesApi(ListAPIView): return super().get_permissions() -class UserGrantedNodesWithAssetsApi(ListAPIView): +class UserGrantedNodesWithAssetsApi(AssetsFilterMixin, ListAPIView): """ 用户授权的节点并带着节点下资产的api """ @@ -155,19 +166,25 @@ class UserGrantedNodesWithAssetsApi(ListAPIView): queryset.append(node) return queryset + def sort_assets(self, queryset): + for node in queryset: + node.assets_granted = super().sort_assets(node.assets_granted) + return queryset + def get_permissions(self): if self.kwargs.get('pk') is None: self.permission_classes = (IsValidUser,) return super().get_permissions() -class UserGrantedNodeAssetsApi(ListAPIView): +class UserGrantedNodeAssetsApi(AssetsFilterMixin, ListAPIView): """ 查询用户授权的节点下的资产的api, 与上面api不同的是,只返回某个节点下的资产 """ permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer - + pagination_class = LimitOffsetPagination + def change_org_if_need(self): if self.request.user.is_superuser or \ self.request.user.is_app or \ @@ -189,6 +206,8 @@ class UserGrantedNodeAssetsApi(ListAPIView): assets = nodes.get(node, []) for asset, system_users in assets.items(): asset.system_users_granted = system_users + + assets = list(assets.keys()) return assets def get_permissions(self): diff --git a/apps/perms/mixins.py b/apps/perms/mixins.py new file mode 100644 index 000000000..e41c0529b --- /dev/null +++ b/apps/perms/mixins.py @@ -0,0 +1,36 @@ +# ~*~ coding: utf-8 ~*~ +# + + +class AssetsFilterMixin(object): + """ + 对资产进行过滤(查询,排序) + """ + + def filter_queryset(self, queryset): + queryset = self.search_assets(queryset) + queryset = self.sort_assets(queryset) + return queryset + + def search_assets(self, queryset): + from perms.utils import is_obj_attr_has + value = self.request.query_params.get('search') + if not value: + return queryset + queryset = [asset for asset in queryset if is_obj_attr_has(asset, value)] + return queryset + + def sort_assets(self, queryset): + from perms.utils import sort_assets + order_by = self.request.query_params.get('order') + if not order_by: + order_by = 'hostname' + + if order_by.startswith('-'): + order_by = order_by.lstrip('-') + reverse = True + else: + reverse = False + + queryset = sort_assets(queryset, order_by=order_by, reverse=reverse) + return queryset diff --git a/apps/perms/templates/perms/asset_permission_asset.html b/apps/perms/templates/perms/asset_permission_asset.html index 364d7e60f..e774692f3 100644 --- a/apps/perms/templates/perms/asset_permission_asset.html +++ b/apps/perms/templates/perms/asset_permission_asset.html @@ -24,7 +24,7 @@
  • - {% trans 'Assets and asset groups' %} + {% trans 'Assets and node' %}
  • diff --git a/apps/perms/templates/perms/asset_permission_detail.html b/apps/perms/templates/perms/asset_permission_detail.html index 3996cb274..9c38cfc29 100644 --- a/apps/perms/templates/perms/asset_permission_detail.html +++ b/apps/perms/templates/perms/asset_permission_detail.html @@ -24,7 +24,7 @@
  • - {% trans 'Assets and asset groups' %} + {% trans 'Assets and node' %}
  • {% trans 'Update' %} diff --git a/apps/perms/templates/perms/asset_permission_list.html b/apps/perms/templates/perms/asset_permission_list.html index 31ccce112..1c1a21470 100644 --- a/apps/perms/templates/perms/asset_permission_list.html +++ b/apps/perms/templates/perms/asset_permission_list.html @@ -217,7 +217,7 @@ function initTable() { select: {}, op_html: $('#actions').html() }; - table = jumpserver.initDataTable(options); + table = jumpserver.initServerSideDataTable(options); return table } diff --git a/apps/perms/templates/perms/asset_permission_user.html b/apps/perms/templates/perms/asset_permission_user.html index 5d490bc28..eef6bf601 100644 --- a/apps/perms/templates/perms/asset_permission_user.html +++ b/apps/perms/templates/perms/asset_permission_user.html @@ -24,7 +24,7 @@
  • - {% trans 'Assets and asset groups' %} + {% trans 'Assets and node' %}
  • diff --git a/apps/perms/utils.py b/apps/perms/utils.py index 817c8b144..8ebe696e0 100644 --- a/apps/perms/utils.py +++ b/apps/perms/utils.py @@ -156,3 +156,22 @@ class AssetPermissionUtil: return tree.nodes +def is_obj_attr_has(obj, val, attrs=("hostname", "ip", "comment")): + if not attrs: + vals = [val for val in obj.__dict__.values() if isinstance(val, (str, int))] + else: + vals = [getattr(obj, attr) for attr in attrs if + hasattr(obj, attr) and isinstance(hasattr(obj, attr), (str, int))] + + for v in vals: + if str(v).find(val) != -1: + return True + return False + + +def sort_assets(assets, order_by='hostname', reverse=False): + if order_by == 'ip': + assets = sorted(assets, key=lambda asset: [int(d) for d in asset.ip.split('.') if d.isdigit()], reverse=reverse) + else: + assets = sorted(assets, key=lambda asset: getattr(asset, order_by), reverse=reverse) + return assets diff --git a/apps/users/api/group.py b/apps/users/api/group.py index 0f42d7426..2b738722c 100644 --- a/apps/users/api/group.py +++ b/apps/users/api/group.py @@ -3,6 +3,7 @@ from rest_framework import generics from rest_framework_bulk import BulkModelViewSet +from rest_framework.pagination import LimitOffsetPagination from ..serializers import UserGroupSerializer, \ UserGroupUpdateMemeberSerializer @@ -15,9 +16,12 @@ __all__ = ['UserGroupViewSet', 'UserGroupUpdateUserApi'] class UserGroupViewSet(IDInFilterMixin, BulkModelViewSet): + filter_fields = ("name",) + search_fields = filter_fields queryset = UserGroup.objects.all() serializer_class = UserGroupSerializer permission_classes = (IsOrgAdmin,) + pagination_class = LimitOffsetPagination class UserGroupUpdateUserApi(generics.RetrieveUpdateAPIView): diff --git a/apps/users/templates/users/user_granted_asset.html b/apps/users/templates/users/user_granted_asset.html index fc2cec031..8a68f3f60 100644 --- a/apps/users/templates/users/user_granted_asset.html +++ b/apps/users/templates/users/user_granted_asset.html @@ -103,7 +103,7 @@ function initTable() { {data: "system_users_granted", orderable: false} ] }; - asset_table = jumpserver.initDataTable(options); + asset_table = jumpserver.initServerSideDataTable(options) } function onSelected(event, treeNode) { diff --git a/apps/users/templates/users/user_group_list.html b/apps/users/templates/users/user_group_list.html index 25acfd439..b2eecc01f 100644 --- a/apps/users/templates/users/user_group_list.html +++ b/apps/users/templates/users/user_group_list.html @@ -58,7 +58,8 @@ $(document).ready(function() { order: [], op_html: $('#actions').html() }; - jumpserver.initDataTable(options); + jumpserver.initServerSideDataTable(options); + }).on('click', '.btn_delete_user_group', function(){ var $this = $(this); var group_id = $this.data('gid');