mirror of https://github.com/jumpserver/jumpserver
[Merge] Merge branch dev of github.com:jumpserver/jumpserver into github_dev
commit
4c4430661b
|
@ -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
|
||||||
|
|
||||||
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):
|
||||||
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
|
||||||
|
|
|
@ -31,7 +31,7 @@ from .. import serializers
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'NodeViewSet', 'NodeChildrenApi',
|
'NodeViewSet', 'NodeChildrenApi',
|
||||||
'NodeAssetsApi', 'NodeWithAssetsApi',
|
'NodeAssetsApi',
|
||||||
'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
|
'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
|
||||||
'NodeReplaceAssetsApi',
|
'NodeReplaceAssetsApi',
|
||||||
'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
|
'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
|
||||||
|
@ -42,14 +42,7 @@ __all__ = [
|
||||||
class NodeViewSet(BulkModelViewSet):
|
class NodeViewSet(BulkModelViewSet):
|
||||||
queryset = Node.objects.all()
|
queryset = Node.objects.all()
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
# serializer_class = serializers.NodeSerializer
|
serializer_class = serializers.NodeSerializer
|
||||||
|
|
||||||
def get_serializer_class(self):
|
|
||||||
show_current_asset = self.request.query_params.get('show_current_asset')
|
|
||||||
if show_current_asset:
|
|
||||||
return serializers.NodeCurrentSerializer
|
|
||||||
else:
|
|
||||||
return serializers.NodeSerializer
|
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
child_key = Node.root().get_next_child_key()
|
child_key = Node.root().get_next_child_key()
|
||||||
|
@ -57,32 +50,32 @@ class NodeViewSet(BulkModelViewSet):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
|
||||||
class NodeWithAssetsApi(generics.ListAPIView):
|
# class NodeWithAssetsApi(generics.ListAPIView):
|
||||||
permission_classes = (IsSuperUser,)
|
# permission_classes = (IsSuperUser,)
|
||||||
serializers = serializers.NodeSerializer
|
# serializers = serializers.NodeSerializer
|
||||||
|
#
|
||||||
def get_node(self):
|
# def get_node(self):
|
||||||
pk = self.kwargs.get('pk') or self.request.query_params.get('node')
|
# pk = self.kwargs.get('pk') or self.request.query_params.get('node')
|
||||||
if not pk:
|
# if not pk:
|
||||||
node = Node.root()
|
# node = Node.root()
|
||||||
else:
|
# else:
|
||||||
node = get_object_or_404(Node, pk)
|
# node = get_object_or_404(Node, pk)
|
||||||
return node
|
# return node
|
||||||
|
#
|
||||||
def get_queryset(self):
|
# def get_queryset(self):
|
||||||
queryset = []
|
# queryset = []
|
||||||
node = self.get_node()
|
# node = self.get_node()
|
||||||
children = node.get_children()
|
# children = node.get_children()
|
||||||
assets = node.get_assets()
|
# assets = node.get_assets()
|
||||||
queryset.extend(list(children))
|
# queryset.extend(list(children))
|
||||||
|
#
|
||||||
for asset in assets:
|
# for asset in assets:
|
||||||
node = Node()
|
# node = Node()
|
||||||
node.id = asset.id
|
# node.id = asset.id
|
||||||
node.parent = node.id
|
# node.parent = node.id
|
||||||
node.value = asset.hostname
|
# node.value = asset.hostname
|
||||||
queryset.append(node)
|
# queryset.append(node)
|
||||||
return queryset
|
# return queryset
|
||||||
|
|
||||||
|
|
||||||
class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
|
class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
|
||||||
|
@ -147,9 +140,9 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
|
||||||
for asset in assets:
|
for asset in assets:
|
||||||
node_fake = Node()
|
node_fake = Node()
|
||||||
node_fake.id = asset.id
|
node_fake.id = asset.id
|
||||||
node_fake.parent = node
|
|
||||||
node_fake.value = asset.hostname
|
|
||||||
node_fake.is_node = False
|
node_fake.is_node = False
|
||||||
|
node_fake.parent_id = node.id
|
||||||
|
node_fake.value = asset.hostname
|
||||||
queryset.append(node_fake)
|
queryset.append(node_fake)
|
||||||
queryset = sorted(queryset, key=lambda x: x.is_node, reverse=True)
|
queryset = sorted(queryset, key=lambda x: x.is_node, reverse=True)
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -185,7 +178,7 @@ class NodeAddChildrenApi(generics.UpdateAPIView):
|
||||||
for node in children:
|
for node in children:
|
||||||
if not node:
|
if not node:
|
||||||
continue
|
continue
|
||||||
node.set_parent(instance)
|
node.parent = instance
|
||||||
return Response("OK")
|
return Response("OK")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 @@
|
||||||
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,22 +150,15 @@ class Asset(models.Model):
|
||||||
nodes = self.nodes.all() or [Node.root()]
|
nodes = self.nodes.all() or [Node.root()]
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
@property
|
def get_all_nodes(self, flat=False):
|
||||||
def nodes_cache_key(self):
|
nodes = []
|
||||||
key = "NODES_OF_{}".format(str(self.id))
|
for node in self.get_nodes():
|
||||||
return key
|
_nodes = node.get_ancestor(with_self=True)
|
||||||
|
_nodes.append(_nodes)
|
||||||
def get_nodes_or_cache(self):
|
if flat:
|
||||||
cached = cache.get(self.nodes_cache_key)
|
nodes = list(reduce(lambda x, y: set(x) | set(y), nodes))
|
||||||
if cached is not None:
|
|
||||||
return cached
|
|
||||||
nodes = list(self.get_nodes())
|
|
||||||
cache.set(self.nodes_cache_key, nodes, 3600)
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def expire_nodes_cache(self):
|
|
||||||
cache.delete(self.nodes_cache_key)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hardware_info(self):
|
def hardware_info(self):
|
||||||
if self.cpu_count:
|
if self.cpu_count:
|
||||||
|
|
|
@ -5,7 +5,7 @@ import uuid
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from common.utils import with_cache
|
||||||
|
|
||||||
__all__ = ['Node']
|
__all__ = ['Node']
|
||||||
|
|
||||||
|
@ -22,32 +22,36 @@ class Node(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.full_value
|
return self.full_value
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.key == other.key
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if self.is_root():
|
||||||
|
return True
|
||||||
|
self_key = [int(k) for k in self.key.split(':')]
|
||||||
|
other_key = [int(k) for k in other.key.split(':')]
|
||||||
|
if len(self_key) < len(other_key):
|
||||||
|
return True
|
||||||
|
elif len(self_key) > len(other_key):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return self_key[-1] < other_key[-1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
@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
|
||||||
def level(self):
|
def level(self):
|
||||||
return len(self.key.split(':'))
|
return len(self.key.split(':'))
|
||||||
|
|
||||||
def set_parent(self, instance):
|
|
||||||
children = self.get_all_children()
|
|
||||||
old_key = self.key
|
|
||||||
with transaction.atomic():
|
|
||||||
self.parent = instance
|
|
||||||
for child in children:
|
|
||||||
child.key = child.key.replace(old_key, self.key, 1)
|
|
||||||
child.save()
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def get_next_child_key(self):
|
def get_next_child_key(self):
|
||||||
mark = self.child_mark
|
mark = self.child_mark
|
||||||
self.child_mark += 1
|
self.child_mark += 1
|
||||||
|
@ -55,32 +59,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)]
|
||||||
|
|
||||||
|
@ -91,7 +98,7 @@ class Node(models.Model):
|
||||||
Q(nodes__id=self.id) | Q(nodes__isnull=True)
|
Q(nodes__id=self.id) | Q(nodes__isnull=True)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
assets = Asset.objects.filter(nodes__id=self.id)
|
assets = self.assets.all()
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def get_valid_assets(self):
|
def get_valid_assets(self):
|
||||||
|
@ -102,8 +109,8 @@ 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()
|
pattern = r'^{0}$|^{0}:'.format(self.key)
|
||||||
assets = Asset.objects.filter(nodes__in=nodes).distinct()
|
assets = Asset.objects.filter(nodes__key__regex=pattern)
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def get_all_valid_assets(self):
|
def get_all_valid_assets(self):
|
||||||
|
@ -125,26 +132,33 @@ class Node(models.Model):
|
||||||
|
|
||||||
@parent.setter
|
@parent.setter
|
||||||
def parent(self, parent):
|
def parent(self, parent):
|
||||||
self.key = parent.get_next_child_key()
|
if self.is_node:
|
||||||
|
children = self.get_all_children()
|
||||||
|
old_key = self.key
|
||||||
|
with transaction.atomic():
|
||||||
|
self.key = parent.get_next_child_key()
|
||||||
|
for child in children:
|
||||||
|
child.key = child.key.replace(old_key, self.key, 1)
|
||||||
|
child.save()
|
||||||
|
self.save()
|
||||||
|
else:
|
||||||
|
self.key = parent.key+':fake'
|
||||||
|
|
||||||
@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 = []
|
|
||||||
for i in range(len(_key)-1):
|
|
||||||
_key.pop()
|
|
||||||
ancestor_keys.append(':'.join(_key))
|
|
||||||
ancestor = self.__class__.objects.filter(key__in=ancestor_keys)
|
|
||||||
ancestor = list(ancestor)
|
|
||||||
return ancestor
|
|
||||||
|
|
||||||
@property
|
_key = self.key.split(':')
|
||||||
def ancestor_with_self(self):
|
if not with_self:
|
||||||
ancestor = list(self.ancestor)
|
_key.pop()
|
||||||
ancestor.insert(0, self)
|
ancestor_keys = []
|
||||||
|
for i in range(len(_key)):
|
||||||
|
ancestor_keys.append(':'.join(_key))
|
||||||
|
_key.pop()
|
||||||
|
ancestor = self.__class__.objects.filter(
|
||||||
|
key__in=ancestor_keys
|
||||||
|
).order_by('key')
|
||||||
return ancestor
|
return ancestor
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -152,4 +166,6 @@ class Node(models.Model):
|
||||||
obj, created = cls.objects.get_or_create(
|
obj, created = cls.objects.get_or_create(
|
||||||
key='0', defaults={"key": '0', 'value': "ROOT"}
|
key='0', defaults={"key": '0', 'value': "ROOT"}
|
||||||
)
|
)
|
||||||
|
print(obj)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,6 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
资产的数据结构
|
资产的数据结构
|
||||||
"""
|
"""
|
||||||
nodes = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
list_serializer_class = BulkListSerializer
|
list_serializer_class = BulkListSerializer
|
||||||
|
@ -31,10 +29,6 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
])
|
])
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_nodes(obj):
|
|
||||||
return [n.id for n in obj.get_nodes_or_cache()]
|
|
||||||
|
|
||||||
|
|
||||||
class AssetGrantedSerializer(serializers.ModelSerializer):
|
class AssetGrantedSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -9,7 +9,7 @@ from .asset import AssetGrantedSerializer
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'NodeSerializer', "NodeGrantedSerializer", "NodeAddChildrenSerializer",
|
'NodeSerializer', "NodeGrantedSerializer", "NodeAddChildrenSerializer",
|
||||||
"NodeAssetsSerializer", "NodeCurrentSerializer",
|
"NodeAssetsSerializer",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@ class NodeSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_parent(obj):
|
def get_parent(obj):
|
||||||
return obj.parent.id
|
return obj.parent.id if obj.is_node else obj.parent_id
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_assets_amount(obj):
|
def get_assets_amount(obj):
|
||||||
return obj.get_all_assets().count()
|
return obj.get_all_assets().count() if obj.is_node else 0
|
||||||
|
|
||||||
def get_fields(self):
|
def get_fields(self):
|
||||||
fields = super().get_fields()
|
fields = super().get_fields()
|
||||||
|
@ -77,12 +77,6 @@ class NodeSerializer(serializers.ModelSerializer):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
class NodeCurrentSerializer(NodeSerializer):
|
|
||||||
@staticmethod
|
|
||||||
def get_assets_amount(obj):
|
|
||||||
return obj.get_assets().count()
|
|
||||||
|
|
||||||
|
|
||||||
class NodeAssetsSerializer(serializers.ModelSerializer):
|
class NodeAssetsSerializer(serializers.ModelSerializer):
|
||||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ def on_system_user_assets_change(sender, instance=None, **kwargs):
|
||||||
@receiver(m2m_changed, sender=Asset.nodes.through)
|
@receiver(m2m_changed, sender=Asset.nodes.through)
|
||||||
def on_asset_node_changed(sender, instance=None, **kwargs):
|
def on_asset_node_changed(sender, instance=None, **kwargs):
|
||||||
if isinstance(instance, Asset):
|
if isinstance(instance, Asset):
|
||||||
instance.expire_nodes_cache()
|
|
||||||
if kwargs['action'] == 'post_add':
|
if kwargs['action'] == 'post_add':
|
||||||
logger.debug("Asset node change signal received")
|
logger.debug("Asset node change signal received")
|
||||||
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
@ -81,10 +80,6 @@ def on_asset_node_changed(sender, instance=None, **kwargs):
|
||||||
def on_node_assets_changed(sender, instance=None, **kwargs):
|
def on_node_assets_changed(sender, instance=None, **kwargs):
|
||||||
if isinstance(instance, Node):
|
if isinstance(instance, Node):
|
||||||
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
# 清理资产节点缓存
|
|
||||||
for asset in assets:
|
|
||||||
asset.expire_nodes_cache()
|
|
||||||
|
|
||||||
if kwargs['action'] == 'post_add':
|
if kwargs['action'] == 'post_add':
|
||||||
logger.debug("Node assets change signal received")
|
logger.debug("Node assets change signal received")
|
||||||
# 重新关联系统用户和资产的关系
|
# 重新关联系统用户和资产的关系
|
||||||
|
|
|
@ -95,7 +95,7 @@ function initTree2() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var zNodes = [];
|
var zNodes = [];
|
||||||
$.get("{% url 'api-assets:node-list' %}?show_current_asset=1", function(data, status){
|
$.get("{% url 'api-assets:node-list' %}", function(data, status){
|
||||||
$.each(data, function (index, value) {
|
$.each(data, function (index, value) {
|
||||||
value["pId"] = value["parent"];
|
value["pId"] = value["parent"];
|
||||||
{#value["open"] = true;#}
|
{#value["open"] = true;#}
|
||||||
|
|
|
@ -399,8 +399,7 @@ function initTree() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var zNodes = [];
|
var zNodes = [];
|
||||||
var query_params = {'show_current_asset': getCookie('show_current_asset')};
|
$.get("{% url 'api-assets:node-list' %}", function(data, status){
|
||||||
$.get("{% url 'api-assets:node-list' %}", query_params, function(data, status){
|
|
||||||
$.each(data, function (index, value) {
|
$.each(data, function (index, value) {
|
||||||
value["pId"] = value["parent"];
|
value["pId"] = value["parent"];
|
||||||
if (value["key"] === "0") {
|
if (value["key"] === "0") {
|
||||||
|
@ -436,7 +435,7 @@ $(document).ready(function(){
|
||||||
initTable();
|
initTable();
|
||||||
initTree();
|
initTree();
|
||||||
|
|
||||||
if(getCookie('show_current_asset') === 'yes'){
|
if(getCookie('show_current_asset') === '1'){
|
||||||
$('#show_all_asset').css('display', 'inline-block');
|
$('#show_all_asset').css('display', 'inline-block');
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -564,7 +563,7 @@ $(document).ready(function(){
|
||||||
hideRMenu();
|
hideRMenu();
|
||||||
$(this).css('display', 'none');
|
$(this).css('display', 'none');
|
||||||
$('#show_all_asset').css('display', 'inline-block');
|
$('#show_all_asset').css('display', 'inline-block');
|
||||||
setCookie('show_current_asset', 'yes');
|
setCookie('show_current_asset', '1');
|
||||||
location.reload();
|
location.reload();
|
||||||
})
|
})
|
||||||
.on('click', '.btn-show-all-asset', function(){
|
.on('click', '.btn-show-all-asset', function(){
|
||||||
|
|
|
@ -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 = [
|
||||||
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
|
||||||
|
|
|
@ -21,23 +21,13 @@ class MailTestingAPI(APIView):
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
email_host_user = serializer.validated_data["EMAIL_HOST_USER"]
|
email_host_user = serializer.validated_data["EMAIL_HOST_USER"]
|
||||||
kwargs = {
|
for k, v in serializer.validated_data.items():
|
||||||
"host": serializer.validated_data["EMAIL_HOST"],
|
if k.startswith('EMAIL'):
|
||||||
"port": serializer.validated_data["EMAIL_PORT"],
|
setattr(settings, k, v)
|
||||||
"username": serializer.validated_data["EMAIL_HOST_USER"],
|
|
||||||
"password": serializer.validated_data["EMAIL_HOST_PASSWORD"],
|
|
||||||
"use_ssl": serializer.validated_data["EMAIL_USE_SSL"],
|
|
||||||
"use_tls": serializer.validated_data["EMAIL_USE_TLS"]
|
|
||||||
}
|
|
||||||
connection = get_connection(timeout=5, **kwargs)
|
|
||||||
try:
|
try:
|
||||||
connection.open()
|
subject = "Test"
|
||||||
except Exception as e:
|
message = "Test smtp setting"
|
||||||
return Response({"error": str(e)}, status=401)
|
send_mail(subject, message, email_host_user, [email_host_user])
|
||||||
|
|
||||||
try:
|
|
||||||
send_mail("Test", "Test smtp setting", email_host_user,
|
|
||||||
[email_host_user], connection=connection)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response({"error": str(e)}, status=401)
|
return Response({"error": str(e)}, status=401)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from django.core.mail import send_mail
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from .utils import get_logger
|
from .utils import get_logger
|
||||||
|
from .models import Setting
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
@ -21,6 +22,10 @@ def send_mail_async(*args, **kwargs):
|
||||||
Example:
|
Example:
|
||||||
send_mail_sync.delay(subject, message, recipient_list, fail_silently=False, html_message=None)
|
send_mail_sync.delay(subject, message, recipient_list, fail_silently=False, html_message=None)
|
||||||
"""
|
"""
|
||||||
|
configs = Setting.objects.filter(name__startswith='EMAIL')
|
||||||
|
for config in configs:
|
||||||
|
setattr(settings, config.name, config.cleaned_value)
|
||||||
|
|
||||||
if len(args) == 3:
|
if len(args) == 3:
|
||||||
args = list(args)
|
args = list(args)
|
||||||
args[0] = settings.EMAIL_SUBJECT_PREFIX + args[0]
|
args[0] = settings.EMAIL_SUBJECT_PREFIX + args[0]
|
||||||
|
|
|
@ -16,6 +16,7 @@ import calendar
|
||||||
import threading
|
import threading
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import uuid
|
import uuid
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
import paramiko
|
import paramiko
|
||||||
import sshpubkeys
|
import sshpubkeys
|
||||||
|
@ -395,3 +396,17 @@ class TeeObj:
|
||||||
def close(self):
|
def close(self):
|
||||||
self.file_obj.close()
|
self.file_obj.close()
|
||||||
|
|
||||||
|
|
||||||
|
def with_cache(func):
|
||||||
|
cache = {}
|
||||||
|
key = "_{}.{}".format(func.__module__, func.__name__)
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
cached = cache.get(key)
|
||||||
|
if cached:
|
||||||
|
return cached
|
||||||
|
res = func(*args, **kwargs)
|
||||||
|
cache[key] = res
|
||||||
|
return res
|
||||||
|
return wrapper
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -70,7 +70,8 @@ class UserGrantedAssetsApi(ListAPIView):
|
||||||
else:
|
else:
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
|
|
||||||
for k, v in AssetPermissionUtil.get_user_assets(user).items():
|
util = AssetPermissionUtil(user)
|
||||||
|
for k, v in util.get_assets().items():
|
||||||
if k.is_unixlike():
|
if k.is_unixlike():
|
||||||
system_users_granted = [s for s in v if s.protocol == 'ssh']
|
system_users_granted = [s for s in v if s.protocol == 'ssh']
|
||||||
else:
|
else:
|
||||||
|
@ -95,7 +96,8 @@ class UserGrantedNodesApi(ListAPIView):
|
||||||
user = get_object_or_404(User, id=user_id)
|
user = get_object_or_404(User, id=user_id)
|
||||||
else:
|
else:
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
util = AssetPermissionUtil(user)
|
||||||
|
nodes = util.get_nodes_with_assets()
|
||||||
return nodes.keys()
|
return nodes.keys()
|
||||||
|
|
||||||
def get_permissions(self):
|
def get_permissions(self):
|
||||||
|
@ -116,7 +118,8 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
else:
|
else:
|
||||||
user = get_object_or_404(User, id=user_id)
|
user = get_object_or_404(User, id=user_id)
|
||||||
|
|
||||||
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
util = AssetPermissionUtil(user)
|
||||||
|
nodes = util.get_nodes_with_assets()
|
||||||
for node, _assets in nodes.items():
|
for node, _assets in nodes.items():
|
||||||
assets = _assets.keys()
|
assets = _assets.keys()
|
||||||
for k, v in _assets.items():
|
for k, v in _assets.items():
|
||||||
|
@ -147,8 +150,9 @@ class UserGrantedNodeAssetsApi(ListAPIView):
|
||||||
user = get_object_or_404(User, id=user_id)
|
user = get_object_or_404(User, id=user_id)
|
||||||
else:
|
else:
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
|
util = AssetPermissionUtil(user)
|
||||||
node = get_object_or_404(Node, id=node_id)
|
node = get_object_or_404(Node, id=node_id)
|
||||||
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
nodes = util.get_nodes_with_assets()
|
||||||
assets = nodes.get(node, [])
|
assets = nodes.get(node, [])
|
||||||
for asset, system_users in assets.items():
|
for asset, system_users in assets.items():
|
||||||
asset.system_users_granted = system_users
|
asset.system_users_granted = system_users
|
||||||
|
@ -172,7 +176,8 @@ class UserGroupGrantedAssetsApi(ListAPIView):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
||||||
assets = AssetPermissionUtil.get_user_group_assets(user_group)
|
util = AssetPermissionUtil(user_group)
|
||||||
|
assets = util.get_assets()
|
||||||
for k, v in assets.items():
|
for k, v in assets.items():
|
||||||
k.system_users_granted = v
|
k.system_users_granted = v
|
||||||
queryset.append(k)
|
queryset.append(k)
|
||||||
|
@ -189,7 +194,8 @@ class UserGroupGrantedNodesApi(ListAPIView):
|
||||||
|
|
||||||
if group_id:
|
if group_id:
|
||||||
group = get_object_or_404(UserGroup, id=group_id)
|
group = get_object_or_404(UserGroup, id=group_id)
|
||||||
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(group)
|
util = AssetPermissionUtil(group)
|
||||||
|
nodes = util.get_nodes_with_assets()
|
||||||
return nodes.keys()
|
return nodes.keys()
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
@ -206,7 +212,8 @@ class UserGroupGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
||||||
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(user_group)
|
util = AssetPermissionUtil(user_group)
|
||||||
|
nodes = util.get_nodes_with_assets()
|
||||||
for node, _assets in nodes.items():
|
for node, _assets in nodes.items():
|
||||||
assets = _assets.keys()
|
assets = _assets.keys()
|
||||||
for asset, system_users in _assets.items():
|
for asset, system_users in _assets.items():
|
||||||
|
@ -226,7 +233,8 @@ class UserGroupGrantedNodeAssetsApi(ListAPIView):
|
||||||
|
|
||||||
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
||||||
node = get_object_or_404(Node, id=node_id)
|
node = get_object_or_404(Node, id=node_id)
|
||||||
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(user_group)
|
util = AssetPermissionUtil(user_group)
|
||||||
|
nodes = util.get_nodes_with_assets()
|
||||||
assets = nodes.get(node, [])
|
assets = nodes.get(node, [])
|
||||||
for asset, system_users in assets.items():
|
for asset, system_users in assets.items():
|
||||||
asset.system_users_granted = system_users
|
asset.system_users_granted = system_users
|
||||||
|
@ -246,7 +254,8 @@ class ValidateUserAssetPermissionView(APIView):
|
||||||
asset = get_object_or_404(Asset, id=asset_id)
|
asset = get_object_or_404(Asset, id=asset_id)
|
||||||
system_user = get_object_or_404(SystemUser, id=system_id)
|
system_user = get_object_or_404(SystemUser, id=system_id)
|
||||||
|
|
||||||
assets_granted = AssetPermissionUtil.get_user_assets(user)
|
util = AssetPermissionUtil(user)
|
||||||
|
assets_granted = util.get_assets()
|
||||||
if system_user in assets_granted.get(asset, []):
|
if system_user in assets_granted.get(asset, []):
|
||||||
return Response({'msg': True}, status=200)
|
return Response({'msg': True}, status=200)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,359 +1,123 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
import collections
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from django.utils import timezone
|
from django.db.models import Q
|
||||||
import copy
|
|
||||||
|
|
||||||
from common.utils import set_or_append_attr_bulk, get_logger
|
from common.utils import get_logger
|
||||||
from .models import AssetPermission
|
from .models import AssetPermission
|
||||||
from .hands import Node
|
from .hands import Node
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
class Tree:
|
def get_user_permissions(user, include_group=True):
|
||||||
def __init__(self):
|
if include_group:
|
||||||
self.__all_nodes = list(Node.objects.all().prefetch_related('assets'))
|
groups = user.groups.all()
|
||||||
self.__node_asset_map = defaultdict(set)
|
arg = Q(users=user) | Q(user_groups=groups)
|
||||||
self.nodes = defaultdict(dict)
|
else:
|
||||||
self.root = Node.root()
|
arg = Q(users=user)
|
||||||
self.init_node_asset_map()
|
return AssetPermission.objects.all().valid().filter(arg)
|
||||||
|
|
||||||
def init_node_asset_map(self):
|
|
||||||
for node in self.__all_nodes:
|
|
||||||
assets = node.get_assets().values_list('id', flat=True)
|
|
||||||
for asset in assets:
|
|
||||||
self.__node_asset_map[str(asset)].add(node)
|
|
||||||
|
|
||||||
def add_asset(self, asset, system_users):
|
def get_user_group_permissions(user_group):
|
||||||
nodes = self.__node_asset_map.get(str(asset.id), [])
|
return AssetPermission.objects.all().valid().filter(
|
||||||
self.add_nodes(nodes)
|
user_groups=user_group
|
||||||
for node in nodes:
|
)
|
||||||
self.nodes[node][asset].update(system_users)
|
|
||||||
|
|
||||||
def add_node(self, node):
|
|
||||||
if node in self.nodes:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.nodes[node] = defaultdict(set)
|
|
||||||
if node.key == self.root.key:
|
|
||||||
return
|
|
||||||
parent_key = ':'.join(node.key.split(':')[:-1])
|
|
||||||
for n in self.__all_nodes:
|
|
||||||
if n.key == parent_key:
|
|
||||||
self.add_node(n)
|
|
||||||
break
|
|
||||||
|
|
||||||
def add_nodes(self, nodes):
|
def get_asset_permissions(asset, include_node=True):
|
||||||
for node in nodes:
|
if include_node:
|
||||||
self.add_node(node)
|
nodes = asset.get_all_nodes(flat=True)
|
||||||
|
arg = Q(assets=asset) | Q(nodes=nodes)
|
||||||
|
else:
|
||||||
|
arg = Q(assets=asset)
|
||||||
|
return AssetPermission.objects.all().valid().filter(arg)
|
||||||
|
|
||||||
|
|
||||||
|
def get_node_permissions(node):
|
||||||
|
return AssetPermission.objects.all().valid().filter(nodes=node)
|
||||||
|
|
||||||
|
|
||||||
|
def get_system_user_permissions(system_user):
|
||||||
|
return AssetPermission.objects.valid().all().filter(
|
||||||
|
system_users=system_user
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionUtil:
|
class AssetPermissionUtil:
|
||||||
@staticmethod
|
get_permissions_map = {
|
||||||
def get_user_permissions(user):
|
"User": get_user_permissions,
|
||||||
return AssetPermission.objects.all().valid().filter(users=user)
|
"UserGroup": get_user_group_permissions,
|
||||||
|
"Asset": get_asset_permissions,
|
||||||
|
"Node": get_node_permissions,
|
||||||
|
"SystemUser": get_node_permissions,
|
||||||
|
}
|
||||||
|
|
||||||
@staticmethod
|
def __init__(self, obj):
|
||||||
def get_user_group_permissions(user_group):
|
self.object = obj
|
||||||
return AssetPermission.objects.all().valid().filter(
|
self._permissions = None
|
||||||
user_groups=user_group
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@property
|
||||||
def get_asset_permissions(asset):
|
def permissions(self):
|
||||||
return AssetPermission.objects.all().valid().filter(
|
if self._permissions:
|
||||||
assets=asset
|
return self._permissions
|
||||||
)
|
object_cls = self.object.__class__.__name__
|
||||||
|
func = self.get_permissions_map[object_cls]
|
||||||
|
permissions = func(self.object)
|
||||||
|
self._permissions = permissions
|
||||||
|
return permissions
|
||||||
|
|
||||||
@staticmethod
|
def get_nodes_direct(self):
|
||||||
def get_node_permissions(node):
|
"""
|
||||||
return AssetPermission.objects.all().valid().filter(nodes=node)
|
返回用户/组授权规则直接关联的节点
|
||||||
|
:return: {node1: set(system_user1,)}
|
||||||
@staticmethod
|
"""
|
||||||
def get_system_user_permissions(system_user):
|
|
||||||
return AssetPermission.objects.valid().all().filter(
|
|
||||||
system_users=system_user
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_group_nodes(cls, group):
|
|
||||||
nodes = defaultdict(set)
|
nodes = defaultdict(set)
|
||||||
permissions = cls.get_user_group_permissions(group)
|
permissions = self.permissions.prefetch_related('nodes', 'system_users')
|
||||||
for perm in permissions:
|
for perm in permissions:
|
||||||
_nodes = perm.nodes.all()
|
for node in perm.nodes.all():
|
||||||
_system_users = perm.system_users.all()
|
nodes[node].update(perm.system_users.all())
|
||||||
set_or_append_attr_bulk(_nodes, 'permission', perm.id)
|
|
||||||
for node in _nodes:
|
|
||||||
nodes[node].update(set(_system_users))
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
@classmethod
|
def get_assets_direct(self):
|
||||||
def get_user_group_assets_direct(cls, group):
|
"""
|
||||||
|
返回用户授权规则直接关联的资产
|
||||||
|
:return: {asset1: set(system_user1,)}
|
||||||
|
"""
|
||||||
assets = defaultdict(set)
|
assets = defaultdict(set)
|
||||||
permissions = cls.get_user_group_permissions(group)
|
permissions = self.permissions.prefetch_related('assets', 'system_users')
|
||||||
for perm in permissions:
|
for perm in permissions:
|
||||||
_assets = perm.assets.all().valid()
|
for asset in perm.assets.all().valid().prefetch_related('nodes'):
|
||||||
_system_users = perm.system_users.all()
|
assets[asset].update(perm.system_users.all())
|
||||||
set_or_append_attr_bulk(_assets, 'permission', perm.id)
|
|
||||||
for asset in _assets:
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
@classmethod
|
def get_assets(self):
|
||||||
def get_user_group_nodes_assets(cls, group):
|
assets = self.get_assets_direct()
|
||||||
assets = defaultdict(set)
|
nodes = self.get_nodes_direct()
|
||||||
nodes = cls.get_user_group_nodes(group)
|
|
||||||
for node, _system_users in nodes.items():
|
|
||||||
_assets = node.get_all_valid_assets()
|
|
||||||
set_or_append_attr_bulk(_assets, 'inherit_node', node.id)
|
|
||||||
set_or_append_attr_bulk(_assets, 'permission', getattr(node, 'permission', None))
|
|
||||||
for asset in _assets:
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_group_assets(cls, group):
|
|
||||||
assets = defaultdict(set)
|
|
||||||
_assets = cls.get_user_group_assets_direct(group)
|
|
||||||
_nodes_assets = cls.get_user_group_nodes_assets(group)
|
|
||||||
for asset, _system_users in _assets.items():
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
for asset, _system_users in _nodes_assets.items():
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_group_nodes_with_assets(cls, group):
|
|
||||||
"""
|
|
||||||
:param group:
|
|
||||||
:return: {node: {asset: set(su1, su2)}}
|
|
||||||
"""
|
|
||||||
_assets = cls.get_user_group_assets(group)
|
|
||||||
tree = Tree()
|
|
||||||
for asset, _system_users in _assets.items():
|
|
||||||
_nodes = asset.get_nodes_or_cache()
|
|
||||||
tree.add_nodes(_nodes)
|
|
||||||
for node in _nodes:
|
|
||||||
tree.nodes[node][asset].update(_system_users)
|
|
||||||
return tree.nodes
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_assets_direct(cls, user):
|
|
||||||
assets = defaultdict(set)
|
|
||||||
permissions = list(cls.get_user_permissions(user))
|
|
||||||
for perm in permissions:
|
|
||||||
_assets = perm.assets.all().valid()
|
|
||||||
_system_users = perm.system_users.all()
|
|
||||||
set_or_append_attr_bulk(_assets, 'permission', perm.id)
|
|
||||||
for asset in _assets:
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes_direct(cls, user):
|
|
||||||
nodes = defaultdict(set)
|
|
||||||
permissions = cls.get_user_permissions(user)
|
|
||||||
for perm in permissions:
|
|
||||||
_nodes = perm.nodes.all()
|
|
||||||
_system_users = perm.system_users.all()
|
|
||||||
set_or_append_attr_bulk(_nodes, 'permission', perm.id)
|
|
||||||
for node in _nodes:
|
|
||||||
nodes[node].update(set(_system_users))
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes_inherit_group(cls, user):
|
|
||||||
nodes = defaultdict(set)
|
|
||||||
groups = user.groups.all()
|
|
||||||
for group in groups:
|
|
||||||
_nodes = cls.get_user_group_nodes(group)
|
|
||||||
for node, system_users in _nodes.items():
|
|
||||||
nodes[node].update(set(system_users))
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes(cls, user):
|
|
||||||
nodes = cls.get_user_nodes_direct(user)
|
|
||||||
nodes_inherit = cls.get_user_nodes_inherit_group(user)
|
|
||||||
for node, system_users in nodes_inherit.items():
|
|
||||||
nodes[node].update(set(system_users))
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes_assets_direct(cls, user):
|
|
||||||
assets = defaultdict(set)
|
|
||||||
nodes = cls.get_user_nodes_direct(user)
|
|
||||||
for node, _system_users in nodes.items():
|
|
||||||
_assets = node.get_all_valid_assets()
|
|
||||||
set_or_append_attr_bulk(_assets, 'inherit_node', node.id)
|
|
||||||
set_or_append_attr_bulk(_assets, 'permission', getattr(node, 'permission', None))
|
|
||||||
for asset in _assets:
|
|
||||||
assets[asset].update(set(_system_users))
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_assets_inherit_group(cls, user):
|
|
||||||
assets = defaultdict(set)
|
|
||||||
for group in user.groups.all():
|
|
||||||
_assets = cls.get_user_group_assets(group)
|
|
||||||
set_or_append_attr_bulk(_assets, 'inherit_group', group.id)
|
|
||||||
for asset, _system_users in _assets.items():
|
|
||||||
assets[asset].update(_system_users)
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_assets(cls, user):
|
|
||||||
assets = defaultdict(set)
|
|
||||||
_assets_direct = cls.get_user_assets_direct(user)
|
|
||||||
_nodes_assets_direct = cls.get_user_nodes_assets_direct(user)
|
|
||||||
_assets_inherit_group = cls.get_user_assets_inherit_group(user)
|
|
||||||
for asset, _system_users in _assets_direct.items():
|
|
||||||
assets[asset].update(_system_users)
|
|
||||||
for asset, _system_users in _nodes_assets_direct.items():
|
|
||||||
assets[asset].update(_system_users)
|
|
||||||
for asset, _system_users in _assets_inherit_group.items():
|
|
||||||
assets[asset].update(_system_users)
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes_with_assets(cls, user):
|
|
||||||
"""
|
|
||||||
:param user:
|
|
||||||
:return: {node: {asset: set(su1, su2)}}
|
|
||||||
"""
|
|
||||||
tree = Tree()
|
|
||||||
_assets = cls.get_user_assets(user)
|
|
||||||
for asset, _system_users in _assets.items():
|
|
||||||
tree.add_asset(asset, _system_users)
|
|
||||||
# _nodes = asset.get_nodes()
|
|
||||||
# tree.add_nodes(_nodes)
|
|
||||||
# for node in _nodes:
|
|
||||||
# tree.nodes[node][asset].update(_system_users)
|
|
||||||
return tree.nodes
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_system_user_assets(cls, system_user):
|
|
||||||
assets = set()
|
|
||||||
permissions = cls.get_system_user_permissions(system_user)
|
|
||||||
for perm in permissions:
|
|
||||||
assets.update(set(perm.assets.all().valid()))
|
|
||||||
nodes = perm.nodes.all()
|
|
||||||
for node in nodes:
|
|
||||||
assets.update(set(node.get_all_valid_assets()))
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_node_system_users(cls, node):
|
|
||||||
system_users = set()
|
|
||||||
permissions = cls.get_node_permissions(node)
|
|
||||||
for perm in permissions:
|
|
||||||
system_users.update(perm.system_users.all())
|
|
||||||
return system_users
|
|
||||||
|
|
||||||
|
|
||||||
# Abandon
|
|
||||||
class NodePermissionUtil:
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_user_group_permissions(user_group):
|
|
||||||
return user_group.nodepermission_set.all() \
|
|
||||||
.filter(is_active=True) \
|
|
||||||
.filter(date_expired__gt=timezone.now())
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_system_user_permissions(system_user):
|
|
||||||
return system_user.nodepermission_set.all() \
|
|
||||||
.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():
|
for node, system_users in nodes.items():
|
||||||
nodes_with_assets[node] = {
|
_assets = node.get_all_assets().valid().prefetch_related('nodes')
|
||||||
'assets': node.get_valid_assets(),
|
for asset in _assets:
|
||||||
'system_users': system_users
|
if isinstance(asset, Node):
|
||||||
}
|
print(_assets)
|
||||||
return nodes_with_assets
|
assets[asset].update(system_users)
|
||||||
|
|
||||||
@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
|
return assets
|
||||||
|
|
||||||
@classmethod
|
def get_nodes_with_assets(self):
|
||||||
def get_user_nodes(cls, user):
|
"""
|
||||||
nodes = collections.defaultdict(set)
|
返回节点并且包含资产
|
||||||
groups = user.groups.all()
|
{"node": {"assets": set("system_user")}}
|
||||||
for group in groups:
|
:return:
|
||||||
group_nodes = cls.get_user_group_nodes(group)
|
"""
|
||||||
for node, system_users in group_nodes.items():
|
assets = self.get_assets()
|
||||||
nodes[node].update(system_users)
|
nodes = defaultdict(dict)
|
||||||
|
for asset, system_users in assets.items():
|
||||||
|
_nodes = asset.nodes.all()
|
||||||
|
for node in _nodes:
|
||||||
|
if asset in nodes[node]:
|
||||||
|
nodes[node][asset].update(system_users)
|
||||||
|
else:
|
||||||
|
nodes[node][asset] = system_users
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user_nodes_with_assets(cls, user):
|
|
||||||
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
|
|
||||||
def get_user_assets(cls, user):
|
|
||||||
assets = collections.defaultdict(set)
|
|
||||||
nodes_with_assets = cls.get_user_nodes_with_assets(user)
|
|
||||||
|
|
||||||
for v in nodes_with_assets.values():
|
|
||||||
for asset in v['assets']:
|
|
||||||
assets[asset].update(v['system_users'])
|
|
||||||
return assets
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_system_user_assets(cls, system_user):
|
|
||||||
assets = set()
|
|
||||||
permissions = cls.get_system_user_permissions(system_user)
|
|
||||||
|
|
||||||
for perm in permissions:
|
|
||||||
assets.update(perm.node.get_all_assets())
|
|
||||||
return assets
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if grep -q 'source ~/.autoenv/activate.sh' ~/.bashrc; then
|
if grep -q 'source /opt/autoenv/activate.sh' ~/.bashrc; then
|
||||||
echo -e "\033[31m 正在自动载入 python 环境 \033[0m"
|
echo -e "\033[31m 正在自动载入 python 环境 \033[0m"
|
||||||
else
|
else
|
||||||
echo -e "\033[31m 不支持自动升级,请参考 http://docs.jumpserver.org/zh/docs/upgrade.html 手动升级 \033[0m"
|
echo -e "\033[31m 不支持自动升级,请参考 http://docs.jumpserver.org/zh/docs/upgrade.html 手动升级 \033[0m"
|
||||||
|
@ -40,5 +40,6 @@ git pull && pip install -r requirements/requirements.txt && cd utils && sh make_
|
||||||
cd .. && ./jms start all -d
|
cd .. && ./jms start all -d
|
||||||
echo -e "\033[31m 请检查jumpserver是否启动成功 \033[0m"
|
echo -e "\033[31m 请检查jumpserver是否启动成功 \033[0m"
|
||||||
echo -e "\033[31m 备份文件存放于$jumpserver_backup目录 \033[0m"
|
echo -e "\033[31m 备份文件存放于$jumpserver_backup目录 \033[0m"
|
||||||
|
stty erase ^?
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
Loading…
Reference in New Issue