Commit f8ff223f authored by ibuler's avatar ibuler

[Update] 更新api和model方法

parent 69e5ab43
...@@ -11,8 +11,7 @@ from django.db.models import Q ...@@ -11,8 +11,7 @@ from django.db.models import Q
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from common.utils import get_logger from common.utils import get_logger
from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \ from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser
NodePermissionUtil
from ..models import Asset, SystemUser, AdminUser, Node from ..models import Asset, SystemUser, AdminUser, Node
from .. import serializers from .. import serializers
from ..tasks import update_asset_hardware_info_manual, \ from ..tasks import update_asset_hardware_info_manual, \
...@@ -22,7 +21,7 @@ from ..utils import LabelFilter ...@@ -22,7 +21,7 @@ from ..utils import LabelFilter
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
'AssetViewSet', 'UserAssetListView', 'AssetListUpdateApi', 'AssetViewSet', 'AssetListUpdateApi',
'AssetRefreshHardwareApi', 'AssetAdminUserTestApi' 'AssetRefreshHardwareApi', 'AssetAdminUserTestApi'
] ]
...@@ -71,19 +70,6 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): ...@@ -71,19 +70,6 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
return queryset return queryset
class UserAssetListView(generics.ListAPIView):
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
permission_classes = (IsValidUser,)
def get_queryset(self):
assets_granted = NodePermissionUtil.get_user_assets(self.request.user).keys()
queryset = self.queryset.filter(
id__in=[asset.id for asset in assets_granted]
)
return queryset
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView): class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
""" """
Asset bulk update api Asset bulk update api
......
...@@ -14,4 +14,3 @@ ...@@ -14,4 +14,3 @@
from common.mixins import AdminUserRequiredMixin from common.mixins import AdminUserRequiredMixin
from common.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser from common.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser
from users.models import User, UserGroup from users.models import User, UserGroup
from perms.utils import NodePermissionUtil
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import uuid import uuid
import logging import logging
import random import random
from functools import reduce
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
...@@ -149,6 +150,15 @@ class Asset(models.Model): ...@@ -149,6 +150,15 @@ class Asset(models.Model):
nodes = self.nodes.all() or [Node.root()] nodes = self.nodes.all() or [Node.root()]
return nodes return nodes
def get_all_nodes(self, flat=False):
nodes = []
for node in self.get_nodes_or_cache():
_nodes = node.get_ancestor(with_self=True)
_nodes.append(_nodes)
if flat:
nodes = list(reduce(lambda x, y: set(x) | set(y), nodes))
return nodes
@property @property
def nodes_cache_key(self): def nodes_cache_key(self):
key = "NODES_OF_{}".format(str(self.id)) key = "NODES_OF_{}".format(str(self.id))
......
...@@ -28,10 +28,9 @@ class Node(models.Model): ...@@ -28,10 +28,9 @@ class Node(models.Model):
@property @property
def full_value(self): def full_value(self):
ancestor = [a.value for a in self.ancestor] ancestor = [a.value for a in self.get_ancestor(with_self=True)]
if self.is_root(): if self.is_root():
return self.value return self.value
ancestor.append(self.value)
return ' / '.join(ancestor) return ' / '.join(ancestor)
@property @property
...@@ -55,32 +54,35 @@ class Node(models.Model): ...@@ -55,32 +54,35 @@ class Node(models.Model):
return "{}:{}".format(self.key, mark) return "{}:{}".format(self.key, mark)
def create_child(self, value): def create_child(self, value):
child_key = self.get_next_child_key() with transaction.atomic():
child = self.__class__.objects.create(key=child_key, value=value) child_key = self.get_next_child_key()
return child child = self.__class__.objects.create(key=child_key, value=value)
return child
def get_children(self): def get_children(self, with_self=False):
pattern = r'^{0}$|^{}:[0-9]+$' if with_self else r'^{}:[0-9]+$'
return self.__class__.objects.filter( return self.__class__.objects.filter(
key__regex=r'^{}:[0-9]+$'.format(self.key) key__regex=pattern.format(self.key)
) )
def get_children_with_self(self): def get_all_children(self, with_self=False):
pattern = r'^{0}$|^{0}:' if with_self else r'^{0}'
return self.__class__.objects.filter( return self.__class__.objects.filter(
key__regex=r'^{0}$|^{0}:[0-9]+$'.format(self.key) key__regex=pattern.format(self.key)
) )
def get_all_children(self): def get_sibling(self, with_self=False):
return self.__class__.objects.filter( key = ':'.join(self.key.split(':')[:-1])
key__startswith='{}:'.format(self.key) pattern = r'^{}:[0-9]+$'.format(key)
) sibling = self.__class__.objects.filter(
key__regex=pattern.format(self.key)
def get_all_children_with_self(self):
return self.__class__.objects.filter(
key__regex=r'^{0}$|^{0}:'.format(self.key)
) )
if not with_self:
sibling = sibling.exclude(key=self.key)
return sibling
def get_family(self): def get_family(self):
ancestor = self.ancestor ancestor = self.get_ancestor()
children = self.get_all_children() children = self.get_all_children()
return [*tuple(ancestor), self, *tuple(children)] return [*tuple(ancestor), self, *tuple(children)]
...@@ -102,7 +104,7 @@ class Node(models.Model): ...@@ -102,7 +104,7 @@ class Node(models.Model):
if self.is_root(): if self.is_root():
assets = Asset.objects.all() assets = Asset.objects.all()
else: else:
nodes = self.get_all_children_with_self() nodes = self.get_all_children(with_self=True)
assets = Asset.objects.filter(nodes__in=nodes).distinct() assets = Asset.objects.filter(nodes__in=nodes).distinct()
return assets return assets
...@@ -127,24 +129,21 @@ class Node(models.Model): ...@@ -127,24 +129,21 @@ class Node(models.Model):
def parent(self, parent): def parent(self, parent):
self.key = parent.get_next_child_key() self.key = parent.get_next_child_key()
@property def get_ancestor(self, with_self=False):
def ancestor(self):
if self.is_root(): if self.is_root():
ancestor = self.__class__.objects.filter(key='0') ancestor = self.__class__.objects.filter(key='0')
else: return ancestor
_key = self.key.split(':')
ancestor_keys = [] _key = self.key.split(':')
for i in range(len(_key)-1): if not with_self:
_key.pop() _key.pop()
ancestor_keys.append(':'.join(_key)) ancestor_keys = []
ancestor = self.__class__.objects.filter(key__in=ancestor_keys) for i in range(len(_key)):
ancestor = list(ancestor) ancestor_keys.append(':'.join(_key))
return ancestor _key.pop()
ancestor = self.__class__.objects.filter(
@property key__in=ancestor_keys
def ancestor_with_self(self): ).order_by('key')
ancestor = list(self.ancestor)
ancestor.insert(0, self)
return ancestor return ancestor
@classmethod @classmethod
...@@ -153,3 +152,12 @@ class Node(models.Model): ...@@ -153,3 +152,12 @@ class Node(models.Model):
key='0', defaults={"key": '0', 'value': "ROOT"} key='0', defaults={"key": '0', 'value': "ROOT"}
) )
return obj return obj
class Tree:
def __init__(self, root):
self.root = root
self.nodes = []
def add_node(self, node):
pass
...@@ -23,8 +23,6 @@ urlpatterns = [ ...@@ -23,8 +23,6 @@ urlpatterns = [
api.AssetRefreshHardwareApi.as_view(), name='asset-refresh'), api.AssetRefreshHardwareApi.as_view(), name='asset-refresh'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/alive/$', url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/alive/$',
api.AssetAdminUserTestApi.as_view(), name='asset-alive-test'), api.AssetAdminUserTestApi.as_view(), name='asset-alive-test'),
url(r'^v1/assets/user-assets/$',
api.UserAssetListView.as_view(), name='user-asset-list'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$',
api.ReplaceNodesAdminUserApi.as_view(), name='replace-nodes-admin-user'), api.ReplaceNodesAdminUserApi.as_view(), name='replace-nodes-admin-user'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/auth/$', url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/auth/$',
...@@ -35,17 +33,26 @@ urlpatterns = [ ...@@ -35,17 +33,26 @@ urlpatterns = [
api.SystemUserPushApi.as_view(), name='system-user-push'), api.SystemUserPushApi.as_view(), name='system-user-push'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$', url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'), api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$',
api.NodeChildrenApi.as_view(), name='node-children'),
url(r'^v1/nodes/children/$', api.NodeChildrenApi.as_view(), name='node-children-2'), url(r'^v1/nodes/children/$', api.NodeChildrenApi.as_view(), name='node-children-2'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$',
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.NodeAssetsApi.as_view(), name='node-assets'), api.NodeAddChildrenApi.as_view(), name='node-add-children'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/replace/$', api.NodeReplaceAssetsApi.as_view(), name='node-replace-assets'), api.NodeAssetsApi.as_view(), name='node-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$',
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$', api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'), api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$', api.TestNodeConnectiveApi.as_view(), name='node-test-connective'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/replace/$',
api.NodeReplaceAssetsApi.as_view(), name='node-replace-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$',
api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$',
api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$',
api.TestNodeConnectiveApi.as_view(), name='node-test-connective'),
url(r'^v1/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$', api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'), url(r'^v1/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$',
api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
] ]
urlpatterns += router.urls urlpatterns += router.urls
......
...@@ -41,11 +41,11 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): ...@@ -41,11 +41,11 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
asset = get_object_or_404(Asset, pk=asset_id) asset = get_object_or_404(Asset, pk=asset_id)
permissions = set(queryset.filter(assets=asset)) permissions = set(queryset.filter(assets=asset))
for node in asset.nodes.all(): for node in asset.nodes.all():
inherit_nodes.update(set(node.ancestor_with_self)) inherit_nodes.update(set(node.get_ancestor(with_self=True)))
elif node_id: elif node_id:
node = get_object_or_404(Node, pk=node_id) node = get_object_or_404(Node, pk=node_id)
permissions = set(queryset.filter(nodes=node)) permissions = set(queryset.filter(nodes=node))
inherit_nodes = node.ancestor inherit_nodes = node.get_ancestor()
for n in inherit_nodes: for n in inherit_nodes:
_permissions = queryset.filter(nodes=n) _permissions = queryset.filter(nodes=n)
......
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
import collections import collections
from collections import defaultdict from collections import defaultdict
from django.db.models import Q
from django.utils import timezone from django.utils import timezone
import copy import copy
from common.utils import set_or_append_attr_bulk, get_logger from common.utils import set_or_append_attr_bulk, get_logger
from .models import AssetPermission from .models import AssetPermission
from .hands import Node from .hands import Node, User, UserGroup, Asset, SystemUser
logger = get_logger(__file__) logger = get_logger(__file__)
...@@ -254,106 +255,47 @@ class AssetPermissionUtil: ...@@ -254,106 +255,47 @@ class AssetPermissionUtil:
return system_users return system_users
# Abandon class AssetPermissionUtilsV2:
class NodePermissionUtil: def __init__(self, obj):
""" self.object = obj
self._permissions = None
""" @staticmethod
def get_user_permissions(user):
groups = user.groups.all()
return AssetPermission.objects.all().valid().filter(
Q(users=user) | Q(user_groups=groups)
)
@staticmethod @staticmethod
def get_user_group_permissions(user_group): def get_user_group_permissions(user_group):
return user_group.nodepermission_set.all() \ return AssetPermission.objects.all().valid().filter(
.filter(is_active=True) \ user_groups=user_group
.filter(date_expired__gt=timezone.now()) )
@staticmethod @staticmethod
def get_system_user_permissions(system_user): def get_asset_permissions(asset):
return system_user.nodepermission_set.all() \ direct_nodes = asset.get_nodes_or_cache()
.filter(is_active=True) \
.filter(date_expired__gt=timezone.now())
@classmethod
def get_user_group_nodes(cls, user_group):
"""
获取用户组授权的node和系统用户
:param user_group:
:return: {"node": set(systemuser1, systemuser2), ..}
"""
permissions = cls.get_user_group_permissions(user_group)
nodes_directed = collections.defaultdict(set)
for perm in permissions:
nodes_directed[perm.node].add(perm.system_user)
nodes = copy.deepcopy(nodes_directed)
for node, system_users in nodes_directed.items():
for child in node.get_all_children_with_self():
nodes[child].update(system_users)
return nodes
@classmethod
def get_user_group_nodes_with_assets(cls, user_group):
"""
获取用户组授权的节点和系统用户,节点下带有资产
:param user_group:
:return: {"node": {"assets": "", "system_user": ""}, {}}
"""
nodes = cls.get_user_group_nodes(user_group)
nodes_with_assets = dict()
for node, system_users in nodes.items():
nodes_with_assets[node] = {
'assets': node.get_valid_assets(),
'system_users': system_users
}
return nodes_with_assets
@classmethod
def get_user_group_assets(cls, user_group):
assets = collections.defaultdict(set)
permissions = cls.get_user_group_permissions(user_group)
for perm in permissions:
for asset in perm.node.get_all_assets():
assets[asset].add(perm.system_user)
return assets
@classmethod
def get_user_nodes(cls, user):
nodes = collections.defaultdict(set)
groups = user.groups.all()
for group in groups:
group_nodes = cls.get_user_group_nodes(group)
for node, system_users in group_nodes.items():
nodes[node].update(system_users)
return nodes
@classmethod return AssetPermission.objects.all().valid().filter(
def get_user_nodes_with_assets(cls, user): Q(assets=asset) | Q(nodes=direct_nodes)
nodes = cls.get_user_nodes(user) )
nodes_with_assets = dict()
for node, system_users in nodes.items():
nodes_with_assets[node] = {
'assets': node.get_valid_assets(),
'system_users': system_users
}
return nodes_with_assets
@classmethod @staticmethod
def get_user_assets(cls, user): def get_node_permissions(node):
assets = collections.defaultdict(set) return AssetPermission.objects.all().valid().filter(nodes=node)
nodes_with_assets = cls.get_user_nodes_with_assets(user)
for v in nodes_with_assets.values(): @staticmethod
for asset in v['assets']: def get_system_user_permissions(system_user):
assets[asset].update(v['system_users']) return AssetPermission.objects.valid().all().filter(
return assets system_users=system_user
)
@classmethod @property
def get_system_user_assets(cls, system_user): def permissions(self):
assets = set() if self._permissions:
permissions = cls.get_system_user_permissions(system_user) return self._permissions
if isinstance(self.object, User):
pass
for perm in permissions:
assets.update(perm.node.get_all_assets())
return assets
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment