perf: 合并授权规则用户相关的 API URL,统一使用 /<str:user>/ 格式

pull/9137/head
Bai 2022-12-01 12:02:20 +08:00
parent a430b0f1a9
commit 592d79c0f8
6 changed files with 131 additions and 175 deletions

View File

@ -3,58 +3,58 @@ from rest_framework.generics import ListAPIView
from common.utils import get_logger from common.utils import get_logger
from .mixin import ( from .mixin import (
UserAllGrantedAssetsQuerysetMixin, UserDirectGrantedAssetsQuerysetMixin, UserFavoriteGrantedAssetsMixin, AssetsTreeFormatMixin,
UserGrantedNodeAssetsMixin, AssetsSerializerFormatMixin, AssetsTreeFormatMixin, UserGrantedNodeAssetsMixin,
AssetSerializerFormatMixin,
UserFavoriteGrantedAssetsMixin,
UserAllGrantedAssetsQuerysetMixin,
UserDirectGrantedAssetsQuerysetMixin,
) )
from ..mixin import AssetRoleAdminMixin, AssetRoleUserMixin from ..mixin import SelfOrPKUserMixin, RebuildTreeMixin
__all__ = [ __all__ = [
'UserDirectGrantedAssetsApi', 'MyDirectGrantedAssetsApi', 'UserDirectGrantedAssetsApi',
'UserFavoriteGrantedAssetsApi', 'UserFavoriteGrantedAssetsApi',
'MyFavoriteGrantedAssetsApi', 'UserDirectGrantedAssetsAsTreeApi', 'UserDirectGrantedAssetsAsTreeApi',
'MyUngroupAssetsAsTreeApi', 'UserUngroupAssetsAsTreeApi',
'UserAllGrantedAssetsApi', 'MyAllGrantedAssetsApi', 'MyAllAssetsAsTreeApi', 'UserAllGrantedAssetsApi',
'UserGrantedNodeAssetsApi', 'UserGrantedNodeAssetsApi',
'MyGrantedNodeAssetsApi',
] ]
logger = get_logger(__name__) logger = get_logger(__name__)
class UserDirectGrantedAssetsApi( class UserDirectGrantedAssetsApi(
AssetRoleAdminMixin, UserDirectGrantedAssetsQuerysetMixin, SelfOrPKUserMixin,
AssetsSerializerFormatMixin, ListAPIView UserDirectGrantedAssetsQuerysetMixin,
AssetSerializerFormatMixin,
ListAPIView
): ):
""" 直接授权给用户的资产 """ """ 直接授权给用户的资产 """
pass pass
class MyDirectGrantedAssetsApi(AssetRoleUserMixin, UserDirectGrantedAssetsApi):
""" 直接授权给我的资产 """
pass
class UserFavoriteGrantedAssetsApi( class UserFavoriteGrantedAssetsApi(
AssetRoleAdminMixin, UserFavoriteGrantedAssetsMixin, SelfOrPKUserMixin,
AssetsSerializerFormatMixin, ListAPIView UserFavoriteGrantedAssetsMixin,
AssetSerializerFormatMixin,
ListAPIView
): ):
""" 用户收藏的授权资产 """ """ 用户收藏的授权资产 """
pass pass
class MyFavoriteGrantedAssetsApi(AssetRoleUserMixin, UserFavoriteGrantedAssetsApi): class UserDirectGrantedAssetsAsTreeApi(
""" 我收藏的授权资产 """ RebuildTreeMixin,
pass AssetsTreeFormatMixin,
UserDirectGrantedAssetsApi
):
class UserDirectGrantedAssetsAsTreeApi(AssetsTreeFormatMixin, UserDirectGrantedAssetsApi):
""" 用户直接授权的资产作为树 """ """ 用户直接授权的资产作为树 """
pass pass
class MyUngroupAssetsAsTreeApi(AssetRoleUserMixin, UserDirectGrantedAssetsAsTreeApi): class UserUngroupAssetsAsTreeApi(UserDirectGrantedAssetsAsTreeApi):
""" 我的未分组节点下的资产作为树 """ """ 用户未分组节点下的资产作为树 """
def get_queryset(self): def get_queryset(self):
queryset = super().get_queryset() queryset = super().get_queryset()
if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
@ -63,31 +63,20 @@ class MyUngroupAssetsAsTreeApi(AssetRoleUserMixin, UserDirectGrantedAssetsAsTree
class UserAllGrantedAssetsApi( class UserAllGrantedAssetsApi(
AssetRoleAdminMixin, UserAllGrantedAssetsQuerysetMixin, SelfOrPKUserMixin,
AssetsSerializerFormatMixin, ListAPIView UserAllGrantedAssetsQuerysetMixin,
AssetSerializerFormatMixin,
ListAPIView
): ):
""" 授权给用户的所有资产 """ """ 授权给用户的所有资产 """
pass pass
class MyAllGrantedAssetsApi(AssetRoleUserMixin, UserAllGrantedAssetsApi):
""" 授权给我的所有资产 """
pass
class MyAllAssetsAsTreeApi(AssetsTreeFormatMixin, MyAllGrantedAssetsApi):
""" 授权给我的所有资产作为树 """
pass
class UserGrantedNodeAssetsApi( class UserGrantedNodeAssetsApi(
AssetRoleAdminMixin, UserGrantedNodeAssetsMixin, SelfOrPKUserMixin,
AssetsSerializerFormatMixin, ListAPIView UserGrantedNodeAssetsMixin,
AssetSerializerFormatMixin,
ListAPIView
): ):
""" 授权给用户的节点资产 """ """ 授权给用户的节点资产 """
pass pass
class MyGrantedNodeAssetsApi(AssetRoleUserMixin, UserGrantedNodeAssetsApi):
""" 授权给我的节点资产 """
pass

View File

@ -1,20 +1,18 @@
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from common.utils import get_logger
from users.models import User
from assets.api.asset.asset import AssetFilterSet from assets.api.asset.asset import AssetFilterSet
from assets.api.mixin import SerializeToTreeNodeMixin from assets.api.mixin import SerializeToTreeNodeMixin
from assets.models import Asset, Node from assets.models import Asset, Node
from common.utils import get_logger
from perms import serializers from perms import serializers
from perms.pagination import NodeGrantedAssetPagination, AllGrantedAssetPagination from perms.pagination import NodeGrantedAssetPagination, AllGrantedAssetPagination
from perms.utils.user_permission import UserGrantedAssetsQueryUtils from perms.utils.user_permission import UserGrantedAssetsQueryUtils
from users.models import User
logger = get_logger(__name__) logger = get_logger(__name__)
# 获取数据的 ------------------------------------------------------------
class UserDirectGrantedAssetsQuerysetMixin: class UserDirectGrantedAssetsQuerysetMixin:
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
user: User user: User
@ -73,18 +71,13 @@ class UserGrantedNodeAssetsMixin:
return Asset.objects.none() return Asset.objects.none()
node_id = self.kwargs.get("node_id") node_id = self.kwargs.get("node_id")
node, assets = UserGrantedAssetsQueryUtils(self.user).get_node_all_assets( node, assets = UserGrantedAssetsQueryUtils(self.user).get_node_all_assets(node_id)
node_id
)
assets = assets.prefetch_related('platform').only(*self.only_fields) assets = assets.prefetch_related('platform').only(*self.only_fields)
self.pagination_node = node self.pagination_node = node
return assets return assets
# 控制格式的 ---------------------------------------------------- class AssetSerializerFormatMixin:
class AssetsSerializerFormatMixin:
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
filterset_fields = ['name', 'address', 'id', 'comment'] filterset_fields = ['name', 'address', 'id', 'comment']
search_fields = ['name', 'address', 'comment'] search_fields = ['name', 'address', 'comment']

View File

@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _
from common.http import is_true from common.http import is_true
from common.utils import is_uuid from common.utils import is_uuid
from common.exceptions import JMSObjectDoesNotExist from common.exceptions import JMSObjectDoesNotExist
from common.mixins.api import RoleAdminMixin, RoleUserMixin
from perms.utils.user_permission import UserGrantedTreeRefreshController from perms.utils.user_permission import UserGrantedTreeRefreshController
from rbac.permissions import RBACPermission from rbac.permissions import RBACPermission
from users.models import User from users.models import User
@ -23,24 +22,6 @@ class RebuildTreeMixin:
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
class AssetRoleAdminMixin(RebuildTreeMixin, RoleAdminMixin):
rbac_perms = (
('list', 'perms.view_userassets'),
('retrieve', 'perms.view_userassets'),
('get_tree', 'perms.view_userassets'),
('GET', 'perms.view_userassets'),
)
class AssetRoleUserMixin(RebuildTreeMixin, RoleUserMixin):
rbac_perms = (
('list', 'perms.view_myassets'),
('retrieve', 'perms.view_myassets'),
('get_tree', 'perms.view_myassets'),
('GET', 'perms.view_myassets'),
)
class SelfOrPKUserMixin: class SelfOrPKUserMixin:
kwargs: dict kwargs: dict
request: Request request: Request
@ -59,6 +40,7 @@ class SelfOrPKUserMixin:
('retrieve', 'perms.view_myassets'), ('retrieve', 'perms.view_myassets'),
('get_tree', 'perms.view_myassets'), ('get_tree', 'perms.view_myassets'),
('GET', 'perms.view_myassets'), ('GET', 'perms.view_myassets'),
('OPTIONS', 'perms.view_myassets'),
) )
@property @property
@ -68,6 +50,7 @@ class SelfOrPKUserMixin:
('retrieve', 'perms.view_userassets'), ('retrieve', 'perms.view_userassets'),
('get_tree', 'perms.view_userassets'), ('get_tree', 'perms.view_userassets'),
('GET', 'perms.view_userassets'), ('GET', 'perms.view_userassets'),
('OPTIONS', 'perms.view_userassets'),
) )
@property @property
@ -76,6 +59,8 @@ class SelfOrPKUserMixin:
user = self.request.user user = self.request.user
elif is_uuid(self.kwargs.get('user')): elif is_uuid(self.kwargs.get('user')):
user = get_object_or_404(User, pk=self.kwargs.get('user')) user = get_object_or_404(User, pk=self.kwargs.get('user'))
elif hasattr(self, 'swagger_fake_view'):
user = self.request.user
else: else:
raise JMSObjectDoesNotExist(object_name=_('User')) raise JMSObjectDoesNotExist(object_name=_('User'))
return user return user

View File

@ -1,31 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import abc import abc
from rest_framework.generics import (
ListAPIView
)
from rest_framework.response import Response
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.generics import ListAPIView
from assets.api.mixin import SerializeToTreeNodeMixin
from common.utils import get_logger from common.utils import get_logger
from .mixin import AssetRoleAdminMixin, AssetRoleUserMixin from assets.api.mixin import SerializeToTreeNodeMixin
from perms.hands import User
from perms import serializers from perms import serializers
from perms.hands import User
from perms.utils.user_permission import UserGrantedNodesQueryUtils from perms.utils.user_permission import UserGrantedNodesQueryUtils
from .mixin import SelfOrPKUserMixin, RebuildTreeMixin
logger = get_logger(__name__) logger = get_logger(__name__)
__all__ = [ __all__ = [
'UserGrantedNodesApi', 'UserGrantedNodesApi',
'MyGrantedNodesApi', 'UserGrantedNodesAsTreeApi',
'MyGrantedNodesAsTreeApi', 'UserGrantedNodeChildrenApi',
'UserGrantedNodeChildrenForAdminApi', 'UserGrantedNodeChildrenAsTreeApi',
'MyGrantedNodeChildrenApi',
'UserGrantedNodeChildrenAsTreeForAdminApi',
'MyGrantedNodeChildrenAsTreeApi',
'BaseGrantedNodeAsTreeApi', 'BaseGrantedNodeAsTreeApi',
'UserGrantedNodesMixin', 'UserGrantedNodesMixin',
] ]
@ -98,35 +92,42 @@ class UserGrantedNodesMixin:
return nodes return nodes
# ------------------------------------------ # API
# 最终的 api
class UserGrantedNodeChildrenForAdminApi(AssetRoleAdminMixin, UserGrantedNodeChildrenMixin, BaseNodeChildrenApi):
class UserGrantedNodeChildrenApi(
SelfOrPKUserMixin,
UserGrantedNodeChildrenMixin,
BaseNodeChildrenApi
):
""" 用户授权的节点下的子节点"""
pass pass
class MyGrantedNodeChildrenApi(AssetRoleUserMixin, UserGrantedNodeChildrenMixin, BaseNodeChildrenApi): class UserGrantedNodeChildrenAsTreeApi(
SelfOrPKUserMixin,
RebuildTreeMixin,
UserGrantedNodeChildrenMixin,
BaseNodeChildrenAsTreeApi
):
""" 用户授权的节点下的子节点树"""
pass pass
class UserGrantedNodeChildrenAsTreeForAdminApi(AssetRoleAdminMixin, UserGrantedNodeChildrenMixin, BaseNodeChildrenAsTreeApi): class UserGrantedNodesApi(
SelfOrPKUserMixin,
UserGrantedNodesMixin,
BaseGrantedNodeApi
):
""" 用户授权的节点 """
pass pass
class MyGrantedNodeChildrenAsTreeApi(AssetRoleUserMixin, UserGrantedNodeChildrenMixin, BaseNodeChildrenAsTreeApi): class UserGrantedNodesAsTreeApi(
def get_permissions(self): SelfOrPKUserMixin,
permissions = super().get_permissions() RebuildTreeMixin,
return permissions UserGrantedNodesMixin,
BaseGrantedNodeAsTreeApi
):
class UserGrantedNodesApi(AssetRoleAdminMixin, UserGrantedNodesMixin, BaseGrantedNodeApi): """ 用户授权的节点树 """
pass pass
class MyGrantedNodesApi(AssetRoleUserMixin, UserGrantedNodesApi):
pass
class MyGrantedNodesAsTreeApi(AssetRoleUserMixin, UserGrantedNodesMixin, BaseGrantedNodeAsTreeApi):
pass
# ------------------------------------------

View File

@ -1,24 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.conf import settings
from django.db.models import F, Value, CharField
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from django.db.models import F, Value, CharField
from django.conf import settings
from common.utils.common import timeit
from orgs.utils import tmp_to_root_org
from common.permissions import IsValidUser
from common.utils import get_logger, get_object_or_none from common.utils import get_logger, get_object_or_none
from .mixin import AssetRoleUserMixin, AssetRoleAdminMixin from common.utils.common import timeit
from common.permissions import IsValidUser
from assets.models import Asset
from assets.api import SerializeToTreeNodeMixin
from perms.hands import Node
from perms.models import AssetPermission, PermNode
from perms.utils.user_permission import ( from perms.utils.user_permission import (
UserGrantedTreeBuildUtils, get_user_all_asset_perm_ids, UserGrantedTreeBuildUtils, get_user_all_asset_perm_ids,
UserGrantedNodesQueryUtils, UserGrantedAssetsQueryUtils, UserGrantedNodesQueryUtils, UserGrantedAssetsQueryUtils,
) )
from perms.models import AssetPermission, PermNode
from assets.models import Asset from .mixin import SelfOrPKUserMixin, RebuildTreeMixin
from assets.api import SerializeToTreeNodeMixin
from perms.hands import Node
logger = get_logger(__name__) logger = get_logger(__name__)
@ -148,9 +149,10 @@ class GrantedNodeChildrenWithAssetsAsTreeApiMixin(SerializeToTreeNodeMixin,
return Response(data=all_tree_nodes) return Response(data=all_tree_nodes)
class UserGrantedNodeChildrenWithAssetsAsTreeApi(AssetRoleAdminMixin, GrantedNodeChildrenWithAssetsAsTreeApiMixin): class UserGrantedNodeChildrenWithAssetsAsTreeApi(
pass SelfOrPKUserMixin,
RebuildTreeMixin,
GrantedNodeChildrenWithAssetsAsTreeApiMixin
class MyGrantedNodeChildrenWithAssetsAsTreeApi(AssetRoleUserMixin, GrantedNodeChildrenWithAssetsAsTreeApiMixin): ):
""" 用户授权的节点的子节点与资产树 """
pass pass

View File

@ -3,68 +3,54 @@ from django.urls import path, include
from .. import api from .. import api
user_permission_urlpatterns = [ user_permission_urlpatterns = [
# 以 serializer 格式返回 # <str:user> such as: my | self | user.id
path('<uuid:pk>/assets/', api.UserAllGrantedAssetsApi.as_view(), name='user-assets'),
path('assets/', api.MyAllGrantedAssetsApi.as_view(), name='my-assets'),
# Tree Node 的数据格式返回
path('<uuid:pk>/assets/tree/', api.UserDirectGrantedAssetsAsTreeApi.as_view(), name='user-assets-as-tree'),
path('assets/tree/', api.MyAllAssetsAsTreeApi.as_view(), name='my-assets-as-tree'),
path('ungroup/assets/tree/', api.MyUngroupAssetsAsTreeApi.as_view(), name='my-ungroup-assets-as-tree'),
# 获取用户所有`直接授权的节点`与`直接授权资产`关联的节点 # assets
# 以 serializer 格式返回 path('<str:user>/assets/', api.UserAllGrantedAssetsApi.as_view(),
path('<uuid:pk>/nodes/', api.UserGrantedNodesApi.as_view(), name='user-nodes'), name='user-assets'),
path('nodes/', api.MyGrantedNodesApi.as_view(), name='my-nodes'), path('<str:user>/assets/tree/', api.UserDirectGrantedAssetsAsTreeApi.as_view(),
# 以 Tree Node 的数据格式返回 name='user-assets-as-tree'),
path('<uuid:pk>/nodes/tree/', api.MyGrantedNodesAsTreeApi.as_view(), name='user-nodes-as-tree'), path('<str:user>/ungroup/assets/tree/', api.UserUngroupAssetsAsTreeApi.as_view(),
path('nodes/tree/', api.MyGrantedNodesAsTreeApi.as_view(), name='my-nodes-as-tree'), name='user-ungroup-assets-as-tree'),
# 一层一层的获取用户授权的节点, # nodes
# 以 Serializer 的数据格式返回 path('<str:user>/nodes/', api.UserGrantedNodesApi.as_view(),
path('<uuid:pk>/nodes/children/', api.UserGrantedNodeChildrenForAdminApi.as_view(), name='user-nodes-children'), name='user-nodes'),
path('nodes/children/', api.MyGrantedNodeChildrenApi.as_view(), name='my-nodes-children'), path('<str:user>/nodes/tree/', api.UserGrantedNodesAsTreeApi.as_view(),
# 以 Tree Node 的数据格式返回 name='user-nodes-as-tree'),
path('<uuid:pk>/nodes/children/tree/', api.UserGrantedNodeChildrenAsTreeForAdminApi.as_view(), path('<str:user>/nodes/children/', api.UserGrantedNodeChildrenApi.as_view(),
name='user-nodes-children'),
path('<str:user>/nodes/children/tree/', api.UserGrantedNodeChildrenAsTreeApi.as_view(),
name='user-nodes-children-as-tree'), name='user-nodes-children-as-tree'),
# 部分调用位置
# - 普通用户 -> 我的资产 -> 展开节点 时调用
path('nodes/children/tree/', api.MyGrantedNodeChildrenAsTreeApi.as_view(), name='my-nodes-children-as-tree'),
# 此接口会返回整棵树 # node-assets
# 普通用户 -> 命令执行 -> 左侧树 path('<str:user>/nodes/<uuid:node_id>/assets/', api.UserGrantedNodeAssetsApi.as_view(),
name='user-node-assets'),
path('<str:user>/nodes/ungrouped/assets/', api.UserDirectGrantedAssetsApi.as_view(),
name='user-ungrouped-assets'),
path('<str:user>/nodes/favorite/assets/', api.UserFavoriteGrantedAssetsApi.as_view(),
name='user-ungrouped-assets'),
path('<str:user>/nodes/children-with-assets/tree/',
api.UserGrantedNodeChildrenWithAssetsAsTreeApi.as_view(),
name='user-nodes-children-with-assets-as-tree'),
path('nodes-with-assets/tree/', api.MyGrantedNodesWithAssetsAsTreeApi.as_view(), path('nodes-with-assets/tree/', api.MyGrantedNodesWithAssetsAsTreeApi.as_view(),
name='my-nodes-with-assets-as-tree'), name='my-nodes-with-assets-as-tree'),
# 主要用于 luna 页面,带资产的节点树 # accounts
path('<uuid:pk>/nodes/children-with-assets/tree/', api.UserGrantedNodeChildrenWithAssetsAsTreeApi.as_view(),
name='user-nodes-children-with-assets-as-tree'),
path('nodes/children-with-assets/tree/', api.MyGrantedNodeChildrenWithAssetsAsTreeApi.as_view(),
name='my-nodes-children-with-assets-as-tree'),
# 查询授权树上某个节点的所有资产
path('<uuid:pk>/nodes/<uuid:node_id>/assets/', api.UserGrantedNodeAssetsApi.as_view(), name='user-node-assets'),
path('nodes/<uuid:node_id>/assets/', api.MyGrantedNodeAssetsApi.as_view(), name='my-node-assets'),
# 未分组的资产
path('<uuid:pk>/nodes/ungrouped/assets/', api.UserDirectGrantedAssetsApi.as_view(), name='user-ungrouped-assets'),
path('nodes/ungrouped/assets/', api.MyDirectGrantedAssetsApi.as_view(), name='my-ungrouped-assets'),
# 收藏的资产
path('<uuid:pk>/nodes/favorite/assets/', api.UserFavoriteGrantedAssetsApi.as_view(), name='user-ungrouped-assets'),
path('nodes/favorite/assets/', api.MyFavoriteGrantedAssetsApi.as_view(),
name='my-ungrouped-assets'),
# 获取授权给用户某个资产的所有账号
# user params: ['my', 'self'] or user.id
path('<str:user>/assets/<uuid:asset_id>/accounts/', api.UserPermedAssetAccountsApi.as_view(), path('<str:user>/assets/<uuid:asset_id>/accounts/', api.UserPermedAssetAccountsApi.as_view(),
name='user-permed-asset-accounts'), name='user-permed-asset-accounts'),
] ]
user_group_permission_urlpatterns = [ user_group_permission_urlpatterns = [
# 查询某个用户组授权的资产和资产组 # 查询某个用户组授权的资产和资产组
path('<uuid:pk>/assets/', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'), path('<uuid:pk>/assets/', api.UserGroupGrantedAssetsApi.as_view(),
path('<uuid:pk>/nodes/', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'), name='user-group-assets'),
path('<uuid:pk>/nodes/children/', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes-children'), path('<uuid:pk>/nodes/', api.UserGroupGrantedNodesApi.as_view(),
name='user-group-nodes'),
path('<uuid:pk>/nodes/children/', api.UserGroupGrantedNodesApi.as_view(),
name='user-group-nodes-children'),
path('<uuid:pk>/nodes/children/tree/', api.UserGroupGrantedNodeChildrenAsTreeApi.as_view(), path('<uuid:pk>/nodes/children/tree/', api.UserGroupGrantedNodeChildrenAsTreeApi.as_view(),
name='user-group-nodes-children-as-tree'), name='user-group-nodes-children-as-tree'),
path('<uuid:pk>/nodes/<uuid:node_id>/assets/', api.UserGroupGrantedNodeAssetsApi.as_view(), path('<uuid:pk>/nodes/<uuid:node_id>/assets/', api.UserGroupGrantedNodeAssetsApi.as_view(),