Unverified Commit 1457281b authored by 老广's avatar 老广 Committed by GitHub

Bugfix (#3232)

* [Update] 拆分user permission

* [Update] 修改 ops command

* [Update] 修改setting无法生效的问题

* [Update] 修复授权详情-授权资产或节点添加资产失败

* [Bugfix] 修复组织管理员运行命令时的问题

* [Update] 修复命令执行左侧树点击问题
parent 49317371
...@@ -92,7 +92,7 @@ function syncSelectedAssetsToModalTable(assetModalTable) { ...@@ -92,7 +92,7 @@ function syncSelectedAssetsToModalTable(assetModalTable) {
} }
// input assets有,table assets没选,则选中(click) // input assets有,table assets没选,则选中(click)
if (inputAssets !== null) { if (inputAssets) {
assetModalTable.selected = inputAssets; assetModalTable.selected = inputAssets;
$.each(inputAssets, function (index, assetId) { $.each(inputAssets, function (index, assetId) {
var dom = document.getElementById(assetId); var dom = document.getElementById(assetId);
......
...@@ -2,16 +2,6 @@ from __future__ import unicode_literals ...@@ -2,16 +2,6 @@ from __future__ import unicode_literals
import sys import sys
from django.apps import AppConfig from django.apps import AppConfig
from django.dispatch import receiver
from django.db.backends.signals import connection_created
@receiver(connection_created)
def on_db_connection_ready(sender, **kwargs):
from .signals import django_ready
if 'migrate' not in sys.argv:
django_ready.send(CommonConfig)
connection_created.disconnect(on_db_connection_ready)
class CommonConfig(AppConfig): class CommonConfig(AppConfig):
...@@ -19,3 +9,6 @@ class CommonConfig(AppConfig): ...@@ -19,3 +9,6 @@ class CommonConfig(AppConfig):
def ready(self): def ready(self):
from . import signals_handlers from . import signals_handlers
from .signals import django_ready
if 'migrate' not in sys.argv:
django_ready.send(CommonConfig)
...@@ -30,10 +30,10 @@ class CommandExecutionViewSet(RootOrgViewMixin, viewsets.ModelViewSet): ...@@ -30,10 +30,10 @@ class CommandExecutionViewSet(RootOrgViewMixin, viewsets.ModelViewSet):
util = AssetPermissionUtilV2(self.request.user) util = AssetPermissionUtilV2(self.request.user)
util.filter_permissions(system_users=system_user.id) util.filter_permissions(system_users=system_user.id)
permed_assets = util.get_assets().filter(id__in=[a.id for a in assets]) permed_assets = util.get_assets().filter(id__in=[a.id for a in assets])
unpermed_assets = set(assets) - set(permed_assets) invalid_assets = set(assets) - set(permed_assets)
if unpermed_assets: if invalid_assets:
msg = _("Not has host {} permission").format( msg = _("Not has host {} permission").format(
[str(a.id) for a in unpermed_assets] [str(a.id) for a in invalid_assets]
) )
raise ValidationError({"hosts": msg}) raise ValidationError({"hosts": msg})
......
...@@ -9,6 +9,7 @@ from common.permissions import ( ...@@ -9,6 +9,7 @@ from common.permissions import (
PermissionsMixin, IsOrgAdmin, IsValidUser, IsOrgAuditor PermissionsMixin, IsOrgAdmin, IsValidUser, IsOrgAuditor
) )
from common.mixins import DatetimeSearchMixin from common.mixins import DatetimeSearchMixin
from orgs.utils import tmp_to_root_org
from ..models import CommandExecution from ..models import CommandExecution
from ..forms import CommandExecutionForm from ..forms import CommandExecutionForm
...@@ -67,8 +68,9 @@ class CommandExecutionStartView(PermissionsMixin, TemplateView): ...@@ -67,8 +68,9 @@ class CommandExecutionStartView(PermissionsMixin, TemplateView):
def get_user_system_users(self): def get_user_system_users(self):
from perms.utils import AssetPermissionUtilV2 from perms.utils import AssetPermissionUtilV2
user = self.request.user user = self.request.user
util = AssetPermissionUtilV2(user) with tmp_to_root_org():
system_users = [s for s in util.get_system_users() if s.protocol == 'ssh'] util = AssetPermissionUtilV2(user)
system_users = [s for s in util.get_system_users() if s.protocol == 'ssh']
return system_users return system_users
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import uuid import uuid
from hashlib import md5
from django.core.cache import cache
from django.db.models import Q from django.db.models import Q
from django.conf import settings
from rest_framework.views import Response
from django.utils.decorators import method_decorator
from django.views.decorators.http import condition
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from django.utils.translation import ugettext as _
from assets.utils import LabelFilterMixin from assets.utils import LabelFilterMixin
from common.permissions import IsValidUser, IsOrgAdminOrAppUser, IsOrgAdmin from common.permissions import IsValidUser, IsOrgAdminOrAppUser
from common.utils import get_logger from common.utils import get_logger
from orgs.utils import set_to_root_org from orgs.utils import set_to_root_org
from ..hands import User, Asset, Node, SystemUser from ..hands import User, Asset, SystemUser
from .. import serializers from .. import serializers
from .. import const
logger = get_logger(__name__) logger = get_logger(__name__)
__all__ = [ __all__ = [
'UserPermissionCacheMixin', 'GrantAssetsMixin', 'NodesWithUngroupMixin',
'UserPermissionMixin', 'UserPermissionMixin',
] ]
...@@ -54,147 +45,6 @@ class UserPermissionMixin: ...@@ -54,147 +45,6 @@ class UserPermissionMixin:
return super().get_permissions() return super().get_permissions()
# def get_etag(request, *args, **kwargs):
# cache_policy = request.GET.get("cache_policy")
# if cache_policy != '1':
# return None
# if not UserPermissionCacheMixin.CACHE_ENABLE:
# return None
# view = request.parser_context.get("view")
# if not view:
# return None
# etag = view.get_meta_cache_id()
# return etag
class UserPermissionCacheMixin:
pass
# cache_policy = '0'
# RESP_CACHE_KEY = '_PERMISSION_RESPONSE_CACHE_V2_{}'
# CACHE_ENABLE = settings.ASSETS_PERM_CACHE_ENABLE
# CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME
# _object = None
#
# def get_object(self):
# return None
#
# # 内部使用可控制缓存
# def _get_object(self):
# if not self._object:
# self._object = self.get_object()
# return self._object
#
# def get_object_id(self):
# obj = self._get_object()
# if obj:
# return str(obj.id)
# return None
#
# def get_request_md5(self):
# path = self.request.path
# query = {k: v for k, v in self.request.GET.items()}
# query.pop("_", None)
# query = "&".join(["{}={}".format(k, v) for k, v in query.items()])
# full_path = "{}?{}".format(path, query)
# return md5(full_path.encode()).hexdigest()
#
# def get_meta_cache_id(self):
# obj = self._get_object()
# util = AssetPermissionUtil(obj, cache_policy=self.cache_policy)
# meta_cache_id = util.cache_meta.get('id')
# return meta_cache_id
#
# def get_response_cache_id(self):
# obj_id = self.get_object_id()
# request_md5 = self.get_request_md5()
# meta_cache_id = self.get_meta_cache_id()
# resp_cache_id = '{}_{}_{}'.format(obj_id, request_md5, meta_cache_id)
# return resp_cache_id
#
# def get_response_from_cache(self):
# # 没有数据缓冲
# meta_cache_id = self.get_meta_cache_id()
# if not meta_cache_id:
# logger.debug("Not get meta id: {}".format(meta_cache_id))
# return None
# # 从响应缓冲里获取响应
# key = self.get_response_key()
# data = cache.get(key)
# if not data:
# logger.debug("Not get response from cache: {}".format(key))
# return None
# logger.debug("Get user permission from cache: {}".format(self.get_object()))
# response = Response(data)
# return response
#
# def expire_response_cache(self):
# obj_id = self.get_object_id()
# expire_cache_id = '{}_{}'.format(obj_id, '*')
# key = self.RESP_CACHE_KEY.format(expire_cache_id)
# cache.delete_pattern(key)
#
# def get_response_key(self):
# resp_cache_id = self.get_response_cache_id()
# key = self.RESP_CACHE_KEY.format(resp_cache_id)
# return key
#
# def set_response_to_cache(self, response):
# key = self.get_response_key()
# cache.set(key, response.data, self.CACHE_TIME)
# logger.debug("Set response to cache: {}".format(key))
#
# @method_decorator(condition(etag_func=get_etag))
# def get(self, request, *args, **kwargs):
# if not self.CACHE_ENABLE:
# self.cache_policy = '0'
# else:
# self.cache_policy = request.GET.get('cache_policy', '0')
#
# obj = self._get_object()
# if obj is None:
# logger.debug("Not get response from cache: obj is none")
# return super().get(request, *args, **kwargs)
#
# if AssetPermissionUtil.is_not_using_cache(self.cache_policy):
# logger.debug("Not get resp from cache: {}".format(self.cache_policy))
# return super().get(request, *args, **kwargs)
# elif AssetPermissionUtil.is_refresh_cache(self.cache_policy):
# logger.debug("Not get resp from cache: {}".format(self.cache_policy))
# self.expire_response_cache()
#
# logger.debug("Try get response from cache")
# resp = self.get_response_from_cache()
# if not resp:
# resp = super().get(request, *args, **kwargs)
# self.set_response_to_cache(resp)
# return resp
class NodesWithUngroupMixin:
util = None
@staticmethod
def get_ungrouped_node(ungroup_key):
return Node(key=ungroup_key, id=const.UNGROUPED_NODE_ID,
value=_("ungrouped"))
@staticmethod
def get_empty_node():
return Node(key=const.EMPTY_NODE_KEY, id=const.EMPTY_NODE_ID,
value=_("empty"))
def add_ungrouped_nodes(self, node_map, node_keys):
ungroup_key = '1:-1'
for key in node_keys:
if key.endswith('-1'):
ungroup_key = key
break
ungroup_node = self.get_ungrouped_node(ungroup_key)
empty_node = self.get_empty_node()
node_map[ungroup_key] = ungroup_node
node_map[const.EMPTY_NODE_KEY] = empty_node
class GrantAssetsMixin(LabelFilterMixin): class GrantAssetsMixin(LabelFilterMixin):
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
......
# -*- coding: utf-8 -*-
#
from .common import *
from .user_permission_nodes import *
from .user_permission_assets import *
from .user_permission_nodes_with_assets import *
# -*- coding: utf-8 -*-
#
from ..mixin import UserPermissionMixin
from ...utils import AssetPermissionUtilV2, ParserNode
from ...hands import Node
from common.tree import TreeNodeSerializer
class UserAssetPermissionMixin(UserPermissionMixin):
util = None
tree = None
def initial(self, *args, **kwargs):
super().initial(*args, *kwargs)
cache_policy = self.request.query_params.get('cache_policy', '0')
system_user_id = self.request.query_params.get("system_user")
self.util = AssetPermissionUtilV2(self.obj, cache_policy=cache_policy)
if system_user_id:
self.util.filter_permissions(system_users=system_user_id)
self.tree = self.util.get_user_tree()
class UserNodeTreeMixin:
serializer_class = TreeNodeSerializer
nodes_only_fields = ParserNode.nodes_only_fields
def parse_nodes_to_queryset(self, nodes):
nodes = nodes.only(*self.nodes_only_fields)
_queryset = []
for node in nodes:
assets_amount = self.tree.assets_amount(node.key)
if assets_amount == 0 and node.key != Node.empty_key:
continue
node._assets_amount = assets_amount
data = ParserNode.parse_node_to_tree_node(node)
_queryset.append(data)
return _queryset
def get_serializer_queryset(self, queryset):
queryset = self.parse_nodes_to_queryset(queryset)
return queryset
def get_serializer(self, queryset, many=True, **kwargs):
queryset = self.get_serializer_queryset(queryset)
queryset.sort()
return super().get_serializer(queryset, many=many, **kwargs)
class UserAssetTreeMixin:
serializer_class = TreeNodeSerializer
nodes_only_fields = ParserNode.assets_only_fields
@staticmethod
def parse_assets_to_queryset(assets, node):
_queryset = []
for asset in assets:
data = ParserNode.parse_asset_to_tree_node(node, asset)
_queryset.append(data)
return _queryset
def get_serializer_queryset(self, queryset):
queryset = queryset.only(*self.nodes_only_fields)
_queryset = self.parse_assets_to_queryset(queryset, None)
return _queryset
def get_serializer(self, queryset, many=True, **kwargs):
queryset = self.get_serializer_queryset(queryset)
queryset.sort()
return super().get_serializer(queryset, many=many, **kwargs)
# -*- coding: utf-8 -*-
#
from django.shortcuts import get_object_or_404
from rest_framework.generics import (
ListAPIView, get_object_or_404
)
from common.permissions import IsOrgAdminOrAppUser
from common.utils import get_logger
from ...hands import Node
from ... import serializers
from .mixin import UserAssetPermissionMixin, UserAssetTreeMixin
logger = get_logger(__name__)
__all__ = [
'UserGrantedAssetsApi',
'UserGrantedAssetsAsTreeApi',
'UserGrantedNodeAssetsApi',
]
class UserGrantedAssetsApi(UserAssetPermissionMixin, ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
filter_fields = ['hostname', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment']
def filter_by_nodes(self, queryset):
node_id = self.request.query_params.get("node")
if not node_id:
return queryset
node = get_object_or_404(Node, pk=node_id)
query_all = self.request.query_params.get("all", "0") in ["1", "true"]
if query_all:
pattern = '^{0}$|^{0}:'.format(node.key)
queryset = queryset.filter(nodes__key__regex=pattern).distinct()
else:
queryset = queryset.filter(nodes=node)
return queryset
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
queryset = self.filter_by_nodes(queryset)
return queryset
def get_queryset(self):
queryset = self.util.get_assets().only(*self.only_fields)
return queryset
class UserGrantedAssetsAsTreeApi(UserAssetTreeMixin, UserGrantedAssetsApi):
pass
class UserGrantedNodeAssetsApi(UserGrantedAssetsApi):
def get_queryset(self):
node_id = self.kwargs.get("node_id")
node = get_object_or_404(Node, pk=node_id)
deep = self.request.query_params.get("all", "0") == "1"
queryset = self.util.get_nodes_assets(node, deep=deep)\
.only(*self.only_fields)
return queryset
# -*- coding: utf-8 -*-
#
from django.shortcuts import get_object_or_404
from rest_framework.generics import (
ListAPIView, get_object_or_404
)
from common.permissions import IsOrgAdminOrAppUser
from common.utils import get_logger
from ...hands import Node, NodeSerializer
from ... import serializers
from .mixin import UserNodeTreeMixin, UserAssetPermissionMixin
logger = get_logger(__name__)
__all__ = [
'UserGrantedNodesApi',
'UserGrantedNodesAsTreeApi',
'UserGrantedNodeChildrenApi',
'UserGrantedNodeChildrenAsTreeApi',
]
class UserGrantedNodesApi(UserAssetPermissionMixin, ListAPIView):
"""
查询用户授权的所有节点的API
"""
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.NodeGrantedSerializer
nodes_only_fields = NodeSerializer.Meta.only_fields
def get_serializer_context(self):
context = super().get_serializer_context()
if self.serializer_class == serializers.NodeGrantedSerializer:
context["tree"] = self.tree
return context
def get_queryset(self):
node_keys = self.util.get_nodes()
queryset = Node.objects.filter(key__in=node_keys)\
.only(*self.nodes_only_fields)
return queryset
class UserGrantedNodesAsTreeApi(UserNodeTreeMixin, UserGrantedNodesApi):
pass
class UserGrantedNodeChildrenApi(UserGrantedNodesApi):
node = None
root_keys = None # 如果是第一次访问,则需要把二级节点添加进去,这个 roots_keys
def get(self, request, *args, **kwargs):
key = self.request.query_params.get("key")
pk = self.request.query_params.get("id")
node = None
if pk is not None:
node = get_object_or_404(Node, id=pk)
elif key is not None:
node = get_object_or_404(Node, key=key)
self.node = node
return super().get(request, *args, **kwargs)
def get_queryset(self):
if self.node:
children = self.tree.children(self.node.key)
else:
children = self.tree.children(self.tree.root)
# 默认打开组织节点下的节点
self.root_keys = [child.identifier for child in children]
for key in self.root_keys:
children.extend(self.tree.children(key))
node_keys = [n.identifier for n in children]
queryset = Node.objects.filter(key__in=node_keys)
return queryset
class UserGrantedNodeChildrenAsTreeApi(UserNodeTreeMixin, UserGrantedNodeChildrenApi):
pass
# -*- coding: utf-8 -*-
#
from common.utils import get_logger
from ...utils import ParserNode
from .mixin import UserAssetTreeMixin
from ...hands import Node
from .user_permission_nodes import UserGrantedNodesAsTreeApi
from .user_permission_nodes import UserGrantedNodeChildrenAsTreeApi
logger = get_logger(__name__)
__all__ = [
'UserGrantedNodesAsTreeApi',
'UserGrantedNodesWithAssetsAsTreeApi',
'UserGrantedNodeChildrenAsTreeApi',
'UserGrantedNodeChildrenWithAssetsAsTreeApi',
]
class UserGrantedNodesWithAssetsAsTreeApi(UserGrantedNodesAsTreeApi):
assets_only_fields = ParserNode.assets_only_fields
def get_serializer_queryset(self, queryset):
_queryset = super().get_serializer_queryset(queryset)
_all_assets = self.util.get_assets().only(*self.assets_only_fields)
_all_assets_map = {a.id: a for a in _all_assets}
for node in queryset:
assets_ids = self.tree.assets(node.key)
assets = [_all_assets_map[_id] for _id in assets_ids if _id in _all_assets_map]
_queryset.extend(
UserAssetTreeMixin.parse_assets_to_queryset(assets, node)
)
return _queryset
class UserGrantedNodeChildrenWithAssetsAsTreeApi(UserGrantedNodeChildrenAsTreeApi):
nodes_only_fields = ParserNode.nodes_only_fields
assets_only_fields = ParserNode.assets_only_fields
def get_serializer_queryset(self, queryset):
_queryset = super().get_serializer_queryset(queryset)
nodes = []
if self.node:
nodes.append(self.node)
elif self.root_keys:
nodes = Node.objects.filter(key__in=self.root_keys)
for node in nodes:
assets = self.util.get_nodes_assets(node).only(
*self.assets_only_fields
)
_queryset.extend(
UserAssetTreeMixin.parse_assets_to_queryset(assets, node)
)
return _queryset
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select assets' %}" class="select2" id="asset_select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select assets' %}" class="select2" id="id_assets" style="width: 100%" multiple="" tabindex="4">
</select> </select>
</td> </td>
</tr> </tr>
...@@ -207,7 +207,7 @@ $(document).ready(function () { ...@@ -207,7 +207,7 @@ $(document).ready(function () {
var nodeListUrl = "{% url 'api-assets:node-list' %}"; var nodeListUrl = "{% url 'api-assets:node-list' %}";
nodesSelect2Init(".nodes-select2", nodeListUrl); nodesSelect2Init(".nodes-select2", nodeListUrl);
$("#asset_select2").parent().find(".select2-selection").on('click', function (e) { $("#id_assets").parent().find(".select2-selection").on('click', function (e) {
if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){ if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
...@@ -216,7 +216,7 @@ $(document).ready(function () { ...@@ -216,7 +216,7 @@ $(document).ready(function () {
}) })
}) })
.on('click', '.btn-add-assets', function () { .on('click', '.btn-add-assets', function () {
var assets_selected = $("#asset_select2 option:selected").map(function () { var assets_selected = $("#id_assets option:selected").map(function () {
return $(this).attr('value'); return $(this).attr('value');
}).get(); }).get();
if (assets_selected.length === 0) { if (assets_selected.length === 0) {
......
...@@ -4,6 +4,8 @@ import pickle ...@@ -4,6 +4,8 @@ import pickle
import threading import threading
from collections import defaultdict from collections import defaultdict
from functools import reduce from functools import reduce
from hashlib import md5
import json
from django.core.cache import cache from django.core.cache import cache
from django.db.models import Q from django.db.models import Q
...@@ -60,29 +62,33 @@ def get_system_user_permissions(system_user): ...@@ -60,29 +62,33 @@ def get_system_user_permissions(system_user):
class AssetPermissionUtilCacheMixin: 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_ttl = settings.ASSETS_PERM_CACHE_TIME
user_tree_cache_enable = settings.ASSETS_PERM_CACHE_ENABLE user_tree_cache_enable = settings.ASSETS_PERM_CACHE_ENABLE
cache_policy = '0' cache_policy = '0'
obj_id = '' obj_id = ''
_filter_id = 'None'
@property
def cache_key(self):
return self.user_tree_cache_key.format(self.obj_id, self._filter_id)
def expire_user_tree_cache(self): def expire_user_tree_cache(self):
key = self.user_tree_cache_key.format(self.obj_id) cache.delete(self.cache_key)
cache.delete(key)
@classmethod @classmethod
def expire_all_user_tree_cache(cls): def expire_all_user_tree_cache(cls):
key = cls.user_tree_cache_key.format('*') key = cls.user_tree_cache_key.format('*', '*')
key = key.split('_')[:-1]
key = '_'.join(key)
cache.delete_pattern(key) cache.delete_pattern(key)
def set_user_tree_to_cache(self, user_tree): def set_user_tree_to_cache(self, user_tree):
data = pickle.dumps(user_tree) data = pickle.dumps(user_tree)
key = self.user_tree_cache_key.format(self.obj_id) cache.set(self.cache_key, data, self.user_tree_cache_ttl)
cache.set(key, data, self.user_tree_cache_ttl)
def get_user_tree_from_cache(self): def get_user_tree_from_cache(self):
key = self.user_tree_cache_key.format(self.obj_id) data = cache.get(self.cache_key)
data = cache.get(key)
if not data: if not data:
return None return None
user_tree = pickle.loads(data) user_tree = pickle.loads(data)
...@@ -129,6 +135,7 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin): ...@@ -129,6 +135,7 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
self._filter_id = 'None' # 当通过filter更改 permission是标记 self._filter_id = 'None' # 当通过filter更改 permission是标记
self.change_org_if_need() self.change_org_if_need()
self._user_tree = None self._user_tree = None
self._user_tree_filter_id = 'None'
self.full_tree = Node.tree() self.full_tree = Node.tree()
self.mutex = threading.Lock() self.mutex = threading.Lock()
...@@ -148,7 +155,9 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin): ...@@ -148,7 +155,9 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
@timeit @timeit
def filter_permissions(self, **filters): def filter_permissions(self, **filters):
filters_json = json.dumps(filters, sort_keys=True)
self._permissions = self.permissions.filter(**filters) self._permissions = self.permissions.filter(**filters)
self._filter_id = md5(filters_json.encode()).hexdigest()
@property @property
def user_tree(self): def user_tree(self):
...@@ -282,15 +291,25 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin): ...@@ -282,15 +291,25 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
parent=user_tree.root, parent=user_tree.root,
) )
def set_user_tree_to_local(self, user_tree):
self._user_tree = user_tree
self._user_tree_filter_id = self._filter_id
def get_user_tree_from_local(self):
if self._user_tree and self._user_tree_filter_id == self._filter_id:
return self._user_tree
return None
@timeit @timeit
def get_user_tree(self): def get_user_tree(self):
# 使用锁,保证多次获取tree的时候顺序执行,可以使用缓存 # 使用锁,保证多次获取tree的时候顺序执行,可以使用缓存
with self.mutex: with self.mutex:
if self._user_tree: user_tree = self.get_user_tree_from_local()
return self._user_tree if user_tree:
return user_tree
user_tree = self.get_user_tree_from_cache_if_need() user_tree = self.get_user_tree_from_cache_if_need()
if user_tree: if user_tree:
self._user_tree = user_tree self.set_user_tree_to_local(user_tree)
return user_tree return user_tree
user_tree = TreeService() user_tree = TreeService()
full_tree_root = self.full_tree.root_node() full_tree_root = self.full_tree.root_node()
...@@ -303,7 +322,7 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin): ...@@ -303,7 +322,7 @@ class AssetPermissionUtilV2(AssetPermissionUtilCacheMixin):
self.parse_user_tree_to_full_tree(user_tree) self.parse_user_tree_to_full_tree(user_tree)
self.add_empty_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_cache_if_need(user_tree)
self._user_tree = user_tree self.set_user_tree_to_local(user_tree)
return user_tree return user_tree
# Todo: 是否可以获取多个资产的系统用户 # Todo: 是否可以获取多个资产的系统用户
......
...@@ -22,7 +22,7 @@ def refresh_settings_on_changed(sender, instance=None, **kwargs): ...@@ -22,7 +22,7 @@ def refresh_settings_on_changed(sender, instance=None, **kwargs):
instance.refresh_setting() instance.refresh_setting()
@receiver(django_ready, dispatch_uid="my_unique_identifier") @receiver(django_ready)
def monkey_patch_settings(sender, **kwargs): def monkey_patch_settings(sender, **kwargs):
logger.debug("Monkey patch settings") logger.debug("Monkey patch settings")
cache_key_prefix = '_SETTING_' cache_key_prefix = '_SETTING_'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment