mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-10-21 15:58:52 +00:00
1.5.7 Merge to dev (#3766)
* [Update] 暂存,优化解决不了问题 * [Update] 待续(小白) * [Update] 修改asset user * [Update] 计划再次更改 * [Update] 修改asset user * [Update] 暂存与喜爱 * [Update] Add id in * [Update] 阶段性完成ops task该做 * [Update] 修改asset user api * [Update] 修改asset user 任务,查看认证等 * [Update] 基本完成asset user改造 * [Update] dynamic user only allow 1 * [Update] 修改asset user task * [Update] 修改node admin user task api * [Update] remove file header license * [Update] 添加sftp root * [Update] 暂存 * [Update] 暂存 * [Update] 修改翻译 * [Update] 修改系统用户改为同名后,用户名改为空 * [Update] 基本完成CAS调研 * [Update] 支持cas server * [Update] 支持cas server * [Update] 添加requirements * [Update] 为方便调试添加mysql ipython到包中 * [Update] 添加huaweiyun翻译 * [Update] 增加下载session 录像 * [Update] 只有第一次通知replay离线的使用方法 * [Update] 暂存一下 * [Bugfix] 获取系统用户信息报错 * [Bugfix] 修改system user info * [Update] 改成清理10天git status * [Update] 修改celery日志保留时间 * [Update]修复部分pip包依赖的版本不兼容问题 (#3672) * [Update] 修复用户更新页面会清空用户public_key的问题 * Fix broken dependencies Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> * [Update] 修改获取系统用户auth info * [Update] Remove log * [Bugfix] 修复sftp home设置的bug * [Update] 授权的系统用户添加sftp root * [Update] 修改系统用户关联的用户 * [Update] 修改placeholder * [Update] 优化获取授权的系统用户 * [Update] 修改tasks * [Update] tree service update * [Update] 暂存 * [Update] 基本完成用户授权树和资产树改造 * [Update] Dashbaord perf * [update] Add huawei cloud sdk requirements * [Updte] 优化dashboard页面 * [Update] system user auth info 添加id * [Update] 修改系统用户serializer * [Update] 优化api * [Update] LDAP Test Util (#3720) * [Update] LDAPTestUtil 1 * [Update] LDAPTestUtil 2 * [Update] LDAPTestUtil 3 * [Update] LDAPTestUtil 4 * [Update] LDAPTestUtil 5 * [Update] LDAPTestUtil 6 * [Update] LDAPTestUtil 7 * [Update] session 已添加is success,并且添加display serializer * [Bugfix] 修复无法删除空节点的bug * [Update] 命令记录分组织显示 * [Update] Session is_success 添加迁移文件 * [Update] 批量命令添加org_id * [Update] 修复一些文案,修改不绑定MFA,不能ssh登录 * [Update] 修改replay api, 返回session信息 * [Update] 解决无效es导致访问命令记录页面失败的问题 * [Update] 拆分profile view * [Update] 修改一个翻译 * [Update] 修改aysnc api框架 * [Update] 命令列表添加risk level * [Update] 完成录像打包下载 * [Update] 更改登陆otp页面 * [Update] 修改command 存储redis_level * [Update] 修改翻译 * [Update] 修改系统用户的用户列表字段 * [Update] 使用新logo和统一Jumpserver为JumpServer * [Update] 优化cloud task * [Update] 统一period task * [Update] 统一period form serializer字段 * [Update] 修改period task * [Update] 修改资产网关信息 * [Update] 用户授权资产树资产信息添加domain * [Update] 修改翻译 * [Update] 测试可连接性 * 1.5.7 bai (#3764) * [Update] 修复index页面Bug;修复测试资产用户可连接性问题; * [Update] 修改测试资产用户可连接 * [Bugfix] 修复backends问题 * [Update] 修改marksafe依赖版本 * [Update] 修改测试资产用户可连接性 * [Update] 修改检测服务器性能时获取percent值 * [Update] 更新依赖boto3=1.12.14 Co-authored-by: Yanzhe Lee <lee.yanzhe@yanzhe.org> Co-authored-by: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Co-authored-by: Bai <bugatti_it@163.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from common.permissions import IsValidUser, IsOrgAdminOrAppUser
|
||||
from common.utils import get_logger
|
||||
from orgs.utils import set_to_root_org, get_current_org, set_current_org, tmp_to_root_org
|
||||
from orgs.utils import set_to_root_org, set_current_org, get_current_org
|
||||
from ..hands import User, UserGroup
|
||||
|
||||
|
||||
@@ -22,25 +22,15 @@ class UserPermissionMixin:
|
||||
|
||||
def initial(self, *args, **kwargs):
|
||||
super().initial(*args, *kwargs)
|
||||
self.current_org = get_current_org()
|
||||
set_to_root_org()
|
||||
self.obj = self.get_obj()
|
||||
|
||||
# def dispatch(self, request, *args, **kwargs):
|
||||
# """不能这么做,校验权限时拿不到组织了"""
|
||||
# with tmp_to_root_org():
|
||||
# return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
# def get(self, request, *args, **kwargs):
|
||||
# """有的api重写了get方法"""
|
||||
# with tmp_to_root_org():
|
||||
# return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_obj(self):
|
||||
user_id = self.kwargs.get('pk', '')
|
||||
if user_id:
|
||||
user = get_object_or_404(User, id=user_id)
|
||||
else:
|
||||
self.current_org = get_current_org()
|
||||
set_to_root_org()
|
||||
user = self.request.user
|
||||
return user
|
||||
|
||||
|
@@ -11,7 +11,7 @@ from rest_framework.generics import (
|
||||
from common.permissions import IsOrgAdminOrAppUser, IsOrgAdmin
|
||||
from common.utils import get_logger
|
||||
from ...utils import (
|
||||
AssetPermissionUtilV2
|
||||
AssetPermissionUtil
|
||||
)
|
||||
from ...hands import User, Asset, SystemUser
|
||||
from ... import serializers
|
||||
@@ -51,8 +51,8 @@ class GetUserAssetPermissionActionsApi(UserAssetPermissionMixin,
|
||||
asset = get_object_or_404(Asset, id=asset_id)
|
||||
system_user = get_object_or_404(SystemUser, id=system_id)
|
||||
|
||||
system_users_actions = self.util.get_asset_system_users_with_actions(asset)
|
||||
actions = system_users_actions.get(system_user)
|
||||
system_users_actions = self.util.get_asset_system_users_id_with_actions(asset)
|
||||
actions = system_users_actions.get(system_user.id)
|
||||
return {"actions": actions}
|
||||
|
||||
|
||||
@@ -81,9 +81,8 @@ class ValidateUserAssetPermissionApi(UserAssetPermissionMixin, APIView):
|
||||
asset = get_object_or_404(Asset, id=asset_id)
|
||||
system_user = get_object_or_404(SystemUser, id=system_id)
|
||||
|
||||
system_users_actions = self.util.get_asset_system_users_with_actions(
|
||||
asset)
|
||||
actions = system_users_actions.get(system_user)
|
||||
system_users_actions = self.util.get_asset_system_users_id_with_actions(asset)
|
||||
actions = system_users_actions.get(system_user.id)
|
||||
if actions is None:
|
||||
return Response({'msg': False}, status=403)
|
||||
if action_name in Action.value_to_choices(actions):
|
||||
@@ -95,7 +94,7 @@ class RefreshAssetPermissionCacheApi(RetrieveAPIView):
|
||||
permission_classes = (IsOrgAdmin,)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
AssetPermissionUtilV2.expire_all_user_tree_cache()
|
||||
AssetPermissionUtil.expire_all_user_tree_cache()
|
||||
return Response({'msg': True}, status=200)
|
||||
|
||||
|
||||
@@ -107,11 +106,14 @@ class UserGrantedAssetSystemUsersApi(UserAssetPermissionMixin, ListAPIView):
|
||||
def get_queryset(self):
|
||||
asset_id = self.kwargs.get('asset_id')
|
||||
asset = get_object_or_404(Asset, id=asset_id)
|
||||
system_users_with_actions = self.util.get_asset_system_users_with_actions(asset)
|
||||
system_users = []
|
||||
for system_user, actions in system_users_with_actions.items():
|
||||
system_users_with_actions = self.util.get_asset_system_users_id_with_actions(asset)
|
||||
system_users_id = system_users_with_actions.keys()
|
||||
system_users = SystemUser.objects.filter(id__in=system_users_id)\
|
||||
.only(*self.serializer_class.Meta.only_fields) \
|
||||
.order_by('priority')
|
||||
system_users = list(system_users)
|
||||
for system_user in system_users:
|
||||
actions = system_users_with_actions.get(system_user.id, 0)
|
||||
system_user.actions = actions
|
||||
system_users.append(system_user)
|
||||
system_users.sort(key=lambda x: x.priority)
|
||||
return system_users
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
from common.utils import lazyproperty
|
||||
from common.tree import TreeNodeSerializer
|
||||
from ..mixin import UserPermissionMixin
|
||||
from ...utils import AssetPermissionUtilV2, ParserNode
|
||||
from ...utils import AssetPermissionUtil, ParserNode
|
||||
from ...hands import Node, Asset
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class UserAssetPermissionMixin(UserPermissionMixin):
|
||||
def util(self):
|
||||
cache_policy = self.get_cache_policy()
|
||||
system_user_id = self.request.query_params.get("system_user")
|
||||
util = AssetPermissionUtilV2(self.obj, cache_policy=cache_policy)
|
||||
util = AssetPermissionUtil(self.obj, cache_policy=cache_policy)
|
||||
if system_user_id:
|
||||
util.filter_permissions(system_users=system_user_id)
|
||||
return util
|
||||
|
@@ -2,9 +2,7 @@
|
||||
#
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.generics import (
|
||||
ListAPIView, get_object_or_404
|
||||
)
|
||||
from rest_framework.generics import ListAPIView
|
||||
|
||||
from common.permissions import IsOrgAdminOrAppUser
|
||||
from common.utils import get_logger, timeit
|
||||
@@ -16,8 +14,7 @@ from .mixin import UserAssetPermissionMixin, UserAssetTreeMixin
|
||||
logger = get_logger(__name__)
|
||||
|
||||
__all__ = [
|
||||
'UserGrantedAssetsApi',
|
||||
'UserGrantedAssetsAsTreeApi',
|
||||
'UserGrantedAssetsApi', 'UserGrantedAssetsAsTreeApi',
|
||||
'UserGrantedNodeAssetsApi',
|
||||
]
|
||||
|
||||
|
@@ -4,70 +4,10 @@
|
||||
from orgs.utils import set_to_root_org
|
||||
|
||||
__all__ = [
|
||||
'AssetsFilterMixin', 'ChangeOrgIfNeedMixin',
|
||||
'ChangeOrgIfNeedMixin',
|
||||
]
|
||||
|
||||
|
||||
class AssetsFilterMixin(object):
|
||||
"""
|
||||
对资产进行过滤(查询,排序)
|
||||
"""
|
||||
|
||||
def filter_queryset(self, queryset):
|
||||
queryset = self.search_assets(queryset)
|
||||
queryset = self.filter_labels(queryset)
|
||||
queryset = self.sort_assets(queryset)
|
||||
return queryset
|
||||
|
||||
def search_assets(self, queryset):
|
||||
from perms.utils import is_obj_attr_has
|
||||
value = self.request.query_params.get('search')
|
||||
if not value:
|
||||
return queryset
|
||||
queryset = [asset for asset in queryset if is_obj_attr_has(asset, value)]
|
||||
return queryset
|
||||
|
||||
def sort_assets(self, queryset):
|
||||
from perms.utils import sort_assets
|
||||
order_by = self.request.query_params.get('order')
|
||||
if not order_by:
|
||||
order_by = 'hostname'
|
||||
|
||||
if order_by.startswith('-'):
|
||||
order_by = order_by.lstrip('-')
|
||||
reverse = True
|
||||
else:
|
||||
reverse = False
|
||||
|
||||
queryset = sort_assets(queryset, order_by=order_by, reverse=reverse)
|
||||
return queryset
|
||||
|
||||
def filter_labels(self, queryset):
|
||||
from assets.models import Label
|
||||
query_keys = self.request.query_params.keys()
|
||||
all_label_keys = Label.objects.values_list('name', flat=True)
|
||||
valid_keys = set(all_label_keys) & set(query_keys)
|
||||
labels_query = {}
|
||||
for key in valid_keys:
|
||||
labels_query[key] = self.request.query_params.get(key)
|
||||
if not labels_query:
|
||||
return queryset
|
||||
|
||||
labels = set()
|
||||
for k, v in labels_query.items():
|
||||
label = Label.objects.filter(name=k, value=v).first()
|
||||
if not label:
|
||||
continue
|
||||
labels.add(label)
|
||||
|
||||
_queryset = []
|
||||
for asset in queryset:
|
||||
_labels = set(asset.labels.all()) & set(labels)
|
||||
if _labels and len(_labels) == len(set(labels)):
|
||||
_queryset.append(asset)
|
||||
return _queryset
|
||||
|
||||
|
||||
class ChangeOrgIfNeedMixin(object):
|
||||
|
||||
@staticmethod
|
||||
|
@@ -27,6 +27,7 @@ class AssetSystemUserSerializer(serializers.ModelSerializer):
|
||||
model = SystemUser
|
||||
only_fields = (
|
||||
'id', 'name', 'username', 'priority', 'protocol', 'login_mode',
|
||||
'sftp_root', 'username_same_with_user',
|
||||
)
|
||||
fields = list(only_fields) + ["actions"]
|
||||
read_only_fields = fields
|
||||
|
@@ -5,8 +5,8 @@ from django.dispatch import receiver
|
||||
|
||||
from common.utils import get_logger
|
||||
from common.decorator import on_transaction_commit
|
||||
from .models import AssetPermission
|
||||
from .utils.asset_permission import AssetPermissionUtilV2
|
||||
from .models import AssetPermission, RemoteAppPermission
|
||||
from .utils.asset_permission import AssetPermissionUtil
|
||||
|
||||
|
||||
logger = get_logger(__file__)
|
||||
@@ -16,45 +16,64 @@ logger = get_logger(__file__)
|
||||
@on_transaction_commit
|
||||
def on_permission_change(sender, action='', **kwargs):
|
||||
logger.debug('Asset permission changed, refresh user tree cache')
|
||||
AssetPermissionUtilV2.expire_all_user_tree_cache()
|
||||
AssetPermissionUtil.expire_all_user_tree_cache()
|
||||
|
||||
# Todo: 检查授权规则到期,从而修改授权规则
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=AssetPermission.nodes.through)
|
||||
def on_permission_nodes_changed(sender, instance=None, action='', **kwargs):
|
||||
if action != 'post_add':
|
||||
def on_permission_nodes_changed(sender, instance=None, action='', reverse=None, **kwargs):
|
||||
if action != 'post_add' and reverse:
|
||||
return
|
||||
if isinstance(instance, AssetPermission):
|
||||
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))
|
||||
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, action='', **kwargs):
|
||||
if action != 'post_add':
|
||||
def on_permission_assets_changed(sender, instance=None, action='', reverse=None, **kwargs):
|
||||
if action != 'post_add' and reverse:
|
||||
return
|
||||
if isinstance(instance, AssetPermission):
|
||||
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))
|
||||
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, action='', **kwargs):
|
||||
if action != 'post_add':
|
||||
def on_asset_permission_system_users_changed(sender, instance=None, action='',
|
||||
reverse=False, **kwargs):
|
||||
if action != 'post_add' and reverse:
|
||||
return
|
||||
if isinstance(instance, AssetPermission):
|
||||
system_users = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||
logger.debug("Asset permission system_users change signal received")
|
||||
assets = instance.assets.all().values_list('id', flat=True)
|
||||
nodes = instance.nodes.all().values_list('id', flat=True)
|
||||
for system_user in system_users:
|
||||
system_user.nodes.add(*tuple(nodes))
|
||||
system_user.assets.add(*tuple(assets))
|
||||
logger.debug("Asset permission system_users change signal received")
|
||||
system_users = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||
assets = instance.assets.all().values_list('id', flat=True)
|
||||
nodes = instance.nodes.all().values_list('id', flat=True)
|
||||
users = instance.users.all().values_list('id', flat=True)
|
||||
groups = instance.user_groups.all().values_list('id', flat=True)
|
||||
for system_user in system_users:
|
||||
system_user.nodes.add(*tuple(nodes))
|
||||
system_user.assets.add(*tuple(assets))
|
||||
if system_user.username_same_with_user:
|
||||
system_user.groups.add(*tuple(groups))
|
||||
system_user.users.add(*tuple(users))
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=RemoteAppPermission.system_users.through)
|
||||
def on_remote_app_permission_system_users_changed(sender, instance=None,
|
||||
action='', reverse=False, **kwargs):
|
||||
if action != 'post_add' or reverse:
|
||||
return
|
||||
system_users = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||
logger.debug("Remote app permission system_users change signal received")
|
||||
assets = instance.remote_apps.all().values_list('asset__id', flat=True)
|
||||
users = instance.users.all().values_list('id', flat=True)
|
||||
groups = instance.user_groups.all().values_list('id', flat=True)
|
||||
for system_user in system_users:
|
||||
system_user.assets.add(*tuple(assets))
|
||||
if system_user.username_same_with_user:
|
||||
system_user.groups.add(*tuple(groups))
|
||||
system_user.users.add(*tuple(users))
|
||||
|
@@ -193,7 +193,7 @@ $(document).ready(function(){
|
||||
{title: "{% trans 'Exclude' %}", value: "0"},
|
||||
]},
|
||||
];
|
||||
initTableFilterDropdown('#permission_list_table_filter input', filterMenu)
|
||||
initTableFilterDropdown('#permission_list_table_filter input', filterMenu, 15)
|
||||
})
|
||||
.on('click', '.btn-del', function () {
|
||||
var $this = $(this);
|
||||
|
@@ -25,7 +25,7 @@ user_permission_urlpatterns = [
|
||||
path('nodes/', api.UserGrantedNodesApi.as_view(), name='my-nodes'),
|
||||
|
||||
# Node children
|
||||
path('<uuid:pk>/nodes/children/', api.UserGrantedNodesApi.as_view(), name='user-nodes-children'),
|
||||
path('<uuid:pk>/nodes/children/', api.UserGrantedNodeChildrenApi.as_view(), name='user-nodes-children'),
|
||||
path('nodes/children/', api.UserGrantedNodesApi.as_view(), name='my-nodes-children'),
|
||||
|
||||
# Node as tree
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# coding: utf-8
|
||||
|
||||
import time
|
||||
import pickle
|
||||
from collections import defaultdict
|
||||
from functools import reduce
|
||||
@@ -8,7 +8,7 @@ from django.core.cache import cache
|
||||
from django.db.models import Q
|
||||
from django.conf import settings
|
||||
|
||||
from orgs.utils import set_to_root_org
|
||||
from orgs.utils import current_org
|
||||
from common.utils import get_logger, timeit, lazyproperty
|
||||
from common.tree import TreeNode
|
||||
from assets.utils import TreeService
|
||||
@@ -19,8 +19,7 @@ logger = get_logger(__file__)
|
||||
|
||||
|
||||
__all__ = [
|
||||
'is_obj_attr_has', 'sort_assets',
|
||||
'ParserNode', 'AssetPermissionUtilV2',
|
||||
'ParserNode', 'AssetPermissionUtil',
|
||||
]
|
||||
|
||||
|
||||
@@ -59,25 +58,48 @@ def get_system_user_permissions(system_user):
|
||||
|
||||
|
||||
class AssetPermissionUtilCacheMixin:
|
||||
user_tree_cache_key = 'USER_PERM_TREE_{}_{}'
|
||||
user_tree_cache_key = 'USER_PERM_TREE_{}_{}_{}'
|
||||
user_tree_cache_ttl = settings.ASSETS_PERM_CACHE_TIME
|
||||
user_tree_cache_enable = settings.ASSETS_PERM_CACHE_ENABLE
|
||||
user_tree_map = {}
|
||||
cache_policy = '0'
|
||||
obj_id = ''
|
||||
_filter_id = 'None'
|
||||
|
||||
@property
|
||||
def cache_key(self):
|
||||
return self.user_tree_cache_key.format(self.obj_id, self._filter_id)
|
||||
return self.get_cache_key()
|
||||
|
||||
def get_cache_key(self, org_id=None):
|
||||
if org_id is None:
|
||||
org_id = current_org.org_id()
|
||||
|
||||
key = self.user_tree_cache_key.format(
|
||||
org_id, self.obj_id, self._filter_id
|
||||
)
|
||||
return key
|
||||
|
||||
def expire_user_tree_cache(self):
|
||||
cache.delete(self.cache_key)
|
||||
|
||||
@classmethod
|
||||
def expire_all_user_tree_cache(cls):
|
||||
key = cls.user_tree_cache_key.format('*', '*')
|
||||
key = key.split('_')[:-1]
|
||||
key = '_'.join(key)
|
||||
expire_cache_key = "USER_TREE_EXPIRED_AT"
|
||||
latest_expired = cache.get(expire_cache_key, 0)
|
||||
now = time.time()
|
||||
if now - latest_expired < 60:
|
||||
return
|
||||
key = cls.user_tree_cache_key.format('*', '1', '1')
|
||||
key = key.replace('_1', '')
|
||||
cache.delete_pattern(key)
|
||||
cache.set(expire_cache_key, now)
|
||||
|
||||
@classmethod
|
||||
def expire_org_tree_cache(cls, org_id=None):
|
||||
if org_id is None:
|
||||
org_id = current_org.org_id()
|
||||
key = cls.user_tree_cache_key.format(org_id, '*', '1')
|
||||
key = key.replace('_1', '')
|
||||
cache.delete_pattern(key)
|
||||
|
||||
def set_user_tree_to_cache(self, user_tree):
|
||||
@@ -111,7 +133,7 @@ class AssetPermissionUtilCacheMixin:
|
||||
self.set_user_tree_to_cache(user_tree)
|
||||
|
||||
|
||||
class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
class AssetPermissionUtil(AssetPermissionUtilCacheMixin):
|
||||
get_permissions_map = {
|
||||
"User": get_user_permissions,
|
||||
"UserGroup": get_user_group_permissions,
|
||||
@@ -134,9 +156,12 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
self._user_tree = None
|
||||
self._user_tree_filter_id = 'None'
|
||||
|
||||
if not isinstance(obj, User):
|
||||
self.cache_policy = '0'
|
||||
|
||||
@staticmethod
|
||||
def change_org_if_need():
|
||||
set_to_root_org()
|
||||
pass
|
||||
|
||||
@lazyproperty
|
||||
def full_tree(self):
|
||||
@@ -157,9 +182,7 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
@timeit
|
||||
def filter_permissions(self, **filters):
|
||||
self.cache_policy = '0'
|
||||
# filters_json = json.dumps(filters, sort_keys=True)
|
||||
self._permissions = self.permissions.filter(**filters)
|
||||
# self._filter_id = md5(filters_json.encode()).hexdigest()
|
||||
|
||||
@lazyproperty
|
||||
def user_tree(self):
|
||||
@@ -253,6 +276,8 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
|
||||
# 获取单独授权资产,并没有在授权的节点上
|
||||
for key, assets in nodes_single_assets.items():
|
||||
if not self.full_tree.contains(key):
|
||||
continue
|
||||
node = self.full_tree.get_node(key, deep=True)
|
||||
parent_id = self.full_tree.parent(key).identifier
|
||||
parent = user_tree.get_node(parent_id)
|
||||
@@ -280,21 +305,6 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
if not ancestors:
|
||||
continue
|
||||
user_tree.safe_add_ancestors(child, ancestors)
|
||||
# parent_id = ancestors[0].identifier
|
||||
# user_tree.move_node(child.identifier, parent_id)
|
||||
|
||||
@staticmethod
|
||||
def add_empty_node_if_need(user_tree):
|
||||
"""
|
||||
添加空节点,如果根节点没有子节点的话
|
||||
"""
|
||||
if not user_tree.children(user_tree.root):
|
||||
node_key = Node.empty_key
|
||||
node_value = Node.empty_value
|
||||
user_tree.create_node(
|
||||
identifier=node_key, tag=node_value,
|
||||
parent=user_tree.root,
|
||||
)
|
||||
|
||||
def add_favorite_node_if_need(self, user_tree):
|
||||
if not isinstance(self.object, User):
|
||||
@@ -321,16 +331,10 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
|
||||
@timeit
|
||||
def get_user_tree(self):
|
||||
# 使用锁,保证多次获取tree的时候顺序执行,可以使用缓存
|
||||
user_tree = self.get_user_tree_from_local()
|
||||
if user_tree:
|
||||
return user_tree
|
||||
user_tree = self.get_user_tree_from_cache_if_need()
|
||||
if user_tree:
|
||||
self.set_user_tree_to_local(user_tree)
|
||||
return user_tree
|
||||
user_tree = TreeService()
|
||||
user_tree._invalid_assets = self.full_tree._invalid_assets
|
||||
full_tree_root = self.full_tree.root_node()
|
||||
user_tree.create_node(
|
||||
tag=full_tree_root.tag,
|
||||
@@ -340,13 +344,12 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
self.add_single_assets_node_to_user_tree(user_tree)
|
||||
self.parse_user_tree_to_full_tree(user_tree)
|
||||
self.add_favorite_node_if_need(user_tree)
|
||||
self.add_empty_node_if_need(user_tree)
|
||||
self.set_user_tree_to_cache_if_need(user_tree)
|
||||
self.set_user_tree_to_local(user_tree)
|
||||
return user_tree
|
||||
|
||||
# Todo: 是否可以获取多个资产的系统用户
|
||||
def get_asset_system_users_with_actions(self, asset):
|
||||
def get_asset_system_users_id_with_actions(self, asset):
|
||||
nodes = asset.get_nodes()
|
||||
nodes_keys_related = set()
|
||||
for node in nodes:
|
||||
@@ -367,35 +370,35 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
queryset = queryset.filter(args)
|
||||
else:
|
||||
queryset = queryset.none()
|
||||
queryset = queryset.distinct().prefetch_related('system_users')
|
||||
asset_protocols = asset.protocols_as_dict.keys()
|
||||
values = queryset.filter(system_users__protocol__in=asset_protocols).distinct()\
|
||||
.values_list('system_users', 'actions')
|
||||
system_users_actions = defaultdict(int)
|
||||
for perm in queryset:
|
||||
system_users = perm.system_users.all()
|
||||
if not system_users or not perm.actions:
|
||||
for system_user_id, actions in values:
|
||||
if None in (system_user_id, actions):
|
||||
continue
|
||||
for s in system_users:
|
||||
if not asset.has_protocol(s.protocol):
|
||||
continue
|
||||
system_users_actions[s] |= perm.actions
|
||||
for i, action in values:
|
||||
system_users_actions[i] |= actions
|
||||
return system_users_actions
|
||||
|
||||
def get_permissions_nodes_and_assets(self):
|
||||
from assets.models import Node
|
||||
permissions = self.permissions.values_list('assets', 'nodes__key').distinct()
|
||||
nodes_keys = set()
|
||||
assets_ids = set()
|
||||
for asset_id, node_key in permissions:
|
||||
if asset_id:
|
||||
assets_ids.add(asset_id)
|
||||
if node_key:
|
||||
nodes_keys.add(node_key)
|
||||
permissions = self.permissions
|
||||
nodes_keys = permissions.exclude(nodes__isnull=True)\
|
||||
.values_list('nodes__key', flat=True)
|
||||
assets_ids = permissions.exclude(assets__isnull=True)\
|
||||
.values_list('assets', flat=True)
|
||||
nodes_keys = set(nodes_keys)
|
||||
assets_ids = set(assets_ids)
|
||||
nodes_keys = Node.clean_children_keys(nodes_keys)
|
||||
return nodes_keys, assets_ids
|
||||
|
||||
@timeit
|
||||
def get_assets(self):
|
||||
nodes_keys, assets_ids = self.get_permissions_nodes_and_assets()
|
||||
queryset = Node.get_nodes_all_assets(nodes_keys, extra_assets_ids=assets_ids)
|
||||
queryset = Node.get_nodes_all_assets(
|
||||
nodes_keys, extra_assets_ids=assets_ids
|
||||
)
|
||||
return queryset.valid()
|
||||
|
||||
def get_nodes_assets(self, node, deep=False):
|
||||
@@ -414,30 +417,9 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
|
||||
return SystemUser.objects.filter(id__in=system_users_id)
|
||||
|
||||
|
||||
def is_obj_attr_has(obj, val, attrs=("hostname", "ip", "comment")):
|
||||
if not attrs:
|
||||
vals = [val for val in obj.__dict__.values() if isinstance(val, (str, int))]
|
||||
else:
|
||||
vals = [getattr(obj, attr) for attr in attrs if
|
||||
hasattr(obj, attr) and isinstance(hasattr(obj, attr), (str, int))]
|
||||
|
||||
for v in vals:
|
||||
if str(v).find(val) != -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def sort_assets(assets, order_by='hostname', reverse=False):
|
||||
if order_by == 'ip':
|
||||
assets = sorted(assets, key=lambda asset: [int(d) for d in asset.ip.split('.') if d.isdigit()], reverse=reverse)
|
||||
else:
|
||||
assets = sorted(assets, key=lambda asset: getattr(asset, order_by), reverse=reverse)
|
||||
return assets
|
||||
|
||||
|
||||
class ParserNode:
|
||||
nodes_only_fields = ("key", "value", "id")
|
||||
assets_only_fields = ("hostname", "id", "ip", "protocols", "org_id")
|
||||
assets_only_fields = ("hostname", "id", "ip", "protocols", "domain", "org_id")
|
||||
system_users_only_fields = (
|
||||
"id", "name", "username", "protocol", "priority", "login_mode",
|
||||
)
|
||||
@@ -490,6 +472,7 @@ class ParserNode:
|
||||
'ip': asset.ip,
|
||||
'protocols': asset.protocols_as_list,
|
||||
'platform': asset.platform_base,
|
||||
'domain': asset.domain_id,
|
||||
'org_name': asset.org_name,
|
||||
},
|
||||
}
|
||||
|
Reference in New Issue
Block a user