mirror of https://github.com/jumpserver/jumpserver
[Update] 修改api和view
parent
d0ede246e7
commit
fffa0def9e
|
@ -27,13 +27,16 @@ class AssetCreateForm(forms.ModelForm):
|
||||||
'class': 'select2', 'data-placeholder': _('Admin user')
|
'class': 'select2', 'data-placeholder': _('Admin user')
|
||||||
}),
|
}),
|
||||||
'labels': forms.SelectMultiple(attrs={
|
'labels': forms.SelectMultiple(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Labels')
|
'class': 'select2', 'data-placeholder': _('Label')
|
||||||
}),
|
}),
|
||||||
'port': forms.TextInput(),
|
'port': forms.TextInput(),
|
||||||
'domain': forms.Select(attrs={
|
'domain': forms.Select(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Domain')
|
'class': 'select2', 'data-placeholder': _('Domain')
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
labels = {
|
||||||
|
'nodes': _("Node"),
|
||||||
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'hostname': '* required',
|
'hostname': '* required',
|
||||||
'ip': '* required',
|
'ip': '* required',
|
||||||
|
@ -57,19 +60,22 @@ class AssetUpdateForm(forms.ModelForm):
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'nodes': forms.SelectMultiple(attrs={
|
'nodes': forms.SelectMultiple(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Nodes')
|
'class': 'select2', 'data-placeholder': _('Node')
|
||||||
}),
|
}),
|
||||||
'admin_user': forms.Select(attrs={
|
'admin_user': forms.Select(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Admin user')
|
'class': 'select2', 'data-placeholder': _('Admin user')
|
||||||
}),
|
}),
|
||||||
'labels': forms.SelectMultiple(attrs={
|
'labels': forms.SelectMultiple(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Labels')
|
'class': 'select2', 'data-placeholder': _('Label')
|
||||||
}),
|
}),
|
||||||
'port': forms.TextInput(),
|
'port': forms.TextInput(),
|
||||||
'domain': forms.Select(attrs={
|
'domain': forms.Select(attrs={
|
||||||
'class': 'select2', 'data-placeholder': _('Domain')
|
'class': 'select2', 'data-placeholder': _('Domain')
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
labels = {
|
||||||
|
'nodes': _("Node"),
|
||||||
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'hostname': '* required',
|
'hostname': '* required',
|
||||||
'ip': '* required',
|
'ip': '* required',
|
||||||
|
@ -116,10 +122,10 @@ class AssetBulkUpdateForm(forms.ModelForm):
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'labels': forms.SelectMultiple(
|
'labels': forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select labels')}
|
attrs={'class': 'select2', 'data-placeholder': _('Label')}
|
||||||
),
|
),
|
||||||
'nodes': forms.SelectMultiple(
|
'nodes': forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select nodes')}
|
attrs={'class': 'select2', 'data-placeholder': _('Node')}
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import uuid
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -100,10 +101,11 @@ class SystemUser(AssetUser):
|
||||||
)
|
)
|
||||||
|
|
||||||
nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes"))
|
nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes"))
|
||||||
|
assets = models.ManyToManyField('assets.Asset', blank=True, verbose_name=_("Assets"))
|
||||||
priority = models.IntegerField(default=10, verbose_name=_("Priority"))
|
priority = models.IntegerField(default=10, verbose_name=_("Priority"))
|
||||||
protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
|
protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
|
||||||
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
|
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
|
||||||
sudo = models.TextField(default='/sbin/ifconfig', verbose_name=_('Sudo'))
|
sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo'))
|
||||||
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
|
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -119,9 +121,8 @@ class SystemUser(AssetUser):
|
||||||
'auto_push': self.auto_push,
|
'auto_push': self.auto_push,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
def get_assets(self):
|
||||||
def assets(self):
|
assets = set(self.assets.all())
|
||||||
assets = set()
|
|
||||||
for node in self.nodes.all():
|
for node in self.nodes.all():
|
||||||
assets.update(set(node.get_all_assets()))
|
assets.update(set(node.get_all_assets()))
|
||||||
return assets
|
return assets
|
||||||
|
@ -168,6 +169,3 @@ class SystemUser(AssetUser):
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
print('Error continue')
|
print('Error continue')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SystemUserSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_assets_amount(obj):
|
def get_assets_amount(obj):
|
||||||
return len(obj.assets)
|
return len(obj.get_assets())
|
||||||
|
|
||||||
|
|
||||||
class SystemUserAuthSerializer(AuthSerializer):
|
class SystemUserAuthSerializer(AuthSerializer):
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from collections import defaultdict
|
||||||
from django.db.models.signals import post_save, m2m_changed
|
from django.db.models.signals import post_save, m2m_changed
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .models import Asset, SystemUser, Node
|
from .models import Asset, SystemUser, Node
|
||||||
from .tasks import update_assets_hardware_info_util, \
|
from .tasks import update_assets_hardware_info_util, \
|
||||||
test_asset_connectability_util, push_system_user_to_node, \
|
test_asset_connectability_util, push_system_user_to_assets
|
||||||
push_node_system_users_to_asset
|
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
@ -31,7 +30,6 @@ def set_asset_root_node(asset):
|
||||||
|
|
||||||
@receiver(post_save, sender=Asset, dispatch_uid="my_unique_identifier")
|
@receiver(post_save, sender=Asset, dispatch_uid="my_unique_identifier")
|
||||||
def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
|
def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
|
||||||
# set_asset_root_node(instance)
|
|
||||||
if created:
|
if created:
|
||||||
logger.info("Asset `{}` create signal received".format(instance))
|
logger.info("Asset `{}` create signal received".format(instance))
|
||||||
update_asset_hardware_info_on_created(instance)
|
update_asset_hardware_info_on_created(instance)
|
||||||
|
@ -41,25 +39,39 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
|
||||||
@receiver(post_save, sender=SystemUser, dispatch_uid="my_unique_identifier")
|
@receiver(post_save, sender=SystemUser, dispatch_uid="my_unique_identifier")
|
||||||
def on_system_user_update(sender, instance=None, created=True, **kwargs):
|
def on_system_user_update(sender, instance=None, created=True, **kwargs):
|
||||||
if instance and not created:
|
if instance and not created:
|
||||||
for node in instance.nodes.all():
|
logger.info("System user `{}` update signal received".format(instance))
|
||||||
push_system_user_to_node(instance, node)
|
assets = instance.assets.all()
|
||||||
|
push_system_user_to_assets.delay(instance, assets)
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=SystemUser.nodes.through)
|
@receiver(m2m_changed, sender=SystemUser.nodes.through)
|
||||||
def on_system_user_node_change(sender, instance=None, **kwargs):
|
def on_system_user_nodes_change(sender, instance=None, **kwargs):
|
||||||
if instance and kwargs["action"] == "post_add":
|
if instance and kwargs["action"] == "post_add":
|
||||||
for pk in kwargs['pk_set']:
|
assets = set()
|
||||||
node = kwargs['model'].objects.get(pk=pk)
|
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
push_system_user_to_node(instance, node)
|
for node in nodes:
|
||||||
|
assets.update(set(node.get_all_assets()))
|
||||||
|
instance.assets.add(*tuple(assets))
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(m2m_changed, sender=SystemUser.assets.through)
|
||||||
|
def on_system_user_assets_change(sender, instance=None, **kwargs):
|
||||||
|
if instance and kwargs["action"] == "post_add":
|
||||||
|
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
push_system_user_to_assets(instance, assets)
|
||||||
|
|
||||||
|
|
||||||
@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) and kwargs['action'] == 'post_add':
|
if isinstance(instance, Asset) and kwargs['action'] == 'post_add':
|
||||||
logger.debug("Asset node change signal received")
|
logger.debug("Asset node change signal received")
|
||||||
for pk in kwargs['pk_set']:
|
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
node = kwargs['model'].objects.get(pk=pk)
|
system_users_assets = defaultdict(set)
|
||||||
push_node_system_users_to_asset(node, [instance])
|
system_users = SystemUser.objects.filter(nodes__in=nodes)
|
||||||
|
for system_user in system_users:
|
||||||
|
system_users_assets[system_user].update({instance})
|
||||||
|
for system_user, assets in system_users_assets.items():
|
||||||
|
system_user.assets.add(*tuple(assets))
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Asset.nodes.through)
|
@receiver(m2m_changed, sender=Asset.nodes.through)
|
||||||
|
@ -67,5 +79,6 @@ def on_node_assets_changed(sender, instance=None, **kwargs):
|
||||||
if isinstance(instance, Node) and kwargs['action'] == 'post_add':
|
if isinstance(instance, Node) and kwargs['action'] == 'post_add':
|
||||||
logger.debug("Node assets change signal received")
|
logger.debug("Node assets change signal received")
|
||||||
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
push_node_system_users_to_asset(instance, assets)
|
system_users = SystemUser.objects.filter(nodes=instance)
|
||||||
|
for system_user in system_users:
|
||||||
|
system_user.assets.add(*tuple(assets))
|
||||||
|
|
|
@ -386,52 +386,17 @@ def push_system_user_util(system_users, assets, task_name):
|
||||||
return task.run()
|
return task.run()
|
||||||
|
|
||||||
|
|
||||||
def get_node_push_system_user_task_name(system_user, node):
|
|
||||||
|
|
||||||
# return _("Push system user to node: {} => {}").format(
|
|
||||||
return _("推送系统用户到节点资产: {} => {}").format(
|
|
||||||
system_user.name,
|
|
||||||
node.value
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
|
||||||
def push_system_user_to_node(system_user, node):
|
|
||||||
logger.info("Start push system user node: {} => {}".format(system_user.name, node.value))
|
|
||||||
assets = node.get_all_assets()
|
|
||||||
task_name = get_node_push_system_user_task_name(system_user, node)
|
|
||||||
push_system_user_util([system_user], assets, task_name)
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
|
||||||
def push_system_user_related_nodes(system_user):
|
|
||||||
if not system_user.is_need_push():
|
|
||||||
msg = "push system user `{}` passed, may be not auto push or ssh " \
|
|
||||||
"protocol is not ssh".format(system_user.name)
|
|
||||||
logger.info(msg)
|
|
||||||
return
|
|
||||||
|
|
||||||
nodes = system_user.nodes.all()
|
|
||||||
for node in nodes:
|
|
||||||
push_system_user_to_node(system_user, node)
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def push_system_user_to_assets_manual(system_user):
|
def push_system_user_to_assets_manual(system_user):
|
||||||
push_system_user_related_nodes(system_user)
|
assets = system_user.get_assets()
|
||||||
|
task_name = "推送系统用户到入资产: {}".format(system_user.name)
|
||||||
|
return push_system_user_util([system_user], assets, task_name=task_name)
|
||||||
|
|
||||||
|
|
||||||
def push_node_system_users_to_asset(node, assets):
|
@shared_task
|
||||||
system_users = []
|
def push_system_user_to_assets(system_user, assets):
|
||||||
nodes = node.ancestor_with_node
|
task_name = _("推送系统用户到入资产: {}").format(system_user.name)
|
||||||
# 获取该节点所有父节点有的系统用户, 然后推送
|
return push_system_user_util.delay([system_user], assets, task_name)
|
||||||
for n in nodes:
|
|
||||||
system_users.extend(list(n.systemuser_set.all()))
|
|
||||||
|
|
||||||
if system_users:
|
|
||||||
# task_name = _("Push system users to node: {}").format(node.value)
|
|
||||||
task_name = _("推送节点系统用户到新加入资产中: {}").format(node.value)
|
|
||||||
push_system_user_util.delay(system_users, assets, task_name)
|
|
||||||
|
|
||||||
|
|
||||||
# @shared_task
|
# @shared_task
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<div class="form-group {% if form.errors.labels %} has-error {% endif %}">
|
<div class="form-group {% if form.errors.labels %} has-error {% endif %}">
|
||||||
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
|
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<select name="labels" class="select2 labels" data-placeholder="{% trans 'Select labels' %}" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
|
<select name="labels" class="select2 labels" data-placeholder="{% trans 'Label' %}" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
|
||||||
{% for name, labels in form.labels.field.queryset|group_labels %}
|
{% for name, labels in form.labels.field.queryset|group_labels %}
|
||||||
<optgroup label="{{ name }}">
|
<optgroup label="{{ name }}">
|
||||||
{% for label in labels %}
|
{% for label in labels %}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
|
<label for="{{ form.labels.id_for_label }}" class="col-md-2 control-label">{% trans 'Label' %}</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<select name="labels" class="select2 labels" data-placeholder="Select labels" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
|
<select name="labels" class="select2 labels" data-placeholder="{% trans 'Label' %}" style="width: 100%" multiple="" tabindex="4" id="{{ form.labels.id_for_label }}">
|
||||||
{% for name, labels in form.labels.field.queryset|group_labels %}
|
{% for name, labels in form.labels.field.queryset|group_labels %}
|
||||||
<optgroup label="{{ name }}">
|
<optgroup label="{{ name }}">
|
||||||
{% for label in labels %}
|
{% for label in labels %}
|
||||||
|
|
|
@ -7,9 +7,9 @@ from rest_framework.generics import ListAPIView, get_object_or_404
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
|
|
||||||
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
|
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
|
||||||
from .utils import NodePermissionUtil
|
from .utils import AssetPermissionUtil
|
||||||
from .models import NodePermission
|
from .models import AssetPermission
|
||||||
from .hands import AssetGrantedSerializer, User, UserGroup, Asset, \
|
from .hands import AssetGrantedSerializer, User, UserGroup, Asset, Node, \
|
||||||
NodeGrantedSerializer, SystemUser, NodeSerializer
|
NodeGrantedSerializer, SystemUser, NodeSerializer
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
资产授权列表的增删改查api
|
资产授权列表的增删改查api
|
||||||
"""
|
"""
|
||||||
queryset = NodePermission.objects.all()
|
queryset = AssetPermission.objects.all()
|
||||||
serializer_class = serializers.AssetPermissionCreateUpdateSerializer
|
serializer_class = serializers.AssetPermissionCreateUpdateSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
@ -27,15 +27,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
|
||||||
return serializers.AssetPermissionListSerializer
|
return serializers.AssetPermissionListSerializer
|
||||||
return self.serializer_class
|
return self.serializer_class
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
queryset = super().get_queryset()
|
|
||||||
node_id = self.request.query_params.get('node_id')
|
|
||||||
|
|
||||||
if node_id:
|
|
||||||
queryset = queryset.filter(node__id=node_id)
|
|
||||||
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
|
|
||||||
class UserGrantedAssetsApi(ListAPIView):
|
class UserGrantedAssetsApi(ListAPIView):
|
||||||
"""
|
"""
|
||||||
|
@ -53,7 +44,7 @@ class UserGrantedAssetsApi(ListAPIView):
|
||||||
else:
|
else:
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
|
|
||||||
for k, v in NodePermissionUtil.get_user_assets(user).items():
|
for k, v in AssetPermissionUtil.get_user_assets(user).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:
|
||||||
|
@ -78,14 +69,14 @@ 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 = NodePermissionUtil.get_user_nodes(user)
|
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
||||||
return nodes.keys()
|
return nodes.keys()
|
||||||
|
|
||||||
|
|
||||||
class UserGrantedNodesWithAssetsApi(ListAPIView):
|
class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
"""
|
"""
|
||||||
授权用户的资产组,注:这里的资产组并非是授权列表中授权的,
|
授权用户的资产组,注:这里的资产组并非是授权列表中授权的,
|
||||||
而是把所有资产取出来,然后反查出所有资产组,然后合并得到,
|
而是把所有资产取出来,然后反查出所有节点,然后合并得到,
|
||||||
结果里也包含资产组下授权的资产
|
结果里也包含资产组下授权的资产
|
||||||
数据结构如下:
|
数据结构如下:
|
||||||
[
|
[
|
||||||
|
@ -121,18 +112,12 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
else:
|
else:
|
||||||
user = get_object_or_404(User, id=user_id)
|
user = get_object_or_404(User, id=user_id)
|
||||||
|
|
||||||
nodes = NodePermissionUtil.get_user_nodes_with_assets(user)
|
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
||||||
assets = {}
|
for node, _assets in nodes.items():
|
||||||
for k, v in NodePermissionUtil.get_user_assets(user).items():
|
assets = _assets.keys()
|
||||||
if k.is_unixlike():
|
for asset, system_users in _assets.items():
|
||||||
system_users_granted = [s for s in v if s.protocol == 'ssh']
|
asset.system_users_granted = system_users
|
||||||
else:
|
node.assets_granted = assets
|
||||||
system_users_granted = [s for s in v if s.protocol == 'rdp']
|
|
||||||
assets[k] = system_users_granted
|
|
||||||
for node, v in nodes.items():
|
|
||||||
for asset in v['assets']:
|
|
||||||
asset.system_users_granted = assets[asset]
|
|
||||||
node.assets_granted = v['assets']
|
|
||||||
queryset.append(node)
|
queryset.append(node)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
@ -142,6 +127,26 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
return super().get_permissions()
|
return super().get_permissions()
|
||||||
|
|
||||||
|
|
||||||
|
class UserGrantedNodeAssetsApi(ListAPIView):
|
||||||
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
|
serializer_class = AssetGrantedSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
user_id = self.kwargs.get('pk', '')
|
||||||
|
node_id = self.kwargs.get('node_id')
|
||||||
|
|
||||||
|
if user_id:
|
||||||
|
user = get_object_or_404(User, id=user_id)
|
||||||
|
else:
|
||||||
|
user = self.request.user
|
||||||
|
node = get_object_or_404(Node, id=node_id)
|
||||||
|
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
|
||||||
|
assets = nodes.get(node, [])
|
||||||
|
for asset, system_users in assets.items():
|
||||||
|
asset.system_users_granted = system_users
|
||||||
|
return assets
|
||||||
|
|
||||||
|
|
||||||
class UserGroupGrantedAssetsApi(ListAPIView):
|
class UserGroupGrantedAssetsApi(ListAPIView):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
serializer_class = AssetGrantedSerializer
|
serializer_class = AssetGrantedSerializer
|
||||||
|
@ -154,7 +159,7 @@ 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 = NodePermissionUtil.get_user_group_assets(user_group)
|
assets = AssetPermissionUtil.get_user_group_assets(user_group)
|
||||||
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)
|
||||||
|
@ -171,8 +176,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 = NodePermissionUtil.get_user_group_nodes(group)
|
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(group)
|
||||||
queryset = nodes.keys()
|
return nodes.keys()
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,15 +193,33 @@ 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 = NodePermissionUtil.get_user_group_nodes_with_assets(user_group)
|
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(user_group)
|
||||||
for node, v in nodes.items():
|
for node, _assets in nodes.items():
|
||||||
for asset in v['assets']:
|
assets = _assets.keys()
|
||||||
asset.system_users_granted = v['system_users']
|
for asset, system_users in _assets.items():
|
||||||
node.assets_granted = v['assets']
|
asset.system_users_granted = system_users
|
||||||
|
node.assets_granted = assets
|
||||||
queryset.append(node)
|
queryset.append(node)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupGrantedNodeAssetsApi(ListAPIView):
|
||||||
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
|
serializer_class = AssetGrantedSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
user_group_id = self.kwargs.get('pk', '')
|
||||||
|
node_id = self.kwargs.get('node_id')
|
||||||
|
|
||||||
|
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
||||||
|
node = get_object_or_404(Node, id=node_id)
|
||||||
|
nodes = AssetPermissionUtil.get_user_group_nodes_with_assets(user_group)
|
||||||
|
assets = nodes.get(node, [])
|
||||||
|
for asset, system_users in assets.items():
|
||||||
|
asset.system_users_granted = system_users
|
||||||
|
return assets
|
||||||
|
|
||||||
|
|
||||||
class ValidateUserAssetPermissionView(APIView):
|
class ValidateUserAssetPermissionView(APIView):
|
||||||
permission_classes = (IsSuperUserOrAppUser,)
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
|
|
||||||
|
@ -210,7 +233,7 @@ 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 = NodePermissionUtil.get_user_assets(user)
|
assets_granted = AssetPermissionUtil.get_user_assets(user)
|
||||||
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,29 +1,19 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from common.utils import get_object_or_none
|
from .models import AssetPermission
|
||||||
from common.fields import StringIDField
|
|
||||||
from .models import AssetPermission, NodePermission
|
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
|
class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NodePermission
|
model = AssetPermission
|
||||||
fields = [
|
exclude = ('id', 'create_by', 'date_created')
|
||||||
'id', 'node', 'user_group', 'system_user',
|
|
||||||
'is_active', 'date_expired'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionListSerializer(serializers.ModelSerializer):
|
class AssetPermissionListSerializer(serializers.ModelSerializer):
|
||||||
node = StringIDField(read_only=True)
|
|
||||||
user_group = StringIDField(read_only=True)
|
|
||||||
system_user = StringIDField(read_only=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NodePermission
|
model = AssetPermission
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,14 +30,3 @@ class AssetPermissionUpdateAssetSerializer(serializers.ModelSerializer):
|
||||||
model = AssetPermission
|
model = AssetPermission
|
||||||
fields = ['id', 'assets']
|
fields = ['id', 'assets']
|
||||||
|
|
||||||
|
|
||||||
class UserAssetPermissionCreateUpdateSerializer(AssetPermissionCreateUpdateSerializer):
|
|
||||||
is_inherited = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_is_inherited(obj):
|
|
||||||
if getattr(obj, 'inherited', ''):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,42 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from django.db.models.signals import m2m_changed
|
||||||
from django.db.models.signals import post_save, post_delete
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .models import NodePermission
|
from .models import AssetPermission
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=NodePermission, dispatch_uid="my_unique_identifier")
|
@receiver(m2m_changed, sender=AssetPermission.nodes.through)
|
||||||
def on_asset_permission_create_or_update(sender, instance=None, **kwargs):
|
def on_permission_nodes_changed(sender, instance=None, **kwargs):
|
||||||
if instance and instance.node and instance.system_user:
|
if isinstance(instance, AssetPermission) and kwargs['action'] == 'post_add':
|
||||||
instance.system_user.nodes.add(instance.node)
|
logger.debug("Asset permission nodes change signal received")
|
||||||
|
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
system_users = instance.system_users.all()
|
||||||
|
for system_user in system_users:
|
||||||
|
system_user.nodes.add(*tuple(nodes))
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(m2m_changed, sender=AssetPermission.assets.through)
|
||||||
|
def on_permission_assets_changed(sender, instance=None, **kwargs):
|
||||||
|
if isinstance(instance, AssetPermission) and kwargs['action'] == 'post_add':
|
||||||
|
logger.debug("Asset permission assets change signal received")
|
||||||
|
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
system_users = instance.system_users.all()
|
||||||
|
for system_user in system_users:
|
||||||
|
system_user.assets.add(*tuple(assets))
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(m2m_changed, sender=AssetPermission.system_users.through)
|
||||||
|
def on_permission_system_users_changed(sender, instance=None, **kwargs):
|
||||||
|
if isinstance(instance, AssetPermission) and kwargs['action'] == 'post_add':
|
||||||
|
logger.debug("Asset permission system_users change signal received")
|
||||||
|
system_users = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
assets = instance.assets.all()
|
||||||
|
nodes = instance.nodes.all()
|
||||||
|
for system_user in system_users:
|
||||||
|
system_user.nodes.add(*tuple(nodes))
|
||||||
|
system_user.assets.add(*tuple(assets))
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{% url 'perms:asset-permission-update' pk=object.id %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>
|
<a href="{% url 'perms:asset-permission-update' pk=object.id %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>
|
||||||
<a href="" class="btn btn-xs btn-danger m-l-xs">{% trans "Delete" %}</a>
|
<a data-uid="{{ object.id }}" class="btn btn-xs btn-danger m-l-xs btn-delete">{% trans "Delete" %}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ object.users_detail }}</td>
|
<td>{{ object.users_detail }}</td>
|
||||||
<td>{{ object.user_groups_detail }}</td>
|
<td>{{ object.user_groups_detail }}</td>
|
||||||
|
@ -147,6 +147,15 @@
|
||||||
calendarWeeks: true,
|
calendarWeeks: true,
|
||||||
autoclose: true
|
autoclose: true
|
||||||
});
|
});
|
||||||
|
}).on('click', '.btn-delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var uid = $this.data('uid');
|
||||||
|
var the_url = '{% url "api-perms:asset-permission-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
setTimeout( function () {
|
||||||
|
window.reload();
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -15,6 +15,8 @@ urlpatterns = [
|
||||||
url(r'^v1/user/assets/$', api.UserGrantedAssetsApi.as_view(), name='my-assets'),
|
url(r'^v1/user/assets/$', api.UserGrantedAssetsApi.as_view(), name='my-assets'),
|
||||||
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', api.UserGrantedNodesApi.as_view(), name='user-nodes'),
|
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', api.UserGrantedNodesApi.as_view(), name='user-nodes'),
|
||||||
url(r'^v1/user/nodes/$', api.UserGrantedNodesApi.as_view(), name='my-nodes'),
|
url(r'^v1/user/nodes/$', api.UserGrantedNodesApi.as_view(), name='my-nodes'),
|
||||||
|
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedNodeAssetsApi.as_view(), name='user-node-assets'),
|
||||||
|
url(r'^v1/user/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedNodeAssetsApi.as_view(), name='my-node-assets'),
|
||||||
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes-assets'),
|
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes-assets'),
|
||||||
url(r'^v1/user/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='my-nodes-assets'),
|
url(r'^v1/user/nodes-assets/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='my-nodes-assets'),
|
||||||
|
|
||||||
|
@ -22,6 +24,7 @@ urlpatterns = [
|
||||||
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
|
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
|
||||||
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'),
|
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'),
|
||||||
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGroupGrantedNodesWithAssetsApi.as_view(), name='user-group-nodes-assets'),
|
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$', api.UserGroupGrantedNodesWithAssetsApi.as_view(), name='user-group-nodes-assets'),
|
||||||
|
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedNodeAssetsApi.as_view(), name='user-group-node-assets'),
|
||||||
|
|
||||||
# 验证用户是否有某个资产和系统用户的权限
|
# 验证用户是否有某个资产和系统用户的权限
|
||||||
url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'),
|
url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'),
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .models import AssetPermission
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionUtils:
|
class AssetPermissionUtil:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_permissions(user):
|
def get_user_permissions(user):
|
||||||
|
@ -81,6 +81,23 @@ class AssetPermissionUtils:
|
||||||
assets[asset].update(set(_system_users))
|
assets[asset].update(set(_system_users))
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_user_group_nodes_with_assets(cls, user):
|
||||||
|
"""
|
||||||
|
:param user:
|
||||||
|
:return: {node: {asset: set(su1, su2)}}
|
||||||
|
"""
|
||||||
|
nodes = defaultdict(dict)
|
||||||
|
_assets = cls.get_user_group_assets(user)
|
||||||
|
for asset, _system_users in _assets.items():
|
||||||
|
_nodes = asset.get_nodes()
|
||||||
|
for node in _nodes:
|
||||||
|
if asset in nodes[node]:
|
||||||
|
nodes[node][asset].update(_system_users)
|
||||||
|
else:
|
||||||
|
nodes[node][asset] = _system_users
|
||||||
|
return nodes
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_user_assets_direct(cls, user):
|
def get_user_assets_direct(cls, user):
|
||||||
assets = defaultdict(set)
|
assets = defaultdict(set)
|
||||||
|
@ -142,7 +159,7 @@ class AssetPermissionUtils:
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_user_node_with_assets(cls, user):
|
def get_user_nodes_with_assets(cls, user):
|
||||||
"""
|
"""
|
||||||
:param user:
|
:param user:
|
||||||
:return: {node: {asset: set(su1, su2)}}
|
:return: {node: {asset: set(su1, su2)}}
|
||||||
|
@ -178,8 +195,11 @@ class AssetPermissionUtils:
|
||||||
return system_users
|
return system_users
|
||||||
|
|
||||||
|
|
||||||
|
# Abandon
|
||||||
class NodePermissionUtil:
|
class NodePermissionUtil:
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_group_permissions(user_group):
|
def get_user_group_permissions(user_group):
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<th class="text-center">{% trans 'Hostname' %}</th>
|
<th class="text-center">{% trans 'Hostname' %}</th>
|
||||||
<th class="text-center">{% trans 'IP' %}</th>
|
<th class="text-center">{% trans 'IP' %}</th>
|
||||||
<th class="text-center">{% trans 'Active' %}</th>
|
<th class="text-center">{% trans 'Active' %}</th>
|
||||||
<th class="text-center">{% trans 'Reachable' %}</th>
|
<th class="text-center">{% trans 'System users' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -63,6 +63,8 @@
|
||||||
<script>
|
<script>
|
||||||
var zTree;
|
var zTree;
|
||||||
var inited = false;
|
var inited = false;
|
||||||
|
var url;
|
||||||
|
var asset_table;
|
||||||
|
|
||||||
function initTable() {
|
function initTable() {
|
||||||
if (inited){
|
if (inited){
|
||||||
|
@ -86,31 +88,28 @@ function initTable() {
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
if (cellData === 'Unknown'){
|
var users = [];
|
||||||
$(td).html('<i class="fa fa-circle text-warning"></i>')
|
$.each(cellData, function (id, data) {
|
||||||
} else if (!cellData) {
|
users.push(data.name);
|
||||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
});
|
||||||
} else {
|
$(td).html(users.join(', '))
|
||||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "api-assets:asset-list" %}',
|
ajax_url: url,
|
||||||
columns: [
|
columns: [
|
||||||
{data: "id"}, {data: "hostname" }, {data: "ip" },
|
{data: "id"}, {data: "hostname" }, {data: "ip" },
|
||||||
{data: "is_active", orderable: false },
|
{data: "is_active", orderable: false },
|
||||||
{data: "is_connective", orderable: false}
|
{data: "system_users_granted", orderable: false}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
asset_table = jumpserver.initServerSideDataTable(options);
|
return jumpserver.initDataTable(options);
|
||||||
return asset_table
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSelected(event, treeNode) {
|
function onSelected(event, treeNode) {
|
||||||
initTable();
|
url = '{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}';
|
||||||
var url = asset_table.ajax.url();
|
url = url.replace("{{ DEFAULT_PK }}", treeNode.id);
|
||||||
url = setUrlParam(url, "node_id", treeNode.id);
|
|
||||||
setCookie('node_selected', treeNode.id);
|
setCookie('node_selected', treeNode.id);
|
||||||
|
asset_table = initTable();
|
||||||
asset_table.ajax.url(url);
|
asset_table.ajax.url(url);
|
||||||
asset_table.ajax.reload();
|
asset_table.ajax.reload();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
<script>
|
<script>
|
||||||
var zTree;
|
var zTree;
|
||||||
var inited = false;
|
var inited = false;
|
||||||
|
var url;
|
||||||
|
|
||||||
function initTable() {
|
function initTable() {
|
||||||
if (inited){
|
if (inited){
|
||||||
|
@ -86,31 +87,29 @@ function initTable() {
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
if (cellData === 'Unknown'){
|
var users = [];
|
||||||
$(td).html('<i class="fa fa-circle text-warning"></i>')
|
$.each(cellData, function (id, data) {
|
||||||
} else if (!cellData) {
|
users.push(data.name);
|
||||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
});
|
||||||
} else {
|
$(td).html(users.join(', '))
|
||||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "api-assets:asset-list" %}',
|
ajax_url: url,
|
||||||
columns: [
|
columns: [
|
||||||
{data: "id"}, {data: "hostname" }, {data: "ip" },
|
{data: "id"}, {data: "hostname" }, {data: "ip" },
|
||||||
{data: "is_active", orderable: false },
|
{data: "is_active", orderable: false },
|
||||||
{data: "is_connective", orderable: false}
|
{data: "system_users_granted", orderable: false}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
asset_table = jumpserver.initServerSideDataTable(options);
|
asset_table = jumpserver.initDataTable(options);
|
||||||
return asset_table
|
return asset_table
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSelected(event, treeNode) {
|
function onSelected(event, treeNode) {
|
||||||
initTable();
|
url = '{% url "api-perms:user-group-node-assets" pk=object.id node_id=DEFAULT_PK %}';
|
||||||
var url = asset_table.ajax.url();
|
url = url.replace("{{ DEFAULT_PK }}", treeNode.id);
|
||||||
url = setUrlParam(url, "node_id", treeNode.id);
|
|
||||||
setCookie('node_selected', treeNode.id);
|
setCookie('node_selected', treeNode.id);
|
||||||
|
asset_table = initTable();
|
||||||
asset_table.ajax.url(url);
|
asset_table.ajax.url(url);
|
||||||
asset_table.ajax.reload();
|
asset_table.ajax.reload();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue