class OverrideDingAPIView(generics.RetrieveUpdateAPIView): ''' 回写覆盖钉钉数据 ''' permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_account_sync')) ]
class LogListAPIView(generics.ListAPIView): ''' get log list [GET] ''' permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_log_read')) ] serializer_class = LogLiteSerializer pagination_class = DefaultListPaginator def get_queryset(self): ''' filter queryset ''' kwargs = {} subject = self.request.query_params.get('subject', '') if subject: kwargs['subject__in'] = subject.split('|') summary = self.request.query_params.get('summary', '') if summary: kwargs['summary__icontains'] = summary days = self.request.query_params.get('days', None) if days is not None: if not days.isdigit(): raise ValidationError( {'days': ['this field must be interger']}) days = int(days) now = timezone.now() if days == 0: local_now = timezone.localtime(now) kwargs['created__gte'] = local_now.replace(hour=0, minute=0, second=0, microsecond=0) else: kwargs['created__gte'] = now - datetime.timedelta(days=days) queryset = Log.objects.filter(**kwargs) user = self.request.query_params.get('user', '') if user: queryset = queryset.filter( Q(user__username__icontains=user) | Q(user__name__icontains=user)) return queryset.order_by('-created')
class ImportDingAPIView(generics.RetrieveUpdateAPIView): ''' 拉取钉钉数据 ''' permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_account_sync')) ] serializer_class = UserListSerializer def get(self, request, *args, **kwargs): task = import_ding.delay() return Response({'task_id': task.task_id, 'task_msg': 'import ding'})
class StorageConfigAPIView(generics.RetrieveUpdateAPIView): ''' 文件存储方式 ''' serializer_class = StorageConfigSerializer permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_config_write')) ] def get_object(self): """ get storage site """ site = Site.objects.get_current() return site
class ContactsConfigAPIView(generics.RetrieveUpdateAPIView): ''' 通讯录配置 ''' serializer_class = ContactsConfigSerializer permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_config_write')) ] def get_object(self): """ get contacts config """ contactsconfig = ContactsConfig.valid_objects.first() return contactsconfig
class OverrideDingAPIView(generics.RetrieveUpdateAPIView): ''' 回写覆盖钉钉数据 ''' permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_account_sync')) ] serializer_class = UserListSerializer def get(self, request, *args, **kwargs): ding_config = DingConfig.get_current() ding_config.sync_state = 'push' ding_config.save() task = override_ding.delay() return Response({'task_id': task.task_id, 'task_msg': 'override ding'})
class ConfigAPIView(generics.RetrieveUpdateAPIView): """ 基本配置 [GET], [PATCH] 管理员可见 """ serializer_class = ConfigSerializer permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_config_write')) ] def get_object(self): """ get current site """ site = Site.objects.get_current() site.refresh_from_db() return site def perform_update(self, serializer): super().perform_update(serializer) # pylint: disable=no-member LOG_CLI().update_config()
class UserListCreateAPIView(generics.ListCreateAPIView): ''' 用户列表 [GET],[POST] ''' serializer_class = EmployeeSerializer pagination_class = DefaultListPaginator read_permission_classes = [IsAuthenticated & IsAdminUser] write_permission_classes = [IsAuthenticated & (IsAdminUser | CustomPerm('system_user_create'))] def get_permissions(self): ''' 读写权限 ''' if self.request.method in SAFE_METHODS: return [perm() for perm in self.read_permission_classes] return [perm() for perm in self.write_permission_classes] def get_queryset(self): ''' return queryset for list [GET] ''' keyword = self.request.query_params.get('keyword', '') if keyword != '': queryset = User.valid_objects.filter(Q(username__icontains=keyword)|Q(email__icontains=keyword)|\ Q(private_email__icontains=keyword)|Q(mobile__icontains=keyword)|Q(name__icontains=keyword)).\ exclude(is_boss=True).exclude(username='******').order_by('id') else: queryset = User.valid_objects.exclude(is_boss=True).exclude(username='******').order_by('id') return queryset @transaction.atomic() def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' create user [POST] ''' data = request.data user_info = data.get('user', '') group_uids = [] dept_uids = [] node_uids = data.get('node_uids', []) if node_uids: for node_uid in node_uids: if node_uid.startswith(Dept.NODE_PREFIX): dept_uids.append(node_uid.replace(Dept.NODE_PREFIX, '', 1)) elif node_uid.startswith(Group.NODE_PREFIX): group_uids.append(node_uid.replace( Group.NODE_PREFIX, '', )) else: group_uids = data.get('group_uids', []) dept_uids = data.get('dept_uids', []) cli = CLI() password = user_info.pop('password', None) user = cli.create_user(user_info) if password: cli.set_user_password(user, password) user.origin = 1 # 管理员添加 user.save() self.assign_user(user, dept_uids=dept_uids, group_uids=group_uids) user_serializer = EmployeeSerializer(user) return Response(user_serializer.data, status=status.HTTP_201_CREATED, headers=self.get_success_headers(user_serializer.data)) @staticmethod def assign_user(user, dept_uids, group_uids): ''' - add_user_to_depts - add_user_to_groups :param User user: :param list dept_uids: list of uid :param list group_uids: list of uid ''' depts = [] for dept_uid in dept_uids: try: dept = Dept.valid_objects.get(uid=dept_uid) except ObjectDoesNotExist: raise ValidationError({'dept_uids': ['dept:{} does not exist'.format(dept_uid)]}) depts.append(dept) groups = [] for group_uid in group_uids: try: group = Group.valid_objects.get(uid=group_uid) except ObjectDoesNotExist: raise ValidationError({'group_uids': ['group:{} does not exist'.format(group_uid)]}) groups.append(group) cli = CLI() cli.add_user_to_depts(user, depts) cli.add_user_to_groups(user, groups)
class APPListCreateAPIView(generics.ListCreateAPIView): ''' 管理页面-应用列表 [GET], [POST] 子管理员管理范围内的应用列表 ''' pagination_class = DefaultListPaginator read_permission_classes = [IsAuthenticated & (IsAdminUser | IsManagerUser)] write_permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_app_create')) ] def get_permissions(self): ''' 读写权限 ''' if self.request.method in SAFE_METHODS: return [perm() for perm in self.read_permission_classes] return [perm() for perm in self.write_permission_classes] def get_serializer_class(self): if self.request.method == 'GET': return APPWithAccessOwnerSerializer return APPSerializer def get_queryset(self): # pylint: disable=too-many-locals ''' get app list ''' kwargs = {} name = self.request.query_params.get('name', '') if name: kwargs = {'name__icontains': name} # 可管理范围 manager_app_uids = set() for manager_group in self.request.user.manager_groups: manager_app_uids.update(set(manager_group.apps)) kwargs['uid__in'] = manager_app_uids if self.request.user.is_admin: kwargs.pop('uid__in') manager_app_uids = None # 筛选-对owner可访问 owner = None access_app_uids = None node_uid = self.request.query_params.get('node_uid', None) if node_uid: node, _ = Dept.retrieve_node(node_uid) if not node: raise ValidationError({'node_uid': ['not found']}) owner = node user_uid = self.request.query_params.get('user_uid', None) if user_uid: user = User.valid_objects.filter(username=user_uid).first() if not user: raise ValidationError({'user_uid': ['not found']}) owner = user if owner: owner_access = self.request.query_params.get('owner_access', None) if owner_access is not None: # 一些基础的access判断 if owner_access in (True, 'true', 'True'): value = True elif owner_access in (False, 'false', 'False'): value = False else: raise ValidationError( {'owner_access': ['must be a boolean']}) scope_kwargs = {} if manager_app_uids is None else { 'perm__scope__in': manager_app_uids } if value is True and not user_uid is None: # 获取的是用户指定应用的权限 uids = [ item['perm__scope'] for item in UserPerm.valid_objects.filter( owner=owner, value=True, perm__subject='app', perm__action__startswith='access', ).values('perm__scope') ] # 获取的是指定应用部门的权限 data = [] dms = DeptMember.valid_objects.filter(user=owner) result = APP.valid_objects.filter( **kwargs).order_by('-created') for item in result: uid = item.uid if item.allow_any_user is True: if item.uuid not in data: data.append(item.uuid) else: if uid in uids: if item.uuid not in data: data.append(item.uuid) else: # 取的当前分组的所拥有的部门和当前用户的部门进行比对 perms = Perm.valid_objects.filter( scope=uid, subject='app', action__startswith='access').order_by('id') for perm in perms: deps = DeptPerm.valid_objects.filter( status=1, perm=perm) for dep in deps: owner = dep.owner # 用户的部门是否属于指定的部门 for dm in dms: dm_owner = dm.owner if dm_owner == owner: if item.uuid not in data: data.append(item.uuid) else: if dm_owner.if_belong_to_dept( owner, True) is True: if item.uuid not in data: data.append(item.uuid) return APP.valid_objects.filter( uuid__in=data).order_by('-created') else: access_app_uids = [ item['perm__scope'] for item in owner.owner_perm_cls.valid_objects.filter( owner=owner, perm__subject='app', perm__action='access', value=value, **scope_kwargs, ).values('perm__scope') ] kwargs['uid__in'] = access_app_uids apps = APP.valid_objects.filter(**kwargs).exclude( uid='oneid').order_by('-created') return apps @transaction.atomic() def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' create app [POST] ''' data = request.data serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) app = serializer.instance self._auto_create_access_perm(app) self._auto_create_manager_group(request, app) if data.get("secret_required", False): create_secret_for_app(app) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=self.get_success_headers(serializer.data)) def perform_create(self, serializer): super().perform_create(serializer) # pylint: disable=no-member cli = LOG_CLI() cli.create_app(serializer.validated_data) @staticmethod def _auto_create_manager_group(request, app): ''' 当创建应用时,自动创建子管理员组 成员只有创建者一人,节点管理范围为空,人员管理范围仅自己,应用管理范围仅此一个应用 ''' cli = CLI() data = { 'uid': gen_uid(name=uuid_utils.uuid4().hex[:6], cls=Group), 'name': f'管理应用{app.name}', 'manager_group': { 'apps': [app.uid], 'users': [request.user.username], 'scope_subject': 2, } } manager_group = cli.create_group(data) parent, _ = Group.valid_objects.get_or_create(uid='manager') cli.add_group_to_group(manager_group, parent) cli.add_users_to_group([request.user], manager_group) @staticmethod def _auto_create_access_perm(app): ''' 当创建应用时,自动创建访问权限 ''' Perm.valid_objects.create(name=f'访问{app.name}', subject='app', scope=app.uid, action='access')
class UserListCreateAPIView(generics.ListCreateAPIView): ''' 用户列表 [GET],[POST] :GET - 主管理员可见全部 - 子管理员可见管理范围内的指定人、指定节点及其子孙节点内的所有人 :POST - 主管理员可以创建用户 - 拥有 system_user_create 权限的子管理员 ''' serializer_class = EmployeeSerializer pagination_class = DefaultListPaginator read_permission_classes = [IsAuthenticated & (IsAdminUser | IsManagerUser)] write_permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_user_create')) ] def get_permissions(self): ''' 读写权限 ''' if self.request.method in SAFE_METHODS: return [perm() for perm in self.read_permission_classes] return [perm() for perm in self.write_permission_classes] def get_queryset(self): ''' return queryset for list [GET] ''' queryset = User.valid_objects.all() keyword = self.request.query_params.get('keyword', '') if keyword != '': queryset = queryset.filter(Q(username__icontains=keyword)|Q(email__icontains=keyword)|\ Q(private_email__icontains=keyword)|Q(mobile__icontains=keyword)|Q(name__icontains=keyword)).\ exclude(is_boss=True).exclude(username='******').order_by('id') else: queryset = queryset.exclude(is_boss=True).exclude( username='******').order_by('id') filter_params = ( 'wechat_unionid', 'name', 'name__icontains', 'username', 'username__icontains', 'email', 'email__icontains', 'private_email', 'private_email__icontains', 'mobile', 'mobile__icontains', 'gender', 'remark', 'remark__icontains', 'created__lte', 'created__gte', 'last_active_time__lte', 'last_active_time__gte', ) mapper = { 'wechat_unionid': 'wechat_user__unionid', } for param in filter_params: value = self.request.query_params.get(param, None) if value is not None: param = mapper.get(param, param) queryset = queryset.filter(**{param: value}) user = self.request.user if user.is_admin: return queryset.select_related('wechat_user', 'custom_user', 'ding_user') under_manage_user_ids = set() for item in queryset: # 这种遍历不能接受 if item.is_visible_to_manager(user): under_manage_user_ids.add(item.username) under_manage_user_query_set = queryset.filter( username__in=under_manage_user_ids) return under_manage_user_query_set @transaction.atomic() def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' create user [POST] ''' data = request.data user_info = data.get('user', '') group_uids = [] dept_uids = [] node_uids = data.get('node_uids', []) if node_uids: for node_uid in node_uids: if node_uid.startswith(Dept.NODE_PREFIX): dept_uids.append(node_uid.replace(Dept.NODE_PREFIX, '', 1)) elif node_uid.startswith(Group.NODE_PREFIX): group_uids.append(node_uid.replace( Group.NODE_PREFIX, '', )) else: group_uids = data.get('group_uids', []) dept_uids = data.get('dept_uids', []) cli = CLI() password = user_info.pop('password', None) user = cli.create_user(user_info) if password: cli.set_user_password(user, password) user.origin = 1 # 管理员添加 user.save() self.assign_user(user, dept_uids=dept_uids, group_uids=group_uids) user_serializer = EmployeeSerializer(user) return Response(user_serializer.data, status=status.HTTP_201_CREATED, headers=self.get_success_headers(user_serializer.data)) @staticmethod def assign_user(user, dept_uids, group_uids): ''' - add_user_to_depts - add_user_to_groups :param User user: :param list dept_uids: list of uid :param list group_uids: list of uid ''' depts = [] for dept_uid in dept_uids: try: dept = Dept.valid_objects.get(uid=dept_uid) except ObjectDoesNotExist: raise ValidationError( {'dept_uids': ['dept:{} does not exist'.format(dept_uid)]}) depts.append(dept) groups = [] for group_uid in group_uids: try: group = Group.valid_objects.get(uid=group_uid) except ObjectDoesNotExist: raise ValidationError({ 'group_uids': ['group:{} does not exist'.format(group_uid)] }) groups.append(group) cli = CLI() cli.add_user_to_depts(user, depts) cli.add_user_to_groups(user, groups)
class GroupChildGroupAPIView( mixins.UpdateModelMixin, mixins.RetrieveModelMixin, generics.ListCreateAPIView, ): ''' 组下属子组信息 [GET], [POST], [PATCH] 管理员可见 TODO: 权限校验需深入 ''' serializer_class = GroupListSerializer read_permission_classes = [ IsAuthenticated & (NodeEmployeeReadable | IsAdminUser | NodeManagerReadable) ] write_permission_classes = [ IsAuthenticated & (IsAdminUser | IsNodeManager) ] create_category_permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_category_create')) ] def dispatch(self, request, *args, **kwargs): ''' 管理员组下的子管理员组用专用View ''' if kwargs['uid'] == 'manager' and request.method == 'GET': return ManagerGroupListAPIView().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs) def get_permissions(self): ''' 读写权限 ''' if self.request.method in SAFE_METHODS: permissions = self.read_permission_classes elif self.kwargs[ 'uid'] == 'intra' and self.request.method == 'POST': # 新建大类 permissions = self.create_category_permission_classes else: permissions = self.write_permission_classes return [perm() for perm in permissions] def get_object(self): ''' find group ''' group = Group.valid_objects.filter(uid=self.kwargs['uid']).first() if not group: raise NotFound self.check_object_permissions(self.request, group) return group def get(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 获取组下属子组信息 [GET] ''' instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data) @transaction.atomic() def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 添加子组,从无到有 [POST] ''' parent_group = self.get_object() group_data = request.data uid = group_data.get('uid', '') if 'manager_group' in group_data: if parent_group.uid == 'manager': if not group_data.get('name', ''): name = "".join( random.choice(string.ascii_lowercase) for _ in range(8)) group_data.update(name=name) else: group_data.pop('manager_group') if not uid: name = group_data.get('name') if not name: raise ValidationError({'name': ['this field is required']}) uid = gen_uid(name=name, cls=Group) group_data['uid'] = uid cli = CLI() group_data.update(parent_uid=self.kwargs['uid']) child_group = cli.create_group(group_data) cli.add_group_to_group(child_group, parent_group) if parent_group.uid == 'intra': self._auto_create_manager_group(request, child_group) transaction.on_commit( lambda: WebhookManager.group_created(child_group)) return Response(GroupDetailSerializer(child_group).data, status=status.HTTP_201_CREATED) @catch_json_load_error def patch(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 调整子组 [PATCH] 操作包括 - 排序sort - 移动add, 即修改父部门。从无到有的添加,由create负责 ''' parent_group = self.get_object() data = json.loads(request.body.decode('utf-8')) subject = data.get('subject', '') if subject not in ['sort', 'add']: raise ValidationError( {'subject': ['this field must be `sort` or `add`']}) filters = {} if subject == 'sort': filters = {'parent': parent_group} group_uids = get_patch_scope(request) try: groups = Group.get_from_pks(pks=group_uids, pk_name='uid', raise_exception=True, **filters) except ObjectDoesNotExist as error: bad_uid = error.args[0] raise ValidationError( {'group_uids': ['group:{} invalid'.format(bad_uid)]}) cli = CLI() if subject == 'sort': cli.sort_groups_in_group(groups, parent_group) elif subject == 'add': for group in groups: cli.move_group_to_group(group, parent_group) return Response(GroupListSerializer(parent_group).data) @staticmethod def _auto_create_manager_group(request, child_group): ''' 当创建大类时,自动创建子管理员组 成员只有创建者一人,节点范围仅此大类,人员管理范围仅自己,应用管理范围为空 ''' cli = CLI() data = { 'uid': gen_uid(name=uuid_utils.uuid4().hex[:6], cls=Group), 'name': f'管理分组{child_group.name}', 'manager_group': { 'nodes': [child_group.node_uid], 'users': [request.user.username], 'scope_subject': 2, }, } manager_group = cli.create_group(data) parent, _ = Group.valid_objects.get_or_create(uid='manager') cli.add_group_to_group(manager_group, parent) cli.add_users_to_group([request.user], manager_group)
class UserListCreateAPIView(generics.ListCreateAPIView): ''' 用户列表 [GET],[POST] :GET - 主管理员可见全部 - 子管理员可见管理范围内的指定人、指定节点及其子孙节点内的所有人 :POST - 主管理员可以创建用户 - 拥有 system_user_create 权限的子管理员 ''' serializer_class = EmployeeSerializer pagination_class = DefaultListPaginator read_permission_classes = [IsAuthenticated & (IsAdminUser | IsManagerUser)] write_permission_classes = [ IsAuthenticated & (IsAdminUser | CustomPerm('system_user_create')) ] def get_permissions(self): ''' 读写权限 ''' if self.request.method in SAFE_METHODS: return [perm() for perm in self.read_permission_classes] return [perm() for perm in self.write_permission_classes] # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements def get_queryset(self): ''' return queryset for list [GET] ''' queryset = User.valid_objects.all() keyword = self.request.query_params.get('keyword', '') if keyword != '': queryset = (queryset.filter( Q(username__icontains=keyword) | Q(email__icontains=keyword) | Q(private_email__icontains=keyword) | Q(mobile__icontains=keyword) | Q(name__icontains=keyword)).exclude(is_boss=True).exclude( username='******').order_by('id')) else: queryset = (queryset.exclude(is_boss=True).exclude( username='******').order_by('id')) # 支持通过 user_id 搜索 # QueryString 中格式为 '&user_ids=id1 ... idn' user_ids = self._get_user_ids( self.request.query_params.get('user_ids', ''), 'user') queryset = (queryset.filter( pk__in=user_ids) if user_ids is not None else queryset) # 支持通过 usernames 搜索 # QueryString 中格式为 '&usernames=username1 ... usernamen' usernames = self.request.query_params.get('usernames', '') if usernames != '': usernames = usernames.split(' ') queryset = queryset.filter(username__in=usernames) # 支持通过 group_uid 搜索 (保留属于group_uids[]的用户) # QueryString 中格式为 '&group_uids=uid1 ... uidn' user_ids = self._get_user_ids( self.request.query_params.get('group_uids', ''), 'group') queryset = (queryset.filter( pk__in=user_ids) if user_ids is not None else queryset) # 支持通过 -group_uid 搜索 (保留不属于group_uids[]的用户) # QueryString 中格式为 '&group_uids=uid1 ... uidn' user_ids = self._get_user_ids( self.request.query_params.get('-group_uids', ''), 'group') queryset = (queryset.exclude( pk__in=user_ids) if user_ids is not None else queryset) # 支持通过 perm_uid 搜索 (保留拥有perm_uids[]的用户) # QueryString 中格式为 '&perm_uids=uid1 ... uidn' user_ids = self._get_user_ids( self.request.query_params.get('perm_uids', ''), 'perm') queryset = (queryset.filter( pk__in=user_ids) if user_ids is not None else queryset) # 支持通过 -perm_uid 搜索 (保留未拥有perm_uids[]的用户) # QueryString 中格式为 '&perm_uids=uid1 ... uidn' user_ids = self._get_user_ids( self.request.query_params.get('-perm_uids', ''), 'perm') queryset = (queryset.exclude( pk__in=user_ids) if user_ids is not None else queryset) filter_params = ( 'wechat_unionid', 'name', 'name__icontains', 'username', 'username__icontains', 'email', 'email__icontains', 'private_email', 'private_email__icontains', 'mobile', 'mobile__icontains', 'gender', 'remark', 'remark__icontains', 'created__lte', 'created__gte', 'last_active_time__lte', 'last_active_time__gte', 'unbound_wechat', 'unbound_ding', 'unbound_alipay', 'unbound_qq', ) mapper = { 'wechat_unionid': 'wechat_user__unionid', 'unbound_wechat': 'wechat_user__isnull', 'unbound_ding': 'ding_user__isnull', 'unbound_alipay': 'alipay_user__isnull', 'unbound_qq': 'qq_user__isnull', } boolean_params = ( 'unbound_wechat', 'unbound_ding', 'unbound_alipay', 'unbound_qq', ) _boolean_map = { 'true': True, 'false': False, } for param in filter_params: value = self.request.query_params.get(param, None) # 用户关联账号相关搜索 if (value is not None and param in boolean_params and value.lower() in _boolean_map.keys()): param = mapper.get(param) queryset = queryset.filter( **{param: _boolean_map.get(value.lower())}) continue if value is not None: param = mapper.get(param, param) queryset = queryset.filter(**{param: value}) # 获取 query string 中自定义字段(*__custom) # 支持 *__(lte, gte, lt, gt 等)__custom 形式,需进行范围搜索的字段在存储时保证传入的为string suffixes = [ '__lte__custom', '__lt__custom', '__gte__custom', '__gt__custom', '__custom', ] for key, value in self.request.query_params.items(): for suffix in suffixes: if key.endswith(suffix): _key = 'custom_user__data__"{custom_field}"{suffix}'.format( custom_field=key[:-1 * len(suffix)], suffix=suffix[:-8]) queryset = queryset.filter(**{_key: value}) break # 支持自定义排序 # QueryString 中格式为 '&sort=field1 ... fieldn' _sort = self.request.query_params.get('sort') _sort = _sort.split(' ') if _sort else [] # 校验排序字段合法性 for field_name in _sort: field_name = field_name[1:] if field_name.startswith( '-') else field_name try: # pylint: disable=no-member # pylint: disable=protected-access _ = User._meta.get_field(field_name) except FieldDoesNotExist: raise ValidationError( {'sort': f"Invalid order_by argument: '{field_name}'"}) queryset = queryset.order_by(*_sort) user = self.request.user if user.is_admin: return queryset.select_related('wechat_user', 'custom_user', 'ding_user') under_manage_user_ids = set() for item in queryset: # 这种遍历不能接受 if item.is_visible_to_manager(user): under_manage_user_ids.add(item.username) under_manage_user_query_set = queryset.filter( username__in=under_manage_user_ids) return under_manage_user_query_set @transaction.atomic() def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' create user [POST] ''' data = request.data user_info = data.get('user', '') group_uids = [] dept_uids = [] node_uids = data.get('node_uids', []) if node_uids: for node_uid in node_uids: if node_uid.startswith(Dept.NODE_PREFIX): dept_uids.append(node_uid.replace(Dept.NODE_PREFIX, '', 1)) elif node_uid.startswith(Group.NODE_PREFIX): group_uids.append(node_uid.replace( Group.NODE_PREFIX, '', )) else: group_uids = data.get('group_uids', []) dept_uids = data.get('dept_uids', []) cli = CLI() password = user_info.pop('password', None) # 创建用户 user = cli.create_user(user_info) if password: validate_password(password) cli.set_user_password(user, password) user.origin = 1 # 管理员添加 user.save() # 分配组和部门 self.assign_user(user, dept_uids=dept_uids, group_uids=group_uids) user_serializer = EmployeeSerializer(user) transaction.on_commit(lambda: WebhookManager.user_created(user)) return Response( user_serializer.data, status=status.HTTP_201_CREATED, headers=self.get_success_headers(user_serializer.data), ) @staticmethod def assign_user(user, dept_uids, group_uids): ''' - add_user_to_depts - add_user_to_groups :param User user: :param list dept_uids: list of uid :param list group_uids: list of uid ''' depts = [] for dept_uid in dept_uids: try: dept = Dept.valid_objects.get(uid=dept_uid) except ObjectDoesNotExist: raise ValidationError( {'dept_uids': ['dept:{} does not exist'.format(dept_uid)]}) depts.append(dept) groups = [] for group_uid in group_uids: try: group = Group.valid_objects.get(uid=group_uid) except ObjectDoesNotExist: raise ValidationError({ 'group_uids': ['group:{} does not exist'.format(group_uid)] }) groups.append(group) cli = CLI() cli.add_user_to_depts(user, depts) cli.add_user_to_groups(user, groups) def _get_user_ids(self, uids, subject): """ 获取即将过滤的 user_ids 列表 :param uids: 通过 QueryString 获取的 uids :param subject: 搜索的标签类型 """ if uids == '': return None user_ids = None uids = uids.split(' ') if subject == 'group': user_ids = (GroupMember.valid_objects.filter( owner__uid__in=uids).values('user__id').distinct()) if subject == 'perm': user_perms = UserPerm.valid_objects.filter(perm__uid__in=uids) for user_perm in user_perms: # 校验权限是否在管辖范围之内 if not user_perm.owner.under_manage(self.request.user): raise PermissionDenied({ 'perm_uids': f"Invalid perm_uids argument: '{user_perm.perm.uid}'" }) user_ids = user_perms.filter( value=True).values('owner__id').distinct() if subject == 'user': user_ids = uids return user_ids