mirror of https://github.com/jumpserver/jumpserver
Stash
parent
8f699fa366
commit
ae690050e7
|
@ -50,19 +50,14 @@ class AssetSystemUserSerializer(serializers.ModelSerializer):
|
|||
"""
|
||||
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
|
||||
"""
|
||||
actions = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = SystemUser
|
||||
fields = (
|
||||
'id', 'name', 'username', 'priority',
|
||||
'protocol', 'comment', 'login_mode', 'actions',
|
||||
'protocol', 'comment', 'login_mode',
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_actions(obj):
|
||||
return [action.name for action in obj.actions]
|
||||
|
||||
|
||||
class SystemUserSimpleSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
|
|
|
@ -54,17 +54,19 @@ class NodeUtil:
|
|||
def sorted_by(node):
|
||||
return [int(i) for i in node.key.split(':')]
|
||||
|
||||
def get_all_nodes(self):
|
||||
def get_queryset(self):
|
||||
all_nodes = Node.objects.all()
|
||||
if self.with_assets_amount:
|
||||
now = time.time()
|
||||
all_nodes = all_nodes.prefetch_related(
|
||||
Prefetch('assets', queryset=Asset.objects.all().only('id'))
|
||||
)
|
||||
all_nodes = list(all_nodes)
|
||||
for node in all_nodes:
|
||||
node._assets = set(node.assets.all())
|
||||
all_nodes = sorted(all_nodes, key=self.sorted_by)
|
||||
return all_nodes
|
||||
|
||||
def get_all_nodes(self):
|
||||
all_nodes = sorted(self.get_queryset(), key=self.sorted_by)
|
||||
|
||||
guarder = Node(key='', value='Guarder')
|
||||
guarder._assets = []
|
||||
|
@ -119,11 +121,11 @@ class NodeUtil:
|
|||
def get_nodes_by_queryset(self, queryset):
|
||||
nodes = []
|
||||
for n in queryset:
|
||||
node = self._nodes.get(n.key)
|
||||
node = self.get_node_by_key(n.key)
|
||||
if not node:
|
||||
continue
|
||||
nodes.append(nodes)
|
||||
return [self]
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
def get_node_by_key(self, key):
|
||||
return self._nodes.get(key)
|
||||
|
@ -156,11 +158,17 @@ class NodeUtil:
|
|||
tree_nodes.add(node)
|
||||
if with_children:
|
||||
tree_nodes.update(node._children)
|
||||
for n in tree_nodes:
|
||||
delattr(n, '_children')
|
||||
delattr(n, '_parents')
|
||||
return list(tree_nodes)
|
||||
|
||||
def get_nodes_parents(self, nodes, with_self=True):
|
||||
parents = set()
|
||||
for n in nodes:
|
||||
node = self.get_node_by_key(n.key)
|
||||
parents.update(set(node._parents))
|
||||
if with_self:
|
||||
parents.add(node)
|
||||
return parents
|
||||
|
||||
|
||||
def test_node_tree():
|
||||
tree = NodeUtil()
|
||||
|
|
|
@ -35,7 +35,8 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
|
|||
permission_classes = (IsOrgAdmin,)
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action in ("list", 'retrieve'):
|
||||
if self.action in ("list", 'retrieve') and \
|
||||
self.request.query_params.get("display"):
|
||||
return serializers.AssetPermissionListSerializer
|
||||
return self.serializer_class
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
import time
|
||||
from hashlib import md5
|
||||
from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
|
@ -261,14 +261,19 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionCacheMixin, ListAPIView)
|
|||
nodes = util.get_nodes_with_assets()
|
||||
print("22222222222222")
|
||||
for node, assets in nodes.items():
|
||||
now = time.time()
|
||||
print("Parse to node")
|
||||
data = parse_node_to_tree_node(node)
|
||||
print("parse to node end, using: {0:.2f}".format(time.time() - now))
|
||||
queryset.append(data)
|
||||
if not self.show_assets:
|
||||
continue
|
||||
for asset, system_users in assets.items():
|
||||
now1 = time.time()
|
||||
print("parse to asset")
|
||||
data = parse_asset_to_tree_node(node, asset, system_users)
|
||||
print("parse to asset end, using: {0:.2f}".format(time.time()-now1))
|
||||
queryset.append(data)
|
||||
queryset = sorted(queryset)
|
||||
return queryset
|
||||
|
||||
|
||||
|
|
|
@ -74,13 +74,13 @@ class AssetPermissionForm(OrgModelForm):
|
|||
'system_users': forms.SelectMultiple(
|
||||
attrs={'class': 'select2', 'data-placeholder': _('System user')}
|
||||
),
|
||||
'action': forms.CheckboxSelectMultiple()
|
||||
'actions': forms.CheckboxSelectMultiple()
|
||||
}
|
||||
labels = {
|
||||
'nodes': _("Node"),
|
||||
}
|
||||
help_texts = {
|
||||
'action': _('Tips: The RDP protocol does not support separate '
|
||||
'actions': _('Tips: The RDP protocol does not support separate '
|
||||
'controls for uploading or downloading files')
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='assetpermission',
|
||||
name='action',
|
||||
field=models.IntegerField(choices=[(255, 'All'), (1, 'Connect'), (2, 'Upload file'), (5, 'Upload download'), (4, 'Download file')], default=255, verbose_name='Action'),
|
||||
field=models.IntegerField(choices=[(255, 'All'), (1, 'Connect'), (2, 'Upload file'), (4, 'Download file'), (6, 'Upload download')], default=255, verbose_name='Actions'),
|
||||
),
|
||||
migrations.RunPython(migrate_old_actions),
|
||||
]
|
||||
|
|
|
@ -14,4 +14,9 @@ class Migration(migrations.Migration):
|
|||
model_name='assetpermission',
|
||||
name='actions',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='assetpermission',
|
||||
old_name='action',
|
||||
new_name='actions',
|
||||
),
|
||||
]
|
||||
|
|
|
@ -39,39 +39,46 @@ class ActionFlag:
|
|||
UPLOAD = 0b00000010
|
||||
DOWNLOAD = 0b00000100
|
||||
UPDOWNLOAD = UPLOAD | DOWNLOAD
|
||||
CONNECT_UPLOADOWN = CONNECT | UPDOWNLOAD
|
||||
ALL = 0b11111111
|
||||
NAME_MAP = {
|
||||
"connect": CONNECT,
|
||||
"upload": UPLOAD,
|
||||
"download": DOWNLOAD,
|
||||
"updownload": UPDOWNLOAD,
|
||||
"all": ALL,
|
||||
}
|
||||
|
||||
CHOICES = (
|
||||
DB_CHOICES = (
|
||||
(ALL, _('All')),
|
||||
(CONNECT, _('Connect')),
|
||||
(UPDOWNLOAD, _("Upload download")),
|
||||
(UPLOAD, _('Upload file')),
|
||||
(DOWNLOAD, _('Download file')),
|
||||
(UPDOWNLOAD, _("Upload download")),
|
||||
)
|
||||
|
||||
NAME_MAP = {
|
||||
ALL: "all",
|
||||
CONNECT: "connect",
|
||||
UPLOAD: "upload_file",
|
||||
DOWNLOAD: "download_file",
|
||||
UPDOWNLOAD: "updownload",
|
||||
}
|
||||
|
||||
NAME_MAP_REVERSE = dict({v: k for k, v in NAME_MAP.items()})
|
||||
CHOICES = []
|
||||
for i, j in DB_CHOICES:
|
||||
CHOICES.append((NAME_MAP[i], j))
|
||||
|
||||
@classmethod
|
||||
def value_to_choices(cls, value):
|
||||
value = int(value)
|
||||
if value == cls.ALL:
|
||||
return [cls.ALL]
|
||||
elif value == cls.UPDOWNLOAD:
|
||||
return [cls.UPDOWNLOAD]
|
||||
elif value == cls.CONNECT_UPLOADOWN:
|
||||
return [cls.CONNECT, cls.UPDOWNLOAD]
|
||||
else:
|
||||
return [i for i in dict(cls.CHOICES) if i == i & int(value)]
|
||||
choices = [cls.NAME_MAP[i] for i, j in cls.DB_CHOICES if value & i == i]
|
||||
return choices
|
||||
|
||||
@classmethod
|
||||
def choices_to_value(cls, value):
|
||||
return reduce(lambda x, y: int(x) | int(y), value)
|
||||
def to_choices(x, y):
|
||||
x = cls.NAME_MAP_REVERSE.get(x, 0)
|
||||
y = cls.NAME_MAP_REVERSE.get(y, 0)
|
||||
return x | y
|
||||
return reduce(to_choices, value)
|
||||
|
||||
@classmethod
|
||||
def choices(cls):
|
||||
return [(cls.NAME_MAP[i], j) for i, j in cls.DB_CHOICES]
|
||||
|
||||
|
||||
class AssetPermission(BasePermission):
|
||||
|
@ -79,7 +86,7 @@ class AssetPermission(BasePermission):
|
|||
nodes = models.ManyToManyField('assets.Node', related_name='granted_by_permissions', blank=True, verbose_name=_("Nodes"))
|
||||
system_users = models.ManyToManyField('assets.SystemUser', related_name='granted_by_permissions', verbose_name=_("System user"))
|
||||
# actions = models.ManyToManyField(Action, related_name='permissions', blank=True, verbose_name=_('Action'))
|
||||
action = models.IntegerField(choices=ActionFlag.CHOICES, default=ActionFlag.ALL, verbose_name=_("Action"))
|
||||
actions = models.IntegerField(choices=ActionFlag.DB_CHOICES, default=ActionFlag.ALL, verbose_name=_("Actions"))
|
||||
|
||||
class Meta:
|
||||
unique_together = [('org_id', 'name')]
|
||||
|
|
|
@ -38,7 +38,7 @@ class ActionDisplayField(ActionField):
|
|||
|
||||
|
||||
class AssetPermissionCreateUpdateSerializer(BulkOrgResourceModelSerializer):
|
||||
action = ActionField()
|
||||
actions = ActionField()
|
||||
|
||||
class Meta:
|
||||
model = AssetPermission
|
||||
|
@ -51,7 +51,7 @@ class AssetPermissionListSerializer(BulkOrgResourceModelSerializer):
|
|||
assets = StringManyToManyField(many=True, read_only=True)
|
||||
nodes = StringManyToManyField(many=True, read_only=True)
|
||||
system_users = StringManyToManyField(many=True, read_only=True)
|
||||
action = ActionDisplayField()
|
||||
actions = ActionDisplayField()
|
||||
is_valid = serializers.BooleanField()
|
||||
is_expired = serializers.BooleanField()
|
||||
|
||||
|
|
|
@ -122,8 +122,8 @@ function format(d) {
|
|||
if (d.system_users.length > 0) {
|
||||
data += makeLabel(["{% trans 'System user' %}", d.system_users.join(", ")])
|
||||
}
|
||||
if (d.action.length > 0) {
|
||||
data += makeLabel(["{% trans 'Action' %}", d.action.join(", ")])
|
||||
if (d.actions.length > 0) {
|
||||
data += makeLabel(["{% trans 'Action' %}", d.actions.join(", ")])
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ function initTable() {
|
|||
$(td).html(update_btn + del_btn);
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-perms:asset-permission-list" %}',
|
||||
ajax_url: '{% url "api-perms:asset-permission-list" %}?display=1',
|
||||
columns: [
|
||||
{data: "id"}, {data: "name"}, {data: "users"},
|
||||
{data: "user_groups"}, {data: "assets"},
|
||||
|
|
|
@ -17,8 +17,8 @@ from orgs.utils import set_to_root_org
|
|||
from common.utils import get_logger
|
||||
from common.tree import TreeNode
|
||||
from .. import const
|
||||
from ..models import AssetPermission, Action
|
||||
from ..hands import Node
|
||||
from ..models import AssetPermission, Action, ActionFlag
|
||||
from ..hands import Node, Asset
|
||||
from assets.utils import NodeUtil
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
@ -31,17 +31,57 @@ __all__ = [
|
|||
]
|
||||
|
||||
|
||||
class TreeNodeCounter(NodeUtil):
|
||||
def __init__(self, nodes):
|
||||
self.__nodes = nodes
|
||||
super().__init__(with_assets_amount=True)
|
||||
|
||||
def get_queryset(self):
|
||||
return self.__nodes
|
||||
|
||||
|
||||
def timeit(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.debug("Start call: {}".format(func.__name__))
|
||||
now = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
using = time.time() - now
|
||||
logger.debug("Call {} end, using: {:.2}s".format(func.__name__, using))
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
||||
class GenerateTree:
|
||||
def __init__(self):
|
||||
"""
|
||||
nodes: {"node_instance": {
|
||||
"asset_instance": set("system_user")
|
||||
nodes = {
|
||||
"<node1>": {
|
||||
"system_users": {
|
||||
"system_user": action,
|
||||
"system_user2": action,
|
||||
},
|
||||
"assets": set([<asset_instance>]),
|
||||
}
|
||||
}
|
||||
assets = {
|
||||
"<asset_instance2>": {
|
||||
"system_user": action,
|
||||
"system_user2": action,
|
||||
},
|
||||
}
|
||||
"""
|
||||
self.node_util = NodeUtil()
|
||||
self.nodes = defaultdict(dict)
|
||||
self._node_util = None
|
||||
self.nodes = defaultdict(lambda: {"system_users": defaultdict(int), "assets": set(), "assets_amount": 0})
|
||||
self.assets = defaultdict(lambda: defaultdict(int))
|
||||
self._root_node = None
|
||||
self._ungroup_node = None
|
||||
self._nodes_with_assets = None
|
||||
|
||||
@property
|
||||
def node_util(self):
|
||||
if not self._node_util:
|
||||
self._node_util = NodeUtil()
|
||||
return self._node_util
|
||||
|
||||
@property
|
||||
def root_node(self):
|
||||
|
@ -66,35 +106,79 @@ class GenerateTree:
|
|||
node_key = '0:0'
|
||||
node_value = _("Default")
|
||||
node = Node(id=node_id, key=node_key, value=node_value)
|
||||
self.add_node(node)
|
||||
self.add_node(node, {})
|
||||
self._ungroup_node = node
|
||||
return node
|
||||
|
||||
def add_asset(self, asset, system_users):
|
||||
@timeit
|
||||
def add_assets_without_system_users(self, assets):
|
||||
for asset in assets:
|
||||
self.add_asset(asset, {})
|
||||
|
||||
@timeit
|
||||
def add_assets(self, assets):
|
||||
for asset, system_users in assets.items():
|
||||
self.add_asset(asset, system_users)
|
||||
|
||||
@timeit
|
||||
def add_asset(self, asset, system_users=None):
|
||||
nodes = asset.nodes.all()
|
||||
for node in nodes:
|
||||
if node in self.nodes:
|
||||
self.nodes[node][asset].update(system_users)
|
||||
else:
|
||||
self.nodes[self.ungrouped_node][asset].update(system_users)
|
||||
nodes = self.node_util.get_nodes_by_queryset(nodes)
|
||||
if not system_users:
|
||||
system_users = defaultdict(int)
|
||||
else:
|
||||
system_users = {k: v for k, v in system_users.items()}
|
||||
_system_users = self.assets[asset]
|
||||
for system_user, action in _system_users.items():
|
||||
system_users[system_user] |= action
|
||||
|
||||
def get_nodes(self):
|
||||
for node in self.nodes:
|
||||
assets = set(self.nodes.get(node).keys())
|
||||
for n in self.nodes.keys():
|
||||
if n.key.startswith(node.key + ':'):
|
||||
assets.update(set(self.nodes[n].keys()))
|
||||
node.assets_amount = len(assets)
|
||||
return self.nodes
|
||||
# 获取父节点们
|
||||
parents = self.node_util.get_nodes_parents(nodes, with_self=True)
|
||||
for node in parents:
|
||||
_system_users = self.nodes[node]["system_users"]
|
||||
self.nodes[node]["assets_amount"] += 1
|
||||
for system_user, action in _system_users.items():
|
||||
system_users[system_user] |= action
|
||||
|
||||
def add_node(self, node):
|
||||
self.nodes[node] = defaultdict(set)
|
||||
# 过滤系统用户的协议
|
||||
system_users = {s: v for s, v in system_users.items() if asset.has_protocol(s.protocol)}
|
||||
self.assets[asset] = system_users
|
||||
|
||||
in_nodes = set(self.nodes.keys()) & set(nodes)
|
||||
if not in_nodes:
|
||||
self.nodes[self.ungrouped_node]["assets_amount"] += 1
|
||||
self.nodes[self.ungrouped_node]["assets"].add(system_users)
|
||||
return
|
||||
|
||||
for node in in_nodes:
|
||||
self.nodes[node]["assets"].add(asset)
|
||||
|
||||
def add_node(self, node, system_users=None):
|
||||
if not system_users:
|
||||
system_users = defaultdict(int)
|
||||
self.nodes[node]["system_users"] = system_users
|
||||
|
||||
# 添加树节点
|
||||
@timeit
|
||||
def add_nodes(self, nodes):
|
||||
need_nodes = self.node_util.get_family(nodes, with_children=True)
|
||||
for node in need_nodes:
|
||||
self.add_node(node)
|
||||
_nodes = nodes.keys()
|
||||
family = self.node_util.get_family(_nodes, with_children=True)
|
||||
for node in family:
|
||||
self.add_node(node, nodes.get(node, {}))
|
||||
|
||||
def get_assets(self):
|
||||
return dict(self.assets)
|
||||
|
||||
@timeit
|
||||
def get_nodes_with_assets(self):
|
||||
if self._nodes_with_assets:
|
||||
return self._nodes_with_assets
|
||||
nodes = {}
|
||||
for node, values in self.nodes.items():
|
||||
node._assets_amount = values["assets_amount"]
|
||||
nodes[node] = {asset: self.assets.get(asset, {}) for asset in values["assets"]}
|
||||
self._nodes_with_assets = nodes
|
||||
return dict(nodes)
|
||||
|
||||
|
||||
def get_user_permissions(user, include_group=True):
|
||||
|
@ -131,17 +215,6 @@ def get_system_user_permissions(system_user):
|
|||
)
|
||||
|
||||
|
||||
def timeit(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.debug("Start call: {}".format(func.__name__))
|
||||
now = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
using = time.time() - now
|
||||
logger.debug("Call {} end, using: {:.2}".format(func.__name__, using))
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
||||
class AssetPermissionCacheMixin:
|
||||
CACHE_KEY_PREFIX = '_ASSET_PERM_CACHE_'
|
||||
CACHE_META_KEY_PREFIX = '_ASSET_PERM_META_KEY_'
|
||||
|
@ -216,6 +289,16 @@ class AssetPermissionCacheMixin:
|
|||
cached = cache.get(self.system_key)
|
||||
return cached
|
||||
|
||||
def get_assets(self):
|
||||
if self._is_not_using_cache():
|
||||
return self.get_assets_from_cache()
|
||||
elif self._is_refresh_cache():
|
||||
self.expire_cache()
|
||||
return self.get_assets_from_cache()
|
||||
else:
|
||||
self.expire_cache()
|
||||
return self.get_assets_without_cache()
|
||||
|
||||
def get_system_users(self):
|
||||
if self._is_using_cache():
|
||||
return self.get_system_user_from_cache()
|
||||
|
@ -282,57 +365,6 @@ class AssetPermissionCacheMixin:
|
|||
cache.delete_pattern(key)
|
||||
|
||||
|
||||
class FlatPermissionQueryset(set):
|
||||
def add_many(self, assets_or_nodes, system_users, action, rtp="asset"):
|
||||
print("Add many: {}-{}-{}".format(len(assets_or_nodes), len(system_users), action))
|
||||
if not any([assets_or_nodes, system_users, action]):
|
||||
return
|
||||
|
||||
iterable = itertools.product(assets_or_nodes, system_users, [action])
|
||||
for source, sysuser, action in iterable:
|
||||
permission = FlatPermission(source, sysuser, action, rtp=rtp)
|
||||
print("ADDDDDDDDDDDDDDDd")
|
||||
self.add(permission)
|
||||
|
||||
def group_by_resource(self):
|
||||
resources = defaultdict(lambda: defaultdict(int))
|
||||
for i in self:
|
||||
resources[i.resource][i.system_user] |= i.action
|
||||
return resources
|
||||
|
||||
|
||||
class FlatPermission:
|
||||
def __init__(self, assets_or_node, system_user, action, rtp="asset"):
|
||||
self.id = "{}_{}_{}".format(assets_or_node.id, system_user.id, action)
|
||||
self.resource = assets_or_node
|
||||
self.resource_type = rtp
|
||||
self.system_user = system_user
|
||||
self.action = action
|
||||
|
||||
def __eq__(self, other):
|
||||
if self.id == other.id:
|
||||
return True
|
||||
# 资产不同
|
||||
if self.resource_type == "asset" and self.id != other.id:
|
||||
return False
|
||||
# 不是子节点
|
||||
elif self.resource_type == "node" and not other.resource.key.startswith(self.resource.key):
|
||||
return False
|
||||
# 系统用户优先级大于后者,则相同
|
||||
if self.system_user.priority > self.system_user.priority:
|
||||
return True
|
||||
# 如果系统用户不同,则不同
|
||||
elif self.system_user != other.system_user:
|
||||
return False
|
||||
# 如果action为与后的结果则相同
|
||||
if self.action == self.action | other.action:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.id)
|
||||
|
||||
|
||||
class AssetPermissionUtil(AssetPermissionCacheMixin):
|
||||
get_permissions_map = {
|
||||
"User": get_user_permissions,
|
||||
|
@ -353,6 +385,7 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
|
|||
self.tree = GenerateTree()
|
||||
self.change_org_if_need()
|
||||
self.nodes = None
|
||||
self._nodes = None
|
||||
|
||||
@staticmethod
|
||||
def change_org_if_need():
|
||||
|
@ -380,29 +413,32 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
|
|||
返回用户/组授权规则直接关联的节点
|
||||
:return: {node1: {system_user1: {'actions': set()},}}
|
||||
"""
|
||||
queryset = FlatPermissionQueryset()
|
||||
nodes = defaultdict(lambda: defaultdict(int))
|
||||
for perm in self.permissions:
|
||||
actions = perm.action
|
||||
actions = [perm.actions]
|
||||
system_users = perm.system_users.all()
|
||||
nodes = perm.nodes.all()
|
||||
queryset.add_many(nodes, system_users, actions, rtp="nodes")
|
||||
print(queryset)
|
||||
return queryset.group_by_resource()
|
||||
_nodes = perm.nodes.all()
|
||||
for node, system_user, action in itertools.product(_nodes, system_users, actions):
|
||||
nodes[node][system_user] |= action
|
||||
self.tree.add_nodes(nodes)
|
||||
return nodes
|
||||
|
||||
@timeit
|
||||
def get_assets_direct(self):
|
||||
"""
|
||||
返回用户授权规则直接关联的资产
|
||||
:return: {asset1: {system_user1: {'actions': set()},}}
|
||||
:return: {asset1: {system_user1: 1,}}
|
||||
"""
|
||||
queryset = FlatPermissionQueryset()
|
||||
assets = defaultdict(lambda: defaultdict(int))
|
||||
for perm in self.permissions:
|
||||
action = perm.action
|
||||
assets = perm.assets.all()
|
||||
actions = [perm.actions]
|
||||
_assets = perm.assets.all().prefetch_related('nodes', 'protocols')
|
||||
system_users = perm.system_users.all()
|
||||
queryset.add_many(assets, system_users, action, rtp="assets")
|
||||
print(queryset)
|
||||
return queryset.group_by_resource()
|
||||
iterable = itertools.product(_assets, system_users, actions)
|
||||
for asset, system_user, action in iterable:
|
||||
assets[asset][system_user] |= action
|
||||
self.tree.add_assets(assets)
|
||||
return assets
|
||||
|
||||
@timeit
|
||||
def get_assets_without_cache(self):
|
||||
|
@ -411,24 +447,34 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
|
|||
"""
|
||||
if self._assets:
|
||||
return self._assets
|
||||
assets = self.get_assets_direct()
|
||||
nodes = self.get_nodes_direct()
|
||||
print("++++++++++++++++++++++")
|
||||
print(assets)
|
||||
print("---------------------")
|
||||
print(nodes)
|
||||
pattern = set()
|
||||
for node in nodes:
|
||||
pattern.add(r'^{0}$|^{0}:'.format(node.key))
|
||||
pattern = '|'.join(list(pattern))
|
||||
now = time.time()
|
||||
print("Get node assets start")
|
||||
if pattern:
|
||||
assets = Asset.objects.filter(nodes__key__regex=pattern)\
|
||||
.prefetch_related('nodes', "protocols").only('id', 'hostname', 'ip').distinct()
|
||||
else:
|
||||
assets = []
|
||||
assets = list(assets)
|
||||
print("Get node assets end, using: {}".format(time.time() - now))
|
||||
self.tree.add_assets_without_system_users(assets)
|
||||
assets = self.tree.get_assets()
|
||||
self._assets = assets
|
||||
return assets
|
||||
|
||||
@timeit
|
||||
def get_nodes_with_assets_without_cache(self):
|
||||
"""
|
||||
返回节点并且包含资产
|
||||
{"node": {"assets": set("system_user")}}
|
||||
{"node": {"asset": {"system_user": 1})}}
|
||||
:return:
|
||||
"""
|
||||
assets = self.get_assets_without_cache()
|
||||
for asset, system_users in assets.items():
|
||||
self.tree.add_asset(asset, system_users)
|
||||
return self.tree.get_nodes()
|
||||
self.get_assets_without_cache()
|
||||
return self.tree.get_nodes_with_assets()
|
||||
|
||||
def get_system_user_without_cache(self):
|
||||
system_users = set()
|
||||
|
@ -460,9 +506,7 @@ def sort_assets(assets, order_by='hostname', reverse=False):
|
|||
|
||||
|
||||
def parse_node_to_tree_node(node):
|
||||
from .. import serializers
|
||||
name = '{} ({})'.format(node.value, node.assets_amount)
|
||||
node_serializer = serializers.GrantedNodeSerializer(node)
|
||||
data = {
|
||||
'id': node.key,
|
||||
'name': name,
|
||||
|
@ -471,7 +515,11 @@ def parse_node_to_tree_node(node):
|
|||
'isParent': True,
|
||||
'open': node.is_root(),
|
||||
'meta': {
|
||||
'node': node_serializer.data,
|
||||
'node': {
|
||||
"id": node.id,
|
||||
"key": node.key,
|
||||
"value": node.value,
|
||||
},
|
||||
'type': 'node'
|
||||
}
|
||||
}
|
||||
|
@ -480,23 +528,21 @@ def parse_node_to_tree_node(node):
|
|||
|
||||
|
||||
def parse_asset_to_tree_node(node, asset, system_users):
|
||||
system_users_protocol_matched = [s for s in system_users if asset.has_protocol(s.protocol)]
|
||||
icon_skin = 'file'
|
||||
if asset.platform.lower() == 'windows':
|
||||
icon_skin = 'windows'
|
||||
elif asset.platform.lower() == 'linux':
|
||||
icon_skin = 'linux'
|
||||
system_users = []
|
||||
for system_user in system_users_protocol_matched:
|
||||
system_users.append({
|
||||
_system_users = []
|
||||
for system_user, action in system_users.items():
|
||||
_system_users.append({
|
||||
'id': system_user.id,
|
||||
'name': system_user.name,
|
||||
'username': system_user.username,
|
||||
'protocol': system_user.protocol,
|
||||
'priority': system_user.priority,
|
||||
'login_mode': system_user.login_mode,
|
||||
'actions': [action.name for action in system_user.actions],
|
||||
'comment': system_user.comment,
|
||||
'actions': [ActionFlag.value_to_choices(action)],
|
||||
})
|
||||
data = {
|
||||
'id': str(asset.id),
|
||||
|
@ -507,7 +553,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
|
|||
'open': False,
|
||||
'iconSkin': icon_skin,
|
||||
'meta': {
|
||||
'system_users': system_users,
|
||||
'system_users': _system_users,
|
||||
'type': 'asset',
|
||||
'asset': {
|
||||
'id': asset.id,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from django.test import TestCase
|
||||
|
||||
from assets.models import Node, SystemUser
|
||||
from .asset_permission import FlatPermission
|
||||
from ..models import ActionFlag
|
||||
|
||||
|
||||
class TestFlatPermissionEqual(TestCase):
|
||||
def setUp(self):
|
||||
node1 = Node(value="parent", key="1:1")
|
||||
node2 = Node(value="child", key="1:1:1")
|
||||
|
||||
system_user1 = SystemUser(username="name1", name="name1", priority=20)
|
||||
system_user2 = SystemUser(username="name2", name="name2", priority=10)
|
||||
|
||||
action1 = ActionFlag.ALL
|
||||
action2 = ActionFlag.CONNECT
|
||||
action3 = ActionFlag.UPDOWNLOAD
|
||||
|
||||
perm1 = FlatPermission(node1, system_user1, action1)
|
||||
perm2 = FlatPermission(node2, system_user1, action1)
|
||||
perm3 = FlatPermission(node2, system_user2, action1)
|
||||
|
||||
self.groups = (
|
||||
(perm1, perm2, True),
|
||||
(perm1, perm3, True),
|
||||
)
|
||||
|
||||
def test_equal(self):
|
||||
for k, k2, wanted in self.groups:
|
||||
if (k == k2) != wanted:
|
||||
print("Not equal {} {}", k, k2)
|
||||
|
||||
|
Loading…
Reference in New Issue