jumpserver/apps/perms/utils.py

161 lines
4.8 KiB
Python
Raw Normal View History

# coding: utf-8
2016-09-16 01:38:07 +00:00
from __future__ import absolute_import, unicode_literals
2018-04-07 16:16:37 +00:00
from collections import defaultdict
2018-05-31 11:47:57 +00:00
from django.db.models import Q
2016-09-16 01:38:07 +00:00
2018-06-01 07:34:08 +00:00
from common.utils import get_logger
2018-04-07 16:16:37 +00:00
from .models import AssetPermission
2018-06-01 07:34:08 +00:00
from .hands import Node
2017-03-09 06:55:33 +00:00
logger = get_logger(__file__)
2016-09-16 01:38:07 +00:00
class Tree:
def __init__(self):
self.__all_nodes = list(Node.objects.all().prefetch_related('assets'))
self.__node_asset_map = defaultdict(set)
self.nodes = defaultdict(dict)
self.root = Node.root()
self.init_node_asset_map()
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):
nodes = self.__node_asset_map.get(str(asset.id), [])
self.add_nodes(nodes)
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):
for node in nodes:
self.add_node(node)
2018-06-01 07:34:08 +00:00
def get_user_permissions(user, include_group=True):
if include_group:
groups = user.groups.all()
arg = Q(users=user) | Q(user_groups__in=groups)
2018-06-01 07:34:08 +00:00
else:
arg = Q(users=user)
return AssetPermission.objects.all().valid().filter(arg)
2018-05-25 09:28:53 +00:00
2018-06-01 07:34:08 +00:00
def get_user_group_permissions(user_group):
return AssetPermission.objects.all().valid().filter(
user_groups=user_group
)
2018-05-25 09:28:53 +00:00
2018-06-01 07:34:08 +00:00
def get_asset_permissions(asset, include_node=True):
if include_node:
nodes = asset.get_all_nodes(flat=True)
arg = Q(assets=asset) | Q(nodes__in=nodes)
2018-06-01 07:34:08 +00:00
else:
arg = Q(assets=asset)
return AssetPermission.objects.all().valid().filter(arg)
2018-05-25 09:28:53 +00:00
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
def get_node_permissions(node):
return AssetPermission.objects.all().valid().filter(nodes=node)
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
def get_system_user_permissions(system_user):
return AssetPermission.objects.valid().all().filter(
system_users=system_user
)
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
class AssetPermissionUtil:
get_permissions_map = {
"User": get_user_permissions,
"UserGroup": get_user_group_permissions,
"Asset": get_asset_permissions,
"Node": get_node_permissions,
"SystemUser": get_node_permissions,
}
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
def __init__(self, obj):
self.object = obj
self._permissions = None
self._assets = None
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
@property
def permissions(self):
if self._permissions:
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
2018-04-07 16:16:37 +00:00
2018-06-01 07:34:08 +00:00
def get_nodes_direct(self):
2018-04-08 12:02:40 +00:00
"""
2018-06-01 07:34:08 +00:00
返回用户/组授权规则直接关联的节点
:return: {node1: set(system_user1,)}
2018-04-08 12:02:40 +00:00
"""
2018-04-07 16:16:37 +00:00
nodes = defaultdict(set)
2018-06-01 07:34:08 +00:00
permissions = self.permissions.prefetch_related('nodes', 'system_users')
2018-04-07 16:16:37 +00:00
for perm in permissions:
2018-06-01 07:34:08 +00:00
for node in perm.nodes.all():
nodes[node].update(perm.system_users.all())
2018-05-23 07:15:27 +00:00
return nodes
2018-06-01 07:34:08 +00:00
def get_assets_direct(self):
2018-04-07 16:16:37 +00:00
"""
2018-06-01 07:34:08 +00:00
返回用户授权规则直接关联的资产
:return: {asset1: set(system_user1,)}
2018-04-07 16:16:37 +00:00
"""
2018-06-01 07:34:08 +00:00
assets = defaultdict(set)
permissions = self.permissions.prefetch_related('assets', 'system_users')
2018-04-07 16:16:37 +00:00
for perm in permissions:
2018-06-01 07:34:08 +00:00
for asset in perm.assets.all().valid().prefetch_related('nodes'):
assets[asset].update(perm.system_users.all())
2018-04-07 16:16:37 +00:00
return assets
2018-06-01 07:34:08 +00:00
def get_assets(self):
if self._assets:
return self._assets
2018-06-01 07:34:08 +00:00
assets = self.get_assets_direct()
nodes = self.get_nodes_direct()
for node, system_users in nodes.items():
_assets = node.get_all_assets().valid().prefetch_related('nodes')
for asset in _assets:
if isinstance(asset, Node):
print(_assets)
assets[asset].update(system_users)
self._assets = assets
return self._assets
2018-02-07 15:25:15 +00:00
2018-06-01 07:34:08 +00:00
def get_nodes_with_assets(self):
2018-06-01 08:22:52 +00:00
"""
返回节点并且包含资产
{"node": {"assets": set("system_user")}}
:return:
"""
2018-06-01 07:34:08 +00:00
assets = self.get_assets()
tree = Tree()
2018-06-01 07:34:08 +00:00
for asset, system_users in assets.items():
tree.add_asset(asset, system_users)
return tree.nodes
2018-02-07 15:25:15 +00:00