fix(perms): 用户添加到用户组报错

This commit is contained in:
xinwen
2020-09-27 19:47:13 +08:00
committed by 老广
parent b8ff3b38bf
commit 6701a1b604
8 changed files with 54 additions and 35 deletions

View File

@@ -17,7 +17,7 @@ from ...utils.user_asset_permission import (
get_indirect_granted_node_children,
get_user_granted_nodes_list_via_mapping_node,
get_top_level_granted_nodes,
init_user_tree_if_need,
rebuild_user_tree_if_need,
)
@@ -61,7 +61,7 @@ class BaseGrantedNodeApi(_GrantedNodeStructApi, metaclass=abc.ABCMeta):
@tmp_to_root_org()
def list(self, request, *args, **kwargs):
init_user_tree_if_need(self.user)
rebuild_user_tree_if_need(request, self.user)
nodes = self.get_nodes()
serializer = self.get_serializer(nodes, many=True)
return Response(serializer.data)
@@ -73,8 +73,8 @@ class BaseNodeChildrenApi(NodeChildrenMixin, BaseGrantedNodeApi, metaclass=abc.A
class BaseGrantedNodeAsTreeApi(SerializeToTreeNodeMixin, _GrantedNodeStructApi, metaclass=abc.ABCMeta):
@tmp_to_root_org()
def list(self, request, *args, **kwargs):
init_user_tree_if_need(self.user)
def list(self, request: Request, *args, **kwargs):
rebuild_user_tree_if_need(request, self.user)
nodes = self.get_nodes()
nodes = self.serialize_nodes(nodes, with_asset_amount=True)
return Response(data=nodes)

View File

@@ -12,7 +12,7 @@ from ...utils.user_asset_permission import (
get_indirect_granted_node_children, UNGROUPED_NODE_KEY, FAVORITE_NODE_KEY,
get_user_direct_granted_assets, get_top_level_granted_nodes,
get_user_granted_nodes_list_via_mapping_node,
get_user_granted_all_assets, init_user_tree_if_need,
get_user_granted_all_assets, rebuild_user_tree_if_need,
get_user_all_assetpermission_ids,
)
@@ -38,7 +38,7 @@ class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
"""
user = request.user
init_user_tree_if_need(user)
rebuild_user_tree_if_need(request, user)
all_nodes = get_user_granted_nodes_list_via_mapping_node(user)
all_assets = get_user_granted_all_assets(user)
@@ -106,7 +106,7 @@ class UserGrantedNodeChildrenWithAssetsAsTreeForAdminApi(ForAdminMixin, UserNode
key = self.id2key_if_have()
user = self.user
init_user_tree_if_need(user)
rebuild_user_tree_if_need(request, user)
nodes, assets = self.get_data(key, user)
tree_nodes = self.serialize_nodes(nodes, with_asset_amount=True)

View File

@@ -4,16 +4,16 @@ from itertools import chain
from django.db.models.signals import m2m_changed, pre_delete, pre_save
from django.dispatch import receiver
from django.db import transaction
from django.db.models import Q
from perms.tasks import dispatch_mapping_node_tasks
from perms.tasks import create_rebuild_user_tree_task
from users.models import User, UserGroup
from assets.models import Asset
from common.utils import get_logger
from common.utils import get_logger, get_object_or_none
from common.exceptions import M2MReverseNotAllowed
from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR
from .models import AssetPermission, RemoteAppPermission, RebuildUserTreeTask
from .models import AssetPermission, RemoteAppPermission
logger = get_logger(__file__)
@@ -21,9 +21,12 @@ logger = get_logger(__file__)
@receiver([pre_save], sender=AssetPermission)
def on_asset_perm_deactive(instance: AssetPermission, **kwargs):
old = AssetPermission.objects.only('is_active').get(id=instance.id)
if instance.is_active != old.is_active:
create_rebuild_user_tree_task_by_asset_perm(instance)
try:
old = AssetPermission.objects.only('is_active').get(id=instance.id)
if instance.is_active != old.is_active:
create_rebuild_user_tree_task_by_asset_perm(instance)
except AssetPermission.DoesNotExist:
pass
@receiver([pre_delete], sender=AssetPermission)
@@ -32,13 +35,6 @@ def on_asset_permission_delete(instance, **kwargs):
create_rebuild_user_tree_task_by_asset_perm(instance)
def create_rebuild_user_tree_task(user_ids):
RebuildUserTreeTask.objects.bulk_create(
[RebuildUserTreeTask(user_id=i) for i in user_ids]
)
transaction.on_commit(dispatch_mapping_node_tasks.delay)
def create_rebuild_user_tree_task_by_asset_perm(asset_perm: AssetPermission):
user_ids = set()
user_ids.update(

View File

@@ -2,6 +2,7 @@
from __future__ import absolute_import, unicode_literals
from datetime import timedelta
from django.db import transaction
from django.db.models import Q
from django.conf import settings
from celery import shared_task
@@ -9,23 +10,25 @@ from common.utils import get_logger
from common.utils.timezone import now
from users.models import User
from perms.models import RebuildUserTreeTask, AssetPermission
from perms.utils.user_asset_permission import rebuild_user_mapping_nodes_if_need_with_lock
from perms.utils.user_asset_permission import rebuild_user_mapping_nodes_if_need_with_lock, lock
logger = get_logger(__file__)
@shared_task(queue='node_tree')
def rebuild_user_mapping_nodes_celery_task(user_id):
logger.info(f'>>> rebuild user[{user_id}] mapping nodes')
user = User.objects.get(id=user_id)
rebuild_user_mapping_nodes_if_need_with_lock(user)
try:
rebuild_user_mapping_nodes_if_need_with_lock(user)
except lock.SomeoneIsDoingThis:
pass
@shared_task(queue='node_tree')
def dispatch_mapping_node_tasks():
user_ids = RebuildUserTreeTask.objects.all().values_list('user_id', flat=True).distinct()
logger.info(f'>>> dispatch_mapping_node_tasks for users {list(user_ids)}')
for id in user_ids:
logger.info(f'>>> dispatch mapping node task for user[{id}]')
rebuild_user_mapping_nodes_celery_task.delay(id)
@@ -55,3 +58,10 @@ def dispatch_process_expired_asset_permission(asset_perm_ids):
)
dispatch_mapping_node_tasks.delay()
def create_rebuild_user_tree_task(user_ids):
RebuildUserTreeTask.objects.bulk_create(
[RebuildUserTreeTask(user_id=i) for i in user_ids]
)
transaction.on_commit(dispatch_mapping_node_tasks.delay)

View File

@@ -8,6 +8,7 @@ from django.conf import settings
from django.db.models import F, Q, Value, BooleanField
from django.utils.translation import gettext as _
from common.http import is_true
from common.utils import get_logger
from common.const.distributed_lock_key import UPDATE_MAPPING_NODE_TASK_LOCK_KEY
from orgs.utils import tmp_to_root_org
@@ -247,10 +248,12 @@ def set_node_granted_assets_amount(user, node):
def rebuild_user_mapping_nodes(user):
logger.info(f'>>> {dt_formater(now())} start rebuild {user} mapping nodes')
tmp_nodes = compute_tmp_mapping_node_from_perm(user)
for _node in tmp_nodes:
set_node_granted_assets_amount(user, _node)
create_mapping_nodes(user, tmp_nodes)
logger.info(f'>>> {dt_formater(now())} end rebuild {user} mapping nodes')
def get_user_granted_nodes_list_via_mapping_node(user):
@@ -486,12 +489,13 @@ def get_favorite_node(user):
)
def init_user_tree_if_need(user):
def rebuild_user_tree_if_need(request, user):
"""
升级授权树策略后,用户的数据可能还未初始化,为防止用户显示没有数据
先检查 MappingNode 如果没有数据,同步创建用户授权树
"""
if not UserGrantedMappingNode.objects.filter(user=user).exists():
if is_true(request.query_params.get('rebuild_tree')) or \
not UserGrantedMappingNode.objects.filter(user=user).exists():
try:
rebuild_user_mapping_nodes_with_lock(user)
except lock.SomeoneIsDoingThis: