mirror of https://github.com/jumpserver/jumpserver
[Update] 添加用户授权资产列表页的分页,搜索,排序 (#1963)
* [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] 普通用户资产列表添加分页、搜索pull/1980/head
parent
ba0d822734
commit
82d866db7d
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -66,7 +66,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
|
|
|
@ -95,7 +95,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
|
|
|
@ -98,7 +98,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
|
|
|
@ -62,7 +62,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
|
|
|
@ -47,7 +47,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
|
|
|
@ -100,7 +100,7 @@ function initTable() {
|
|||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,3 @@ class DatetimeSearchMixin:
|
|||
def get(self, request, *args, **kwargs):
|
||||
self.get_date_range()
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
|
||||
|
||||
|
|
Binary file not shown.
|
@ -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"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
|
@ -24,7 +24,7 @@
|
|||
</li>
|
||||
<li class="active">
|
||||
<a href="{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and asset groups' %}</a>
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and node' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</li>
|
||||
<li>
|
||||
<a href="{% url 'perms:asset-permission-asset-list' pk=object.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and asset groups' %}</a>
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and node' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'perms:asset-permission-update' pk=object.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
|
|
|
@ -217,7 +217,7 @@ function initTable() {
|
|||
select: {},
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
table = jumpserver.initDataTable(options);
|
||||
table = jumpserver.initServerSideDataTable(options);
|
||||
return table
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</li>
|
||||
<li>
|
||||
<a href="{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and asset groups' %}</a>
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and node' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
Loading…
Reference in New Issue