mirror of https://github.com/jumpserver/jumpserver
perf: 优化用户授权 api
parent
61e6ab20a2
commit
2d771eedc1
|
@ -37,7 +37,10 @@ class AssetFilterSet(BaseFilterSet):
|
|||
|
||||
class Meta:
|
||||
model = Asset
|
||||
fields = ["name", "address", "is_active", "type", "category", "hostname"]
|
||||
fields = [
|
||||
"id", "name", "address", "is_active",
|
||||
"type", "category", "hostname"
|
||||
]
|
||||
|
||||
|
||||
class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
|
||||
|
|
|
@ -1,25 +1,37 @@
|
|||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from django.conf import settings
|
||||
from rest_framework.generics import ListAPIView
|
||||
|
||||
from common.utils import get_logger
|
||||
from users.models import User
|
||||
from assets.api.asset.asset import AssetFilterSet
|
||||
from assets.api.mixin import SerializeToTreeNodeMixin
|
||||
from assets.models import Asset, Node
|
||||
from common.utils import get_logger
|
||||
from perms import serializers
|
||||
from perms.pagination import NodeGrantedAssetPagination, AllGrantedAssetPagination
|
||||
from perms.pagination import AllGrantedAssetPagination
|
||||
from perms.pagination import NodeGrantedAssetPagination
|
||||
from perms.utils.user_permission import UserGrantedAssetsQueryUtils
|
||||
from .mixin import (
|
||||
SelfOrPKUserMixin, RebuildTreeMixin,
|
||||
PermedAssetSerializerMixin, AssetsTreeFormatMixin
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'UserDirectPermedAssetsApi',
|
||||
'UserFavoriteAssetsApi',
|
||||
'UserDirectPermedAssetsAsTreeApi',
|
||||
'UserUngroupAssetsAsTreeApi',
|
||||
'UserAllPermedAssetsApi',
|
||||
'UserPermedNodeAssetsApi',
|
||||
]
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class UserDirectGrantedAssetsQuerysetMixin:
|
||||
class UserDirectPermedAssetsApi(SelfOrPKUserMixin, PermedAssetSerializerMixin, ListAPIView):
|
||||
""" 直接授权给用户的资产 """
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
user: User
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
return Asset.objects.none()
|
||||
|
||||
assets = UserGrantedAssetsQueryUtils(self.user) \
|
||||
.get_direct_granted_assets() \
|
||||
.prefetch_related('platform') \
|
||||
|
@ -27,14 +39,49 @@ class UserDirectGrantedAssetsQuerysetMixin:
|
|||
return assets
|
||||
|
||||
|
||||
class UserAllGrantedAssetsQuerysetMixin:
|
||||
class UserFavoriteAssetsApi(SelfOrPKUserMixin, PermedAssetSerializerMixin, ListAPIView):
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
""" 用户收藏的授权资产 """
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
return Asset.objects.none()
|
||||
|
||||
user = self.user
|
||||
utils = UserGrantedAssetsQueryUtils(user)
|
||||
assets = utils.get_favorite_assets()
|
||||
assets = assets.prefetch_related('platform').only(*self.only_fields)
|
||||
return assets
|
||||
|
||||
|
||||
class UserDirectPermedAssetsAsTreeApi(RebuildTreeMixin, AssetsTreeFormatMixin, UserDirectPermedAssetsApi):
|
||||
""" 用户直接授权的资产作为树 """
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
return Asset.objects.none()
|
||||
|
||||
assets = UserGrantedAssetsQueryUtils(self.user) \
|
||||
.get_direct_granted_assets() \
|
||||
.prefetch_related('platform') \
|
||||
.only(*self.only_fields)
|
||||
return assets
|
||||
|
||||
|
||||
class UserUngroupAssetsAsTreeApi(UserDirectPermedAssetsAsTreeApi):
|
||||
""" 用户未分组节点下的资产作为树 """
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
|
||||
queryset = queryset.none()
|
||||
return queryset
|
||||
|
||||
|
||||
class UserAllPermedAssetsApi(SelfOrPKUserMixin, PermedAssetSerializerMixin, ListAPIView):
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
pagination_class = AllGrantedAssetPagination
|
||||
ordering_fields = ("name", "address")
|
||||
filterset_class = AssetFilterSet
|
||||
ordering = ('name',)
|
||||
|
||||
user: User
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
@ -45,26 +92,11 @@ class UserAllGrantedAssetsQuerysetMixin:
|
|||
return queryset
|
||||
|
||||
|
||||
class UserFavoriteGrantedAssetsMixin:
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
user: User
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
return Asset.objects.none()
|
||||
user = self.user
|
||||
utils = UserGrantedAssetsQueryUtils(user)
|
||||
assets = utils.get_favorite_assets()
|
||||
assets = assets.prefetch_related('platform').only(*self.only_fields)
|
||||
return assets
|
||||
|
||||
|
||||
class UserGrantedNodeAssetsMixin:
|
||||
class UserPermedNodeAssetsApi(SelfOrPKUserMixin, PermedAssetSerializerMixin, ListAPIView):
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
pagination_class = NodeGrantedAssetPagination
|
||||
pagination_node: Node
|
||||
user: User
|
||||
kwargs: dict
|
||||
pagination_node: Node
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
@ -75,34 +107,3 @@ class UserGrantedNodeAssetsMixin:
|
|||
assets = assets.prefetch_related('platform').only(*self.only_fields)
|
||||
self.pagination_node = node
|
||||
return assets
|
||||
|
||||
|
||||
class AssetSerializerFormatMixin:
|
||||
serializer_class = serializers.AssetGrantedSerializer
|
||||
filterset_fields = ['name', 'address', 'id', 'comment']
|
||||
search_fields = ['name', 'address', 'comment']
|
||||
filterset_class = AssetFilterSet
|
||||
ordering_fields = ("name", "address")
|
||||
ordering = ('name',)
|
||||
|
||||
|
||||
class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
|
||||
"""
|
||||
将 资产 序列化成树的结构返回
|
||||
"""
|
||||
filter_queryset: callable
|
||||
get_queryset: callable
|
||||
|
||||
filterset_fields = ['name', 'address', 'id', 'comment']
|
||||
search_fields = ['name', 'address', 'comment']
|
||||
|
||||
def list(self, request: Request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
if request.query_params.get('search'):
|
||||
# 如果用户搜索的条件不精准,会导致返回大量的无意义数据。
|
||||
# 这里限制一下返回数据的最大条数
|
||||
queryset = queryset[:999]
|
||||
queryset = sorted(queryset, key=lambda asset: asset.name)
|
||||
data = self.serialize_assets(queryset, None)
|
||||
return Response(data=data)
|
|
@ -1 +0,0 @@
|
|||
from .api import *
|
|
@ -1,82 +0,0 @@
|
|||
from django.conf import settings
|
||||
from rest_framework.generics import ListAPIView
|
||||
|
||||
from common.utils import get_logger
|
||||
from .mixin import (
|
||||
AssetsTreeFormatMixin,
|
||||
UserGrantedNodeAssetsMixin,
|
||||
AssetSerializerFormatMixin,
|
||||
UserFavoriteGrantedAssetsMixin,
|
||||
UserAllGrantedAssetsQuerysetMixin,
|
||||
UserDirectGrantedAssetsQuerysetMixin,
|
||||
)
|
||||
from ..mixin import SelfOrPKUserMixin, RebuildTreeMixin
|
||||
|
||||
__all__ = [
|
||||
'UserDirectGrantedAssetsApi',
|
||||
'UserFavoriteGrantedAssetsApi',
|
||||
'UserDirectGrantedAssetsAsTreeApi',
|
||||
'UserUngroupAssetsAsTreeApi',
|
||||
'UserAllGrantedAssetsApi',
|
||||
'UserGrantedNodeAssetsApi',
|
||||
]
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class UserDirectGrantedAssetsApi(
|
||||
SelfOrPKUserMixin,
|
||||
UserDirectGrantedAssetsQuerysetMixin,
|
||||
AssetSerializerFormatMixin,
|
||||
ListAPIView
|
||||
):
|
||||
""" 直接授权给用户的资产 """
|
||||
pass
|
||||
|
||||
|
||||
class UserFavoriteGrantedAssetsApi(
|
||||
SelfOrPKUserMixin,
|
||||
UserFavoriteGrantedAssetsMixin,
|
||||
AssetSerializerFormatMixin,
|
||||
ListAPIView
|
||||
):
|
||||
""" 用户收藏的授权资产 """
|
||||
pass
|
||||
|
||||
|
||||
class UserDirectGrantedAssetsAsTreeApi(
|
||||
RebuildTreeMixin,
|
||||
AssetsTreeFormatMixin,
|
||||
UserDirectGrantedAssetsApi
|
||||
):
|
||||
""" 用户直接授权的资产作为树 """
|
||||
pass
|
||||
|
||||
|
||||
class UserUngroupAssetsAsTreeApi(UserDirectGrantedAssetsAsTreeApi):
|
||||
""" 用户未分组节点下的资产作为树 """
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
|
||||
queryset = queryset.none()
|
||||
return queryset
|
||||
|
||||
|
||||
class UserAllGrantedAssetsApi(
|
||||
SelfOrPKUserMixin,
|
||||
UserAllGrantedAssetsQuerysetMixin,
|
||||
AssetSerializerFormatMixin,
|
||||
ListAPIView
|
||||
):
|
||||
""" 授权给用户的所有资产 """
|
||||
pass
|
||||
|
||||
|
||||
class UserGrantedNodeAssetsApi(
|
||||
SelfOrPKUserMixin,
|
||||
UserGrantedNodeAssetsMixin,
|
||||
AssetSerializerFormatMixin,
|
||||
ListAPIView
|
||||
):
|
||||
""" 授权给用户的节点资产 """
|
||||
pass
|
|
@ -1,12 +1,16 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.request import Request
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
|
||||
from assets.api.asset.asset import AssetFilterSet
|
||||
from assets.api.mixin import SerializeToTreeNodeMixin
|
||||
from common.exceptions import JMSObjectDoesNotExist
|
||||
from common.http import is_true
|
||||
from common.utils import is_uuid
|
||||
from common.exceptions import JMSObjectDoesNotExist
|
||||
from perms import serializers
|
||||
from perms.utils.user_permission import UserGrantedTreeRefreshController
|
||||
from rbac.permissions import RBACPermission
|
||||
from users.models import User
|
||||
|
@ -67,3 +71,33 @@ class SelfOrPKUserMixin:
|
|||
|
||||
def request_user_is_self(self):
|
||||
return self.kwargs.get('user') in ['my', 'self']
|
||||
|
||||
|
||||
class PermedAssetSerializerMixin:
|
||||
serializer_class = serializers.AssetGrantedSerializer
|
||||
filterset_class = AssetFilterSet
|
||||
search_fields = ['name', 'address', 'comment']
|
||||
ordering_fields = ("name", "address")
|
||||
ordering = ('name',)
|
||||
|
||||
|
||||
class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
|
||||
"""
|
||||
将 资产 序列化成树的结构返回
|
||||
"""
|
||||
filter_queryset: callable
|
||||
get_queryset: callable
|
||||
|
||||
filterset_fields = ['name', 'address', 'id', 'comment']
|
||||
search_fields = ['name', 'address', 'comment']
|
||||
|
||||
def list(self, request: Request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
if request.query_params.get('search'):
|
||||
# 如果用户搜索的条件不精准,会导致返回大量的无意义数据。
|
||||
# 这里限制一下返回数据的最大条数
|
||||
queryset = queryset[:999]
|
||||
queryset = sorted(queryset, key=lambda asset: asset.name)
|
||||
data = self.serialize_assets(queryset, None)
|
||||
return Response(data=data)
|
||||
|
|
|
@ -6,9 +6,9 @@ user_permission_urlpatterns = [
|
|||
# <str:user> such as: my | self | user.id
|
||||
|
||||
# assets
|
||||
path('<str:user>/assets/', api.UserAllGrantedAssetsApi.as_view(),
|
||||
path('<str:user>/assets/', api.UserAllPermedAssetsApi.as_view(),
|
||||
name='user-assets'),
|
||||
path('<str:user>/assets/tree/', api.UserDirectGrantedAssetsAsTreeApi.as_view(),
|
||||
path('<str:user>/assets/tree/', api.UserDirectPermedAssetsAsTreeApi.as_view(),
|
||||
name='user-assets-as-tree'),
|
||||
path('<str:user>/ungroup/assets/tree/', api.UserUngroupAssetsAsTreeApi.as_view(),
|
||||
name='user-ungroup-assets-as-tree'),
|
||||
|
@ -24,11 +24,11 @@ user_permission_urlpatterns = [
|
|||
name='user-nodes-children-as-tree'),
|
||||
|
||||
# node-assets
|
||||
path('<str:user>/nodes/<uuid:node_id>/assets/', api.UserGrantedNodeAssetsApi.as_view(),
|
||||
path('<str:user>/nodes/<uuid:node_id>/assets/', api.UserPermedNodeAssetsApi.as_view(),
|
||||
name='user-node-assets'),
|
||||
path('<str:user>/nodes/ungrouped/assets/', api.UserDirectGrantedAssetsApi.as_view(),
|
||||
path('<str:user>/nodes/ungrouped/assets/', api.UserDirectPermedAssetsApi.as_view(),
|
||||
name='user-ungrouped-assets'),
|
||||
path('<str:user>/nodes/favorite/assets/', api.UserFavoriteGrantedAssetsApi.as_view(),
|
||||
path('<str:user>/nodes/favorite/assets/', api.UserFavoriteAssetsApi.as_view(),
|
||||
name='user-ungrouped-assets'),
|
||||
|
||||
path('<str:user>/nodes/children-with-assets/tree/',
|
||||
|
|
Loading…
Reference in New Issue