Compare commits

...

3 Commits
v3.7 ... v2.4.1

8 changed files with 23 additions and 23 deletions

View File

@@ -242,6 +242,9 @@ CACHES = {
'host': CONFIG.REDIS_HOST, 'host': CONFIG.REDIS_HOST,
'port': CONFIG.REDIS_PORT, 'port': CONFIG.REDIS_PORT,
'db': CONFIG.REDIS_DB_CACHE, 'db': CONFIG.REDIS_DB_CACHE,
},
'OPTIONS': {
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30}
} }
} }
} }

View File

@@ -4,6 +4,7 @@ from rest_framework.request import Request
from common.permissions import IsOrgAdminOrAppUser, IsValidUser from common.permissions import IsOrgAdminOrAppUser, IsValidUser
from common.utils import lazyproperty from common.utils import lazyproperty
from orgs.utils import tmp_to_root_org
from users.models import User from users.models import User
from perms.models import UserGrantedMappingNode from perms.models import UserGrantedMappingNode
@@ -47,6 +48,10 @@ class ForUserMixin:
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
request: Request request: Request
def get(self, request, *args, **kwargs):
with tmp_to_root_org():
return super().get(request, *args, **kwargs)
@lazyproperty @lazyproperty
def user(self): def user(self):
return self.request.user return self.request.user

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.utils.decorators import method_decorator
from perms.api.user_permission.mixin import UserNodeGrantStatusDispatchMixin from perms.api.user_permission.mixin import UserNodeGrantStatusDispatchMixin
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.response import Response from rest_framework.response import Response
@@ -10,7 +9,6 @@ from assets.api.mixin import SerializeToTreeNodeMixin
from common.utils import get_logger from common.utils import get_logger
from perms.pagination import GrantedAssetLimitOffsetPagination from perms.pagination import GrantedAssetLimitOffsetPagination
from assets.models import Asset, Node, FavoriteAsset from assets.models import Asset, Node, FavoriteAsset
from orgs.utils import tmp_to_root_org
from ... import serializers from ... import serializers
from ...utils.user_asset_permission import ( from ...utils.user_asset_permission import (
get_node_all_granted_assets, get_user_direct_granted_assets, get_node_all_granted_assets, get_user_direct_granted_assets,
@@ -22,7 +20,6 @@ from .mixin import ForAdminMixin, ForUserMixin
logger = get_logger(__name__) logger = get_logger(__name__)
@method_decorator(tmp_to_root_org(), name='list')
class UserDirectGrantedAssetsApi(ListAPIView): class UserDirectGrantedAssetsApi(ListAPIView):
""" """
用户直接授权的资产的列表,也就是授权规则上直接授权的资产,并非是来自节点的 用户直接授权的资产的列表,也就是授权规则上直接授权的资产,并非是来自节点的
@@ -40,7 +37,6 @@ class UserDirectGrantedAssetsApi(ListAPIView):
return assets return assets
@method_decorator(tmp_to_root_org(), name='list')
class UserFavoriteGrantedAssetsApi(ListAPIView): class UserFavoriteGrantedAssetsApi(ListAPIView):
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
@@ -55,7 +51,6 @@ class UserFavoriteGrantedAssetsApi(ListAPIView):
return assets return assets
@method_decorator(tmp_to_root_org(), name='list')
class AssetsAsTreeMixin(SerializeToTreeNodeMixin): class AssetsAsTreeMixin(SerializeToTreeNodeMixin):
""" """
将 资产 序列化成树的结构返回 将 资产 序列化成树的结构返回
@@ -82,12 +77,10 @@ class MyFavoriteGrantedAssetsApi(ForUserMixin, UserFavoriteGrantedAssetsApi):
pass pass
@method_decorator(tmp_to_root_org(), name='list')
class UserDirectGrantedAssetsAsTreeForAdminApi(ForAdminMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi): class UserDirectGrantedAssetsAsTreeForAdminApi(ForAdminMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi):
pass pass
@method_decorator(tmp_to_root_org(), name='list')
class MyUngroupAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi): class MyUngroupAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi):
def get_queryset(self): def get_queryset(self):
queryset = super().get_queryset() queryset = super().get_queryset()
@@ -96,9 +89,11 @@ class MyUngroupAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserDirectGrante
return queryset return queryset
@method_decorator(tmp_to_root_org(), name='list') class UserAllGrantedAssetsApi(ForAdminMixin, ListAPIView):
class UserAllGrantedAssetsApi(ListAPIView):
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
serializer_class = serializers.AssetGrantedSerializer
filter_fields = ['hostname', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment']
def get_queryset(self): def get_queryset(self):
queryset = get_user_granted_all_assets(self.user) queryset = get_user_granted_all_assets(self.user)
@@ -106,11 +101,14 @@ class UserAllGrantedAssetsApi(ListAPIView):
return queryset.only(*self.only_fields) return queryset.only(*self.only_fields)
class MyAllGrantedAssetsApi(ForUserMixin, UserAllGrantedAssetsApi):
pass
class MyAllAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserAllGrantedAssetsApi): class MyAllAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserAllGrantedAssetsApi):
search_fields = ['hostname', 'ip'] search_fields = ['hostname', 'ip']
@method_decorator(tmp_to_root_org(), name='list')
class UserGrantedNodeAssetsApi(UserNodeGrantStatusDispatchMixin, ListAPIView): class UserGrantedNodeAssetsApi(UserNodeGrantStatusDispatchMixin, ListAPIView):
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields

View File

@@ -7,7 +7,6 @@ from rest_framework.generics import (
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.request import Request from rest_framework.request import Request
from orgs.utils import tmp_to_root_org
from assets.api.mixin import SerializeToTreeNodeMixin from assets.api.mixin import SerializeToTreeNodeMixin
from common.utils import get_logger from common.utils import get_logger
from .mixin import ForAdminMixin, ForUserMixin, UserNodeGrantStatusDispatchMixin from .mixin import ForAdminMixin, ForUserMixin, UserNodeGrantStatusDispatchMixin
@@ -59,7 +58,6 @@ class NodeChildrenMixin:
class BaseGrantedNodeApi(_GrantedNodeStructApi, metaclass=abc.ABCMeta): class BaseGrantedNodeApi(_GrantedNodeStructApi, metaclass=abc.ABCMeta):
serializer_class = serializers.NodeGrantedSerializer serializer_class = serializers.NodeGrantedSerializer
@tmp_to_root_org()
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
rebuild_user_tree_if_need(request, self.user) rebuild_user_tree_if_need(request, self.user)
nodes = self.get_nodes() nodes = self.get_nodes()
@@ -72,7 +70,6 @@ class BaseNodeChildrenApi(NodeChildrenMixin, BaseGrantedNodeApi, metaclass=abc.A
class BaseGrantedNodeAsTreeApi(SerializeToTreeNodeMixin, _GrantedNodeStructApi, metaclass=abc.ABCMeta): class BaseGrantedNodeAsTreeApi(SerializeToTreeNodeMixin, _GrantedNodeStructApi, metaclass=abc.ABCMeta):
@tmp_to_root_org()
def list(self, request: Request, *args, **kwargs): def list(self, request: Request, *args, **kwargs):
rebuild_user_tree_if_need(request, self.user) rebuild_user_tree_if_need(request, self.user)
nodes = self.get_nodes() nodes = self.get_nodes()

View File

@@ -19,7 +19,6 @@ from ...utils.user_asset_permission import (
from assets.models import Asset, FavoriteAsset from assets.models import Asset, FavoriteAsset
from assets.api import SerializeToTreeNodeMixin from assets.api import SerializeToTreeNodeMixin
from orgs.utils import tmp_to_root_org
from ...hands import Node from ...hands import Node
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -28,7 +27,6 @@ logger = get_logger(__name__)
class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView): class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
@tmp_to_root_org()
def list(self, request: Request, *args, **kwargs): def list(self, request: Request, *args, **kwargs):
""" """
此算法依赖 UserGrantedMappingNode 此算法依赖 UserGrantedMappingNode
@@ -102,7 +100,6 @@ class UserGrantedNodeChildrenWithAssetsAsTreeForAdminApi(ForAdminMixin, UserNode
if node: if node:
return node.key return node.key
@tmp_to_root_org()
def list(self, request: Request, *args, **kwargs): def list(self, request: Request, *args, **kwargs):
key = self.request.query_params.get('key') key = self.request.query_params.get('key')
if key is None: if key is None:

View File

@@ -19,11 +19,9 @@ user_permission_urlpatterns = [
# 直接授权:在 `AssetPermission` 中关联的对象 # 直接授权:在 `AssetPermission` 中关联的对象
# --------------------------------------------------------- # ---------------------------------------------------------
# 获取用户所有直接授权的资产
# 以 serializer 格式返回 # 以 serializer 格式返回
path('<uuid:pk>/assets/', api.UserDirectGrantedAssetsForAdminApi.as_view(), name='user-assets'), path('<uuid:pk>/assets/', api.UserAllGrantedAssetsApi.as_view(), name='user-assets'),
path('assets/', api.MyDirectGrantedAssetsApi.as_view(), name='my-assets'), path('assets/', api.MyAllAssetsAsTreeApi.as_view(), name='my-assets'),
# Tree Node 的数据格式返回 # Tree Node 的数据格式返回
path('<uuid:pk>/assets/tree/', api.UserDirectGrantedAssetsAsTreeForAdminApi.as_view(), name='user-assets-as-tree'), path('<uuid:pk>/assets/tree/', api.UserDirectGrantedAssetsAsTreeForAdminApi.as_view(), name='user-assets-as-tree'),

View File

@@ -55,11 +55,13 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
post_user_create.send(self.__class__, user=user) post_user_create.send(self.__class__, user=user)
@staticmethod @staticmethod
def set_users_to_org(users, org_roles): def set_users_to_org(users, org_roles, update=False):
# 只有真实存在的组织才真正关联用户 # 只有真实存在的组织才真正关联用户
if not current_org or not current_org.is_real(): if not current_org or not current_org.is_real():
return return
for user, roles in zip(users, org_roles): for user, roles in zip(users, org_roles):
if update and roles is None:
continue
if not roles: if not roles:
# 当前组织创建的用户,至少是该组织的`User` # 当前组织创建的用户,至少是该组织的`User`
roles = [ORG_ROLE.USER] roles = [ORG_ROLE.USER]
@@ -107,7 +109,7 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
users = serializer.save() users = serializer.save()
if isinstance(users, User): if isinstance(users, User):
users = [users] users = [users]
self.set_users_to_org(users, org_roles) self.set_users_to_org(users, org_roles, update=True)
def perform_bulk_update(self, serializer): def perform_bulk_update(self, serializer):
# TODO: 需要测试 # TODO: 需要测试

View File

@@ -59,7 +59,7 @@ python-dateutil==2.6.1
python-gssapi==0.6.4 python-gssapi==0.6.4
pytz==2018.3 pytz==2018.3
PyYAML==5.1 PyYAML==5.1
redis==3.2.0 redis==3.5.3
requests==2.22.0 requests==2.22.0
jms-storage==0.0.34 jms-storage==0.0.34
s3transfer==0.3.3 s3transfer==0.3.3