mirror of https://github.com/jumpserver/jumpserver
				
				
				
			[Update] 用户权限增加cache
							parent
							
								
									dfd26d88d4
								
							
						
					
					
						commit
						58c4a46f6e
					
				|  | @ -29,6 +29,7 @@ class Node(OrgModelMixin): | |||
| 
 | ||||
|     class Meta: | ||||
|         verbose_name = _("Node") | ||||
|         ordering = ['key'] | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return self.full_value | ||||
|  |  | |||
|  | @ -1,5 +0,0 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| from django.dispatch import Signal | ||||
| 
 | ||||
| on_app_ready = Signal() | ||||
|  | @ -17,7 +17,6 @@ | |||
|                    <div class="file-manager "> | ||||
|                        <div id="assetTree" class="ztree"> | ||||
|                        </div> | ||||
| 
 | ||||
|                        <div class="clearfix"></div> | ||||
|                    </div> | ||||
|                </div> | ||||
|  | @ -62,16 +61,19 @@ | |||
| 
 | ||||
| {% block custom_foot_js %} | ||||
| <script> | ||||
| var treeUrl = "{% url 'api-perms:my-nodes-assets-as-tree' %}?show_assets=0&cache_policy=1"; | ||||
| var zTree, asset_table, show=0; | ||||
| var inited = false; | ||||
| var url; | ||||
| 
 | ||||
| 
 | ||||
| function initTable() { | ||||
|     if (inited){ | ||||
|         return | ||||
|     } else { | ||||
|         inited = true; | ||||
|     } | ||||
|     url = "{% url 'api-perms:my-assets' %}"; | ||||
|     url = "{% url 'api-perms:my-assets' %}?cache_policy=1"; | ||||
|     var options = { | ||||
|         ele: $('#user_assets_table'), | ||||
|         columnDefs: [ | ||||
|  | @ -106,7 +108,7 @@ function initTable() { | |||
| } | ||||
| 
 | ||||
| function onSelected(event, treeNode) { | ||||
|     url = '{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}'; | ||||
|     url = '{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}?cache_policy=1'; | ||||
|     var node_id = treeNode.meta.node.id; | ||||
|     url = url.replace("{{ DEFAULT_PK }}", node_id); | ||||
|     setCookie('node_selected', treeNode.id); | ||||
|  | @ -118,7 +120,7 @@ function initTree() { | |||
|     var setting = { | ||||
|         view: { | ||||
|             dblClickExpand: false, | ||||
|             showLine: true | ||||
|             showLine: true, | ||||
|         }, | ||||
|         data: { | ||||
|             simpleData: { | ||||
|  | @ -131,10 +133,14 @@ function initTree() { | |||
|     }; | ||||
| 
 | ||||
|     var zNodes = []; | ||||
|     $.get("{% url 'api-perms:my-nodes-assets-as-tree' %}?show_assets=0", function(data, status){ | ||||
|     $.get(treeUrl, function(data, status){ | ||||
|         zNodes = data; | ||||
|         $.fn.zTree.init($("#assetTree"), setting, zNodes); | ||||
|         zTree = $.fn.zTree.getZTreeObj("assetTree"); | ||||
|         rootNodeAddDom(zTree, function () { | ||||
|             treeUrl = treeUrl.replace('cache_policy=1', 'cache_policy=2'); | ||||
|             initTree(); | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,20 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| from django.shortcuts import render | ||||
| from django.http import JsonResponse | ||||
| 
 | ||||
| 
 | ||||
| def handler404(request, *args, **argv): | ||||
|     if request.content_type.find('application/json') > -1: | ||||
|         response = JsonResponse({'error': 'Not found'}, status=404) | ||||
|     else: | ||||
|         response = render(request, '404.html', status=404) | ||||
|     return response | ||||
| 
 | ||||
| 
 | ||||
| def handler500(request, *args, **argv): | ||||
|     if request.content_type.find('application/json') > -1: | ||||
|         response = JsonResponse({'error': 'Server internal error'}, status=500) | ||||
|     else: | ||||
|         response = render(request, '500.html', status=500) | ||||
|     return response | ||||
|  | @ -21,7 +21,7 @@ api_v1_patterns = [ | |||
|         path('audits/v1/', include('audits.urls.api_urls', namespace='api-audits')), | ||||
|         path('orgs/v1/', include('orgs.urls.api_urls', namespace='api-orgs')), | ||||
|         path('settings/v1/', include('settings.urls.api_urls', namespace='api-settings')), | ||||
|        path('authentication/v1/', include('authentication.urls.api_urls', namespace='api-auth')), | ||||
|         path('authentication/v1/', include('authentication.urls.api_urls', namespace='api-auth')), | ||||
|    ])) | ||||
| ] | ||||
| 
 | ||||
|  | @ -68,6 +68,9 @@ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ | |||
|             + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) | ||||
| urlpatterns += js_i18n_patterns | ||||
| 
 | ||||
| handler404 = 'jumpserver.error_views.handler404' | ||||
| handler500 = 'jumpserver.error_views.handler500' | ||||
| 
 | ||||
| if settings.DEBUG: | ||||
|     urlpatterns += [ | ||||
|         re_path('^swagger(?P<format>\.json|\.yaml)$', | ||||
|  |  | |||
|  | @ -110,9 +110,9 @@ function initTree() { | |||
|             onCheck: onCheck | ||||
|         } | ||||
|     }; | ||||
|     var url = "{% url 'api-perms:my-nodes-assets-as-tree' %}"; | ||||
|     var url = "{% url 'api-perms:my-nodes-assets-as-tree' %}?cache_policy=1"; | ||||
|     if (systemUserId) { | ||||
|         url += '?system_user=' + systemUserId | ||||
|         url += '&system_user=' + systemUserId | ||||
|     } | ||||
| 
 | ||||
|     $.get(url, function(data, status){ | ||||
|  |  | |||
|  | @ -1,6 +1,9 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| 
 | ||||
| from hashlib import md5 | ||||
| from django.core.cache import cache | ||||
| from django.conf import settings | ||||
| from django.shortcuts import get_object_or_404 | ||||
| from rest_framework.views import APIView, Response | ||||
| from rest_framework.generics import ( | ||||
|  | @ -10,6 +13,7 @@ from rest_framework.pagination import LimitOffsetPagination | |||
| 
 | ||||
| from common.permissions import IsValidUser, IsOrgAdminOrAppUser | ||||
| from common.tree import TreeNodeSerializer | ||||
| from common.utils import get_logger | ||||
| from orgs.utils import set_to_root_org | ||||
| from ..utils import ( | ||||
|     AssetPermissionUtil, parse_asset_to_tree_node, parse_node_to_tree_node | ||||
|  | @ -21,6 +25,7 @@ from ..hands import ( | |||
| from .. import serializers | ||||
| from ..mixins import AssetsFilterMixin | ||||
| 
 | ||||
| logger = get_logger(__name__) | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'UserGrantedAssetsApi', 'UserGrantedNodesApi', | ||||
|  | @ -32,18 +37,61 @@ __all__ = [ | |||
| 
 | ||||
| class UserPermissionMixin: | ||||
|     cache_policy = '0' | ||||
|     RESP_CACHE_KEY = '_PERMISSION_RESPONSE_CACHE_{}' | ||||
|     CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def change_org_if_need(request, kwargs): | ||||
|         if request.user.is_superuser or \ | ||||
|         if request.user.is_authenticated and \ | ||||
|                 request.user.is_superuser or \ | ||||
|                 request.user.is_app or \ | ||||
|                 kwargs.get('pk') is None: | ||||
|             set_to_root_org() | ||||
| 
 | ||||
|     def dispatch(self, request, *args, **kwargs): | ||||
|     def get_response_from_cache(self, request): | ||||
|         if self.cache_policy in ['1', 'using']: | ||||
|             path_md5 = md5(request.get_full_path().encode()).hexdigest() | ||||
|             obj = self.get_object() | ||||
|             util = AssetPermissionUtil(obj, cache_policy=self.cache_policy) | ||||
|             cache_id = '{}_{}'.format(path_md5, util.cache_meta.get('id')) | ||||
|             response = self.get_cache_response(cache_id) | ||||
|             return response | ||||
|         return None | ||||
| 
 | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         self.change_org_if_need(request, kwargs) | ||||
|         self.cache_policy = request.GET.get('cache_policy', '0') | ||||
|         return super().dispatch(request, *args, **kwargs) | ||||
|         path_md5 = md5(request.get_full_path().encode()).hexdigest() | ||||
|         path_cache_key = '{}_{}'.format(path_md5, '*') | ||||
|         if self.cache_policy in AssetPermissionUtil.CACHE_POLICY_MAP[0]: | ||||
|             return super().get(request, *args, **kwargs) | ||||
|         elif self.cache_policy in AssetPermissionUtil.CACHE_POLICY_MAP[2]: | ||||
|             self.expire_cache_response(path_cache_key) | ||||
|         obj = self.get_object() | ||||
|         util = AssetPermissionUtil(obj, cache_policy=self.cache_policy) | ||||
|         cache_id = '{}_{}'.format(path_md5, util.cache_meta.get('id')) | ||||
|         response = self.get_cache_response(cache_id) | ||||
|         if not response: | ||||
|             response = super().get(request, *args, **kwargs) | ||||
|             self.set_cache_response(cache_id, response) | ||||
|         return response | ||||
| 
 | ||||
|     def get_cache_response(self, _id): | ||||
|         if not _id: | ||||
|             return None | ||||
|         key = self.RESP_CACHE_KEY.format(_id) | ||||
|         data = cache.get(key) | ||||
|         if not data: | ||||
|             return None | ||||
|         return Response(data) | ||||
| 
 | ||||
|     def expire_cache_response(self, _id): | ||||
|         key = self.RESP_CACHE_KEY.format(_id) | ||||
|         cache.delete(key) | ||||
| 
 | ||||
|     def set_cache_response(self, _id, response): | ||||
|         key = self.RESP_CACHE_KEY.format(_id) | ||||
|         cache.set(key, response.data, self.CACHE_TIME) | ||||
| 
 | ||||
| 
 | ||||
| class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView): | ||||
|  | @ -54,15 +102,18 @@ class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView): | |||
|     serializer_class = AssetGrantedSerializer | ||||
|     pagination_class = LimitOffsetPagination | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|     def get_object(self): | ||||
|         user_id = self.kwargs.get('pk', '') | ||||
|         queryset = [] | ||||
| 
 | ||||
|         if user_id: | ||||
|             user = get_object_or_404(User, id=user_id) | ||||
|         else: | ||||
|             user = self.request.user | ||||
|         return user | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         queryset = [] | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         assets = util.get_assets() | ||||
|         for k, v in assets.items(): | ||||
|  | @ -84,12 +135,16 @@ class UserGrantedNodesApi(UserPermissionMixin, ListAPIView): | |||
|     permission_classes = (IsOrgAdminOrAppUser,) | ||||
|     serializer_class = NodeSerializer | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|     def get_object(self): | ||||
|         user_id = self.kwargs.get('pk', '') | ||||
|         if user_id: | ||||
|             user = get_object_or_404(User, id=user_id) | ||||
|         else: | ||||
|             user = self.request.user | ||||
|         return user | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         nodes = util.get_nodes_with_assets() | ||||
|         return nodes.keys() | ||||
|  | @ -107,14 +162,17 @@ class UserGrantedNodesWithAssetsApi(UserPermissionMixin, AssetsFilterMixin, List | |||
|     permission_classes = (IsOrgAdminOrAppUser,) | ||||
|     serializer_class = serializers.NodeGrantedSerializer | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|     def get_object(self): | ||||
|         user_id = self.kwargs.get('pk', '') | ||||
|         queryset = [] | ||||
|         if not user_id: | ||||
|             user = self.request.user | ||||
|         else: | ||||
|             user = get_object_or_404(User, id=user_id) | ||||
|         return user | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         queryset = [] | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         nodes = util.get_nodes_with_assets() | ||||
|         for node, _assets in nodes.items(): | ||||
|  | @ -154,17 +212,22 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionMixin, ListAPIView): | |||
|             self.permission_classes = (IsValidUser,) | ||||
|         return super().get_permissions() | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|     def get_object(self): | ||||
|         user_id = self.kwargs.get('pk', '') | ||||
|         queryset = [] | ||||
|         if not user_id: | ||||
|             user = self.request.user | ||||
|         else: | ||||
|             user = get_object_or_404(User, id=user_id) | ||||
|         return user | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         queryset = [] | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         if self.system_user_id: | ||||
|             util.filter_permission_with_system_user( | ||||
|                 system_user=self.system_user_id) | ||||
|                 system_user=self.system_user_id | ||||
|             ) | ||||
|         nodes = util.get_nodes_with_assets() | ||||
|         for node, assets in nodes.items(): | ||||
|             data = parse_node_to_tree_node(node) | ||||
|  | @ -186,14 +249,18 @@ class UserGrantedNodeAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIVi | |||
|     serializer_class = AssetGrantedSerializer | ||||
|     pagination_class = LimitOffsetPagination | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|     def get_object(self): | ||||
|         user_id = self.kwargs.get('pk', '') | ||||
|         node_id = self.kwargs.get('node_id') | ||||
| 
 | ||||
|         if user_id: | ||||
|             user = get_object_or_404(User, id=user_id) | ||||
|         else: | ||||
|             user = self.request.user | ||||
|         return user | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         user = self.get_object() | ||||
|         node_id = self.kwargs.get('node_id') | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         node = get_object_or_404(Node, id=node_id) | ||||
|         nodes = util.get_nodes_with_assets() | ||||
|  | @ -217,8 +284,12 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView): | |||
|     permission_classes = (IsValidUser,) | ||||
|     serializer_class = serializers.AssetPermissionNodeSerializer | ||||
| 
 | ||||
|     def get_object(self): | ||||
|         return self.request.user | ||||
| 
 | ||||
|     def get_children_queryset(self): | ||||
|         util = AssetPermissionUtil(self.request.user, cache_policy=self.cache_policy) | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         node_id = self.request.query_params.get('id') | ||||
|         nodes_granted = util.get_nodes_with_assets() | ||||
|         if not nodes_granted: | ||||
|  | @ -258,7 +329,8 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView): | |||
|         return queryset | ||||
| 
 | ||||
|     def get_search_queryset(self, keyword): | ||||
|         util = AssetPermissionUtil(self.request.user, cache_policy=self.cache_policy) | ||||
|         user = self.get_object() | ||||
|         util = AssetPermissionUtil(user, cache_policy=self.cache_policy) | ||||
|         nodes_granted = util.get_nodes_with_assets() | ||||
|         queryset = [] | ||||
|         for node, assets in nodes_granted.items(): | ||||
|  | @ -294,7 +366,7 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView): | |||
| class ValidateUserAssetPermissionApi(UserPermissionMixin, APIView): | ||||
|     permission_classes = (IsOrgAdminOrAppUser,) | ||||
| 
 | ||||
|     def get(self, request): | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         user_id = request.query_params.get('user_id', '') | ||||
|         asset_id = request.query_params.get('asset_id', '') | ||||
|         system_id = request.query_params.get('system_user_id', '') | ||||
|  |  | |||
|  | @ -1,15 +1,26 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| from django.db.models.signals import m2m_changed | ||||
| from django.db.models.signals import m2m_changed, post_save, post_delete | ||||
| from django.dispatch import receiver | ||||
| 
 | ||||
| from common.utils import get_logger | ||||
| from .utils import AssetPermissionUtil | ||||
| from .models import AssetPermission | ||||
| 
 | ||||
| 
 | ||||
| logger = get_logger(__file__) | ||||
| 
 | ||||
| 
 | ||||
| @receiver(post_save) | ||||
| def on_permission_update(sender, **kwargs): | ||||
|     AssetPermissionUtil.expire_all_cache() | ||||
| 
 | ||||
| 
 | ||||
| @receiver(post_delete) | ||||
| def on_permission_delete(sender, **kwargs): | ||||
|     AssetPermissionUtil.expire_all_cache() | ||||
| 
 | ||||
| 
 | ||||
| @receiver(m2m_changed, sender=AssetPermission.nodes.through) | ||||
| def on_permission_nodes_changed(sender, instance=None, **kwargs): | ||||
|     if isinstance(instance, AssetPermission) and kwargs['action'] == 'post_add': | ||||
|  |  | |||
|  | @ -1,7 +1,9 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| from __future__ import absolute_import, unicode_literals | ||||
| import uuid | ||||
| from collections import defaultdict | ||||
| from django.utils import timezone | ||||
| from django.db.models import Q | ||||
| from django.core.cache import cache | ||||
| from django.conf import settings | ||||
|  | @ -100,14 +102,19 @@ class AssetPermissionUtil: | |||
|     } | ||||
| 
 | ||||
|     CACHE_KEY = '_ASSET_PERM_CACHE_{}_{}' | ||||
|     CACHE_META_KEY = '_ASSET_PERM_META_KEY_{}' | ||||
|     CACHE_TIME = settings.ASSETS_PERM_CACHE_TIME | ||||
|     CACHE_POLICY_MAP = (('0', 'never'), ('1', 'using'), ('2', 'refresh')) | ||||
| 
 | ||||
|     def __init__(self, obj, cache_policy='0'): | ||||
|         self.object = obj | ||||
|         self.obj_id = str(obj.id) | ||||
|         self._permissions = None | ||||
|         self._assets = None | ||||
|         self.cache_policy = cache_policy | ||||
|         self.node_key = self.CACHE_KEY.format(self.obj_id, 'NODES_WITH_ASSETS') | ||||
|         self.asset_key = self.CACHE_KEY.format(self.obj_id, 'ASSETS') | ||||
|         self.system_key = self.CACHE_KEY.format(self.obj_id, 'SYSTEM_USER') | ||||
| 
 | ||||
|     @property | ||||
|     def permissions(self): | ||||
|  | @ -163,14 +170,11 @@ class AssetPermissionUtil: | |||
|         return self._assets | ||||
| 
 | ||||
|     def get_assets_from_cache(self): | ||||
|         cache_key = self.CACHE_KEY.format(str(self.object.id), 'ASSETS') | ||||
|         cached = cache.get(cache_key) | ||||
|         if cached: | ||||
|             return cached | ||||
|         assets = self.get_assets_without_cache() | ||||
|         self.expire_cache() | ||||
|         cache.set(cache_key, assets, self.CACHE_TIME) | ||||
|         return assets | ||||
|         cached = cache.get(self.asset_key) | ||||
|         if not cached: | ||||
|             self.update_cache() | ||||
|             cached = cache.get(self.asset_key) | ||||
|         return cached | ||||
| 
 | ||||
|     def get_assets(self): | ||||
|         if self.cache_policy in self.CACHE_POLICY_MAP[1]: | ||||
|  | @ -179,6 +183,7 @@ class AssetPermissionUtil: | |||
|             self.expire_cache() | ||||
|             return self.get_assets_from_cache() | ||||
|         else: | ||||
|             self.expire_cache() | ||||
|             return self.get_assets_without_cache() | ||||
| 
 | ||||
|     def get_nodes_with_assets_without_cache(self): | ||||
|  | @ -187,21 +192,18 @@ class AssetPermissionUtil: | |||
|         {"node": {"assets": set("system_user")}} | ||||
|         :return: | ||||
|         """ | ||||
|         assets = self.get_assets() | ||||
|         assets = self.get_assets_without_cache() | ||||
|         tree = GenerateTree() | ||||
|         for asset, system_users in assets.items(): | ||||
|             tree.add_asset(asset, system_users) | ||||
|         return tree.get_nodes() | ||||
| 
 | ||||
|     def get_nodes_with_assets_from_cache(self): | ||||
|         cache_key = self.CACHE_KEY.format(str(self.object.id), 'NODES_WITH_ASSETS') | ||||
|         cached = cache.get(cache_key) | ||||
|         if cached: | ||||
|             return cached | ||||
|         nodes = self.get_nodes_with_assets_without_cache() | ||||
|         self.expire_cache() | ||||
|         cache.set(cache_key, nodes, self.CACHE_TIME) | ||||
|         return nodes | ||||
|         cached = cache.get(self.node_key) | ||||
|         if not cached: | ||||
|             self.update_cache() | ||||
|             cached = cache.get(self.node_key) | ||||
|         return cached | ||||
| 
 | ||||
|     def get_nodes_with_assets(self): | ||||
|         if self.cache_policy in self.CACHE_POLICY_MAP[1]: | ||||
|  | @ -220,14 +222,11 @@ class AssetPermissionUtil: | |||
|         return system_users | ||||
| 
 | ||||
|     def get_system_user_from_cache(self): | ||||
|         cache_key = self.CACHE_KEY.format(str(self.object.id), 'SYSTEM_USER') | ||||
|         cached = cache.get(cache_key) | ||||
|         if cached: | ||||
|             return cached | ||||
|         self.expire_cache() | ||||
|         system_users = self.get_system_user_without_cache() | ||||
|         cache.set(cache_key, system_users, self.CACHE_TIME) | ||||
|         return system_users | ||||
|         cached = cache.get(self.system_key) | ||||
|         if not cached: | ||||
|             self.update_cache() | ||||
|             cached = cache.get(self.system_key) | ||||
|         return cached | ||||
| 
 | ||||
|     def get_system_users(self): | ||||
|         if self.cache_policy in self.CACHE_POLICY_MAP[1]: | ||||
|  | @ -238,14 +237,51 @@ class AssetPermissionUtil: | |||
|         else: | ||||
|             return self.get_system_user_without_cache() | ||||
| 
 | ||||
|     @property | ||||
|     def cache_meta(self): | ||||
|         key = self.CACHE_META_KEY.format(str(self.object.id)) | ||||
|         return cache.get(key) or {} | ||||
| 
 | ||||
|     def set_cache_meta(self): | ||||
|         key = self.CACHE_META_KEY.format(str(self.object.id)) | ||||
|         meta = { | ||||
|             'id': str(uuid.uuid4()), | ||||
|             'datetime': timezone.now(), | ||||
|             'object': str(self.object) | ||||
|         } | ||||
|         cache.set(key, meta, self.CACHE_TIME) | ||||
| 
 | ||||
|     def expire_cache_meta(self): | ||||
|         key = self.CACHE_META_KEY.format(str(self.object.id)) | ||||
|         cache.delete(key) | ||||
| 
 | ||||
|     def update_cache(self): | ||||
|         assets = self.get_assets_without_cache() | ||||
|         nodes = self.get_nodes_with_assets_without_cache() | ||||
|         system_users = self.get_system_user_without_cache() | ||||
|         cache.set(self.asset_key, assets, self.CACHE_TIME) | ||||
|         cache.set(self.node_key, nodes, self.CACHE_TIME) | ||||
|         cache.set(self.system_key, system_users, self.CACHE_TIME) | ||||
|         self.set_cache_meta() | ||||
| 
 | ||||
|     def expire_cache(self): | ||||
|         cache_key = self.CACHE_KEY.format(str(self.object.id), '*') | ||||
|         cache.delete_pattern(cache_key) | ||||
|         """ | ||||
|         因为 获取用户的节点,资产,系统用户等都能会缓存,这里会清理所有与该对象有关的 | ||||
|         缓存,以免造成不统一的情况 | ||||
|         :return: | ||||
|         """ | ||||
|         key = self.CACHE_KEY.format(str(self.object.id), '*') | ||||
|         cache.delete_pattern(key) | ||||
|         self.expire_cache_meta() | ||||
| 
 | ||||
|     def expire_all_cache_meta(self): | ||||
|         key = self.CACHE_META_KEY.format('*') | ||||
|         cache.delete_pattern(key) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def expire_all_cache(cls): | ||||
|         cache_key = cls.CACHE_KEY.format('*', '*') | ||||
|         cache.delete_pattern(cache_key) | ||||
|         key = cls.CACHE_KEY.format('*', '*') | ||||
|         cache.delete_pattern(key) | ||||
| 
 | ||||
| 
 | ||||
| def is_obj_attr_has(obj, val, attrs=("hostname", "ip", "comment")): | ||||
|  |  | |||
|  | @ -105,7 +105,8 @@ class LDAPSettingForm(BaseForm): | |||
|     ) | ||||
|     AUTH_LDAP_SEARCH_OU = forms.CharField( | ||||
|         label=_("User OU"), | ||||
|         help_text=_("Use | split User OUs") | ||||
|         help_text=_("Use | split User OUs"), | ||||
|         required=False, | ||||
|     ) | ||||
|     AUTH_LDAP_SEARCH_FILTER = forms.CharField( | ||||
|         label=_("User search filter"), | ||||
|  |  | |||
|  | @ -450,3 +450,7 @@ div.dataTables_wrapper div.dataTables_filter { | |||
|     content:"*"; | ||||
|     color:red; | ||||
| } | ||||
| 
 | ||||
| #tree-refresh .fa-refresh { | ||||
|     font: normal normal normal 14px/1 FontAwesome !important; | ||||
| } | ||||
|  | @ -922,3 +922,16 @@ function initSelectedAssets2Table(){ | |||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function rootNodeAddDom(ztree, callback) { | ||||
|     var refreshIcon = "<a id='tree-refresh'><i class='fa fa-refresh'></i></a>"; | ||||
|     var rootNode = ztree.getNodes()[0]; | ||||
|     var $rootNodeRef = $("#" + rootNode.tId + "_a"); | ||||
|     $rootNodeRef.after(refreshIcon); | ||||
|     var refreshIconRef = $('#tree-refresh'); | ||||
|     refreshIconRef.bind('click', function () { | ||||
|         ztree.destroy(); | ||||
|         callback() | ||||
|     }) | ||||
| } | ||||
|  | @ -0,0 +1,10 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <title>Not found</title> | ||||
| </head> | ||||
| <body> | ||||
| <h1>Not found</h1> | ||||
| </body> | ||||
| </html> | ||||
|  | @ -0,0 +1,10 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <title>Server error</title> | ||||
| </head> | ||||
| <body> | ||||
| <h1>Server error occur, contact administrator</h1> | ||||
| </body> | ||||
| </html> | ||||
|  | @ -286,20 +286,21 @@ class User(AbstractUser): | |||
| 
 | ||||
|     @property | ||||
|     def private_token(self): | ||||
|         return self.create_private_token() | ||||
| 
 | ||||
|     def create_private_token(self): | ||||
|         from .authentication import PrivateToken | ||||
|         from authentication.models import PrivateToken | ||||
|         try: | ||||
|             token = PrivateToken.objects.get(user=self) | ||||
|         except PrivateToken.DoesNotExist: | ||||
|             token = PrivateToken.objects.create(user=self) | ||||
|         return token.key | ||||
|             token = self.create_private_token() | ||||
|         return token | ||||
| 
 | ||||
|     def create_private_token(self): | ||||
|         from authentication.models import PrivateToken | ||||
|         token = PrivateToken.objects.create(user=self) | ||||
|         return token | ||||
| 
 | ||||
|     def refresh_private_token(self): | ||||
|         from .authentication import PrivateToken | ||||
|         PrivateToken.objects.filter(user=self).delete() | ||||
|         return PrivateToken.objects.create(user=self) | ||||
|         self.private_token.delete() | ||||
|         return self.create_private_token() | ||||
| 
 | ||||
|     def create_bearer_token(self, request=None): | ||||
|         expiration = settings.TOKEN_EXPIRATION or 3600 | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ var zTree; | |||
| var inited = false; | ||||
| var url; | ||||
| var asset_table; | ||||
| var treeUrl = "{% url 'api-perms:user-nodes-assets-as-tree' pk=object.id %}?show_assets=0&cache_policy=1"; | ||||
| 
 | ||||
| function initTable() { | ||||
|     if (inited){ | ||||
|  | @ -71,7 +72,7 @@ function initTable() { | |||
|     } else { | ||||
|         inited = true; | ||||
|     } | ||||
|     url = "{% url 'api-perms:user-assets' pk=object.id %}"; | ||||
|     url = "{% url 'api-perms:user-assets' pk=object.id %}?cache_policy=1"; | ||||
|     var options = { | ||||
|         ele: $('#user_assets_table'), | ||||
|         columnDefs: [ | ||||
|  | @ -106,13 +107,14 @@ function initTable() { | |||
| } | ||||
| 
 | ||||
| function onSelected(event, treeNode) { | ||||
|     url = '{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}'; | ||||
|     url = '{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}?cache_policy=1'; | ||||
|     var node_id = treeNode.meta.node.id; | ||||
|     url = url.replace("{{ DEFAULT_PK }}", node_id); | ||||
|     asset_table.ajax.url(url); | ||||
|     asset_table.ajax.reload(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function initTree() { | ||||
|     var setting = { | ||||
|         view: { | ||||
|  | @ -129,9 +131,13 @@ function initTree() { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     $.get("{% url 'api-perms:user-nodes-assets-as-tree' pk=object.id %}?show_assets=0", function(data, status) { | ||||
|     $.get(treeUrl, function(data, status) { | ||||
|         $.fn.zTree.init($("#assetTree"), setting, data); | ||||
|         zTree = $.fn.zTree.getZTreeObj("assetTree"); | ||||
|         rootNodeAddDom(zTree, function () { | ||||
|             treeUrl = treeUrl.replace('cache_policy=1', 'cache_policy=2'); | ||||
|             initTree(); | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 ibuler
						ibuler