jumpserver/apps/perms/api/asset/user_group_permission.py

193 lines
6.7 KiB
Python
Raw Normal View History

2019-03-04 12:45:57 +00:00
# -*- coding: utf-8 -*-
#
from itertools import chain
2019-03-04 12:45:57 +00:00
from django.db.models import Q
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
2019-03-04 12:45:57 +00:00
from common.permissions import IsOrgAdminOrAppUser
from common.utils import lazyproperty
from perms.models import AssetPermission
from assets.models import Asset, Node
from perms.api.asset import user_permission as uapi
from perms import serializers
from perms.utils.asset.permission import get_asset_system_user_ids_with_actions_by_group
from assets.api.mixin import SerializeToTreeNodeMixin
from users.models import UserGroup
2019-03-04 12:45:57 +00:00
__all__ = [
'UserGroupGrantedAssetsApi', 'UserGroupGrantedNodesApi',
'UserGroupGrantedNodeAssetsApi',
'UserGroupGrantedNodeChildrenAsTreeApi',
Dev beta (#3048) * [Update] 统一url地址 * [Update] 修改api * [Update] 使用规范的签名 * [Update] 修改url * [Update] 修改swagger * [Update] 添加serializer class避免报错 * [Update] 修改token * [Update] 支持api key * [Update] 支持生成api key * [Update] 修改api重定向 * [Update] 修改翻译 * [Update] 添加说明文档 * [Update] 修复浏览器关闭后session不失效的问题 * [Update] 修改一些内容 * [Update] 修改 jms脚本 * [Update] 修改重定向 * [Update] 修改搜索trim * [Update] 修改搜索trim * [Update] 添加sys log * [Bugfix] 修改登陆错误 * [Update] 优化User操作private_token的接口 (#3091) * [Update] 优化User操作private_token的接口 * [Update] 优化User操作private_token的接口 2 * [Bugfix] 解决授权了一个节点,当移动节点后,被移动的节点下的资产会放到未分组节点下的问题 * [Update] 升级jquery * [Update] 默认使用page * [Update] 修改使用Orgmodel view set * [Update] 支持 nv的硬盘 https://github.com/jumpserver/jumpserver/issues/1804 * [UPdate] 解决命令执行宽度问题 * [Update] 优化节点 * [Update] 修改nodes过多时创建比较麻烦 * [Update] 修改导入 * [Update] 节点获取更新 * [Update] 修改nodes * [Update] nodes显示full value * [Update] 统一使用nodes select2 函数 * [Update] 修改磁盘大小小数 * [Update] 修改 Node service * [Update] 优化授权节点 * [Update] 修改 node permission * [Update] 修改asset permission * [Stash] * [Update] 修改node assets api * [Update] 修改tree service,支持资产数量 * [Update] 修改暂时完成 * [Update] 修改一些bug
2019-08-21 12:27:21 +00:00
'UserGroupGrantedAssetSystemUsersApi',
2019-03-04 12:45:57 +00:00
]
class UserGroupMixin:
@lazyproperty
def group(self):
group_id = self.kwargs.get('pk')
return UserGroup.objects.get(id=group_id)
class UserGroupGrantedAssetsApi(ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
filterset_fields = ['hostname', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment']
def get_queryset(self):
user_group_id = self.kwargs.get('pk', '')
asset_perm_ids = list(AssetPermission.objects.valid().filter(
user_groups__id=user_group_id
).distinct().values_list('id', flat=True))
granted_node_keys = Node.objects.filter(
granted_by_permissions__id__in=asset_perm_ids,
).distinct().values_list('key', flat=True)
granted_q = Q()
for _key in granted_node_keys:
granted_q |= Q(nodes__key__startswith=f'{_key}:')
granted_q |= Q(nodes__key=_key)
granted_q |= Q(granted_by_permissions__id__in=asset_perm_ids)
assets = Asset.objects.filter(
granted_q
).distinct().only(
*self.only_fields
)
return assets
class UserGroupGrantedNodeAssetsApi(ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
filterset_fields = ['hostname', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment']
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return Asset.objects.none()
user_group_id = self.kwargs.get('pk', '')
node_id = self.kwargs.get("node_id")
node = Node.objects.get(id=node_id)
granted = AssetPermission.objects.filter(
user_groups__id=user_group_id,
nodes__id=node_id
).valid().exists()
if granted:
assets = Asset.objects.filter(
Q(nodes__key__startswith=f'{node.key}:') |
Q(nodes__key=node.key)
)
return assets
else:
asset_perm_ids = list(AssetPermission.objects.valid().filter(
user_groups__id=user_group_id
).distinct().values_list('id', flat=True))
granted_node_keys = Node.objects.filter(
granted_by_permissions__id__in=asset_perm_ids,
key__startswith=f'{node.key}:'
).distinct().values_list('key', flat=True)
granted_node_q = Q()
for _key in granted_node_keys:
granted_node_q |= Q(nodes__key__startswith=f'{_key}:')
granted_node_q |= Q(nodes__key=_key)
granted_asset_q = (
Q(granted_by_permissions__id__in=asset_perm_ids) &
(
Q(nodes__key__startswith=f'{node.key}:') |
Q(nodes__key=node.key)
)
)
assets = Asset.objects.filter(
granted_node_q | granted_asset_q
).distinct()
return assets
class UserGroupGrantedNodesApi(ListAPIView):
serializer_class = serializers.NodeGrantedSerializer
permission_classes = (IsOrgAdminOrAppUser,)
def get_queryset(self):
user_group_id = self.kwargs.get('pk', '')
nodes = Node.objects.filter(
Q(granted_by_permissions__user_groups__id=user_group_id) |
Q(assets__granted_by_permissions__user_groups__id=user_group_id)
)
return nodes
class UserGroupGrantedNodeChildrenAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
def get_children_nodes(self, parent_key):
return Node.objects.filter(parent_key=parent_key)
def add_children_key(self, node_key, key, key_set):
if key.startswith(f'{node_key}:'):
try:
end = key.index(':', len(node_key) + 1)
key_set.add(key[:end])
except ValueError:
key_set.add(key)
def get_nodes(self):
group_id = self.kwargs.get('pk')
node_key = self.request.query_params.get('key', None)
asset_perm_ids = list(AssetPermission.objects.valid().filter(
user_groups__id=group_id
).distinct().values_list('id', flat=True))
granted_keys = Node.objects.filter(
granted_by_permissions__id__in=asset_perm_ids
).values_list('key', flat=True)
asset_granted_keys = Node.objects.filter(
assets__granted_by_permissions__id__in=asset_perm_ids
).values_list('key', flat=True)
if node_key is None:
root_keys = set()
for _key in chain(granted_keys, asset_granted_keys):
root_keys.add(_key.split(':', 1)[0])
return Node.objects.filter(key__in=root_keys)
else:
children_keys = set()
for _key in granted_keys:
# 判断当前节点是否是授权节点
if node_key == _key:
return self.get_children_nodes(node_key)
# 判断当前节点有没有授权的父节点
if node_key.startswith(f'{_key}:'):
return self.get_children_nodes(node_key)
self.add_children_key(node_key, _key, children_keys)
for _key in asset_granted_keys:
self.add_children_key(node_key, _key, children_keys)
return Node.objects.filter(key__in=children_keys)
def list(self, request, *args, **kwargs):
nodes = self.get_nodes()
nodes = self.serialize_nodes(nodes)
return Response(data=nodes)
class UserGroupGrantedAssetSystemUsersApi(UserGroupMixin, uapi.UserGrantedAssetSystemUsersForAdminApi):
def get_asset_system_user_ids_with_actions(self, asset):
return get_asset_system_user_ids_with_actions_by_group(self.group, asset)