mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-01 23:47:40 +00:00
fix: 修复授权树一些问题
This commit is contained in:
@@ -10,8 +10,11 @@
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from functools import reduce, partial
|
||||
import inspect
|
||||
|
||||
from django.db.models import *
|
||||
from django.db.models import QuerySet
|
||||
from django.db.models.functions import Concat
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
@@ -86,3 +89,84 @@ def concated_display(name1, name2):
|
||||
|
||||
def output_as_string(field_name):
|
||||
return ExpressionWrapper(F(field_name), output_field=CharField())
|
||||
|
||||
|
||||
class UnionQuerySet(QuerySet):
|
||||
after_union = ['order_by']
|
||||
not_return_qs = [
|
||||
'query', 'get', 'create', 'get_or_create',
|
||||
'update_or_create', 'bulk_create', 'count',
|
||||
'latest', 'earliest', 'first', 'last', 'aggregate',
|
||||
'exists', 'update', 'delete', 'as_manager', 'explain',
|
||||
]
|
||||
|
||||
def __init__(self, *queryset_list):
|
||||
self.queryset_list = queryset_list
|
||||
self.after_union_items = []
|
||||
self.before_union_items = []
|
||||
|
||||
def __execute(self):
|
||||
queryset_list = []
|
||||
for qs in self.queryset_list:
|
||||
for attr, args, kwargs in self.before_union_items:
|
||||
qs = getattr(qs, attr)(*args, **kwargs)
|
||||
queryset_list.append(qs)
|
||||
union_qs = reduce(lambda x, y: x.union(y), queryset_list)
|
||||
for attr, args, kwargs in self.after_union_items:
|
||||
union_qs = getattr(union_qs, attr)(*args, **kwargs)
|
||||
return union_qs
|
||||
|
||||
def __before_union_perform(self, item, *args, **kwargs):
|
||||
self.before_union_items.append((item, args, kwargs))
|
||||
return self.__clone(*self.queryset_list)
|
||||
|
||||
def __after_union_perform(self, item, *args, **kwargs):
|
||||
self.after_union_items.append((item, args, kwargs))
|
||||
return self.__clone(*self.queryset_list)
|
||||
|
||||
def __clone(self, *queryset_list):
|
||||
uqs = UnionQuerySet(*queryset_list)
|
||||
uqs.after_union_items = self.after_union_items
|
||||
uqs.before_union_items = self.before_union_items
|
||||
return uqs
|
||||
|
||||
def __getattribute__(self, item):
|
||||
if item.startswith('__') or item in UnionQuerySet.__dict__ or item in [
|
||||
'queryset_list', 'after_union_items', 'before_union_items'
|
||||
]:
|
||||
return object.__getattribute__(self, item)
|
||||
|
||||
if item in UnionQuerySet.not_return_qs:
|
||||
return getattr(self.__execute(), item)
|
||||
|
||||
origin_item = object.__getattribute__(self, 'queryset_list')[0]
|
||||
origin_attr = getattr(origin_item, item, None)
|
||||
if not inspect.ismethod(origin_attr):
|
||||
return getattr(self.__execute(), item)
|
||||
|
||||
if item in UnionQuerySet.after_union:
|
||||
attr = partial(self.__after_union_perform, item)
|
||||
else:
|
||||
attr = partial(self.__before_union_perform, item)
|
||||
return attr
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.__execute()[item]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.__execute())
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__execute())
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.__execute())
|
||||
|
||||
@classmethod
|
||||
def test_it(cls):
|
||||
from assets.models import Asset
|
||||
assets1 = Asset.objects.filter(hostname__startswith='a')
|
||||
assets2 = Asset.objects.filter(hostname__startswith='b')
|
||||
|
||||
qs = cls(assets1, assets2)
|
||||
return qs
|
||||
|
@@ -277,7 +277,3 @@ def bulk_get(d, *keys, default=None):
|
||||
for key in keys:
|
||||
values.append(d.get(key, default))
|
||||
return values
|
||||
|
||||
|
||||
def isinstance_method(attr):
|
||||
return isinstance(attr, type(Time().time))
|
@@ -93,21 +93,21 @@ class DistributedLock(RedisLock):
|
||||
if self.locked_by_current_thread():
|
||||
self._acquired_reentrant_lock = True
|
||||
logger.debug(
|
||||
f'I[{self.id}] reentry lock[{self.name}] in thread[{self._thread_id}].')
|
||||
f'Reentry lock ok: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
|
||||
return True
|
||||
|
||||
logger.debug(f'I[{self.id}] attempt acquire reentrant-lock[{self.name}].')
|
||||
logger.debug(f'Attempt acquire reentrant-lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
acquired = super().acquire(blocking=blocking, timeout=timeout)
|
||||
if acquired:
|
||||
logger.debug(f'I[{self.id}] acquired reentrant-lock[{self.name}] now.')
|
||||
logger.debug(f'Acquired reentrant-lock ok: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
setattr(thread_local, self.name, self.id)
|
||||
else:
|
||||
logger.debug(f'I[{self.id}] acquired reentrant-lock[{self.name}] failed.')
|
||||
logger.debug(f'Acquired reentrant-lock failed: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
return acquired
|
||||
else:
|
||||
logger.debug(f'I[{self.id}] attempt acquire lock[{self.name}].')
|
||||
logger.debug(f'Attempt acquire lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
acquired = super().acquire(blocking=blocking, timeout=timeout)
|
||||
logger.debug(f'I[{self.id}] acquired lock[{self.name}] {acquired}.')
|
||||
logger.debug(f'Acquired lock: ok={acquired} lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
return acquired
|
||||
|
||||
@property
|
||||
@@ -126,17 +126,17 @@ class DistributedLock(RedisLock):
|
||||
def _release_on_reentrant_locked_by_brother(self):
|
||||
if self._acquired_reentrant_lock:
|
||||
self._acquired_reentrant_lock = False
|
||||
logger.debug(f'I[{self.id}] released reentrant-lock[{self.name}] owner[{self.get_owner_id()}] in thread[{self._thread_id}]')
|
||||
logger.debug(f'Released reentrant-lock: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
|
||||
return
|
||||
else:
|
||||
self._raise_exc_with_log(f'Reentrant-lock[{self.name}] is not acquired by me[{self.id}].')
|
||||
self._raise_exc_with_log(f'Reentrant-lock is not acquired: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
|
||||
|
||||
def _release_on_reentrant_locked_by_me(self):
|
||||
logger.debug(f'I[{self.id}] release reentrant-lock[{self.name}] in thread[{self._thread_id}]')
|
||||
logger.debug(f'Release reentrant-lock locked by me: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
|
||||
id = getattr(thread_local, self.name, None)
|
||||
if id != self.id:
|
||||
raise PermissionError(f'Reentrant-lock[{self.name}] is not locked by me[{self.id}], owner[{id}]')
|
||||
raise PermissionError(f'Reentrant-lock is not locked by me: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
|
||||
try:
|
||||
# 这里要保证先删除 thread_local 的标记,
|
||||
delattr(thread_local, self.name)
|
||||
@@ -158,9 +158,9 @@ class DistributedLock(RedisLock):
|
||||
def _release(self):
|
||||
try:
|
||||
self._release_redis_lock()
|
||||
logger.debug(f'I[{self.id}] released lock[{self.name}]')
|
||||
logger.debug(f'Released lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
except NotAcquired as e:
|
||||
logger.error(f'I[{self.id}] release lock[{self.name}] failed {e}')
|
||||
logger.error(f'Release lock failed: lock_id={self.id} lock={self.name} thread={self._thread_id} error: {e}')
|
||||
self._raise_exc(e)
|
||||
|
||||
def release(self):
|
||||
@@ -174,11 +174,11 @@ class DistributedLock(RedisLock):
|
||||
else:
|
||||
_release = self._release_on_reentrant_locked_by_brother
|
||||
else:
|
||||
self._raise_exc_with_log(f'Reentrant-lock[{self.name}] is not acquired in current-thread[{self._thread_id}]')
|
||||
self._raise_exc_with_log(f'Reentrant-lock is not acquired: lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
|
||||
# 处理是否在事务提交时才释放锁
|
||||
if self._release_on_transaction_commit:
|
||||
logger.debug(f'I[{self.id}] release lock[{self.name}] on transaction commit ...')
|
||||
logger.debug(f'Release lock on transaction commit ... :lock_id={self.id} lock={self.name} thread={self._thread_id}')
|
||||
transaction.on_commit(_release)
|
||||
else:
|
||||
_release()
|
||||
|
Reference in New Issue
Block a user