def update(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 更新部门信息 ''' dept = self.get_object() data = json.loads(request.body.decode('utf-8')) dept = CLI().update_dept(dept, data) transaction.on_commit(lambda: WebhookManager.dept_updated(dept)) return Response(self.get_serializer(dept).data)
def create(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 添加子部门,从无到有 [POST] ''' parent_dept = self.get_object() dept_data = json.loads(request.body.decode('utf-8')) uid = dept_data.get('uid', '') if not uid: name = dept_data.get('name') uid = gen_uid(name=name, cls=Dept) dept_data['uid'] = uid dept_data.update(parent_uid=self.kwargs['uid']) cli = CLI() child_dept = cli.create_dept(dept_data) cli.add_dept_to_dept(child_dept, parent_dept) transaction.on_commit(lambda: WebhookManager.dept_created(child_dept)) return Response(DeptDetailSerializer(child_dept).data, status=status.HTTP_201_CREATED)
def update(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 更新组信息 [PATCH] ''' group = self.get_object() data = json.loads(request.body.decode('utf-8')) group = CLI().update_group(group, data) transaction.on_commit(lambda: WebhookManager.group_updated(group)) return Response(self.get_serializer(group).data)
def update(self, request, *args, **kwargs): # pylint: disable=unused-argument serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) validated_data = serializer.validated_data user = validated_data.pop('user') if user.is_settled: # raise AuthenticationFailed return 403 ? return Response('only for unsettled user', status=status.HTTP_401_UNAUTHORIZED) cli = CLI(user=user) user.__dict__.update(validated_data) user.save() cli.set_user_password(user, validated_data['password']) LOG_CLI(user).user_activate() return Response({ # 'token': user.token, **UserWithPermSerializer(user).data, })
def update(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' update user detail [PATCH] ''' user = self.get_object() data = request.data user = CLI().update_user(user, data) user_serializer = EmployeeSerializer(user) return Response(user_serializer.data)
def update(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' update user detail [PATCH] ''' user = self.get_object() data = request.data user = CLI().update_user(user, data) transaction.on_commit(lambda: WebhookManager.user_updated(user)) return Response(UserSerializer(user).data)
def create(self, request, *args, **kwargs): ''' qq扫码加绑定 ''' if not AccountConfig.get_current().support_qq_qr_register: return Response({'err_msg': 'qq qr register not allowed'}, HTTP_403_FORBIDDEN) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.perform_create(serializer) cli = CLI(user) cli.add_users_to_group([user], Group.get_extern_root()) data = self.read_serializer_class(user).data data.update(token=user.token) open_id = serializer.validated_data['user_id'] qq_user = QQUser.valid_objects.create(open_id=open_id, user=user) qq_user.save() return Response(data, status=status.HTTP_201_CREATED)
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), )
def patch(self, request, *args, **kwargs): # pylint: disable=unused-argument ''' 调整子部门 [PATCH] 目前应只需要排序和移入 ''' parent_dept = 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_dept} dept_uids = get_patch_scope(request) try: depts = Dept.get_from_pks(pks=dept_uids, pk_name='uid', raise_exception=True, **filters) except ObjectDoesNotExist as error: bad_uid = error.args[0] raise ValidationError( {'dept_uids': ['dept:{} invalid'.format(bad_uid)]}) cli = CLI() if subject == 'sort': cli.sort_depts_in_dept(depts, parent_dept) elif subject == 'add': for dept in depts: cli.move_dept_to_dept(dept, parent_dept) return Response(DeptListSerializer(parent_dept).data)
def extern_to_intra(user, depts=[]): ''' 外部用户转化为内部用户 ''' cli = CLI() cli.delete_user_from_groups(user, user.groups) cli.add_user_to_depts(user, depts)
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)
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 update_user_nodes(user, nodes, uids, node_type, action_subject): # pylint: disable=too-many-locals ''' :param oneid_meta.groups.User user: :param list nodes: :param list uids: 优先级低于`nodes` :param str node_type: group or dept :param str action_subject: enum(['add', 'delete', 'override']) ''' if action_subject not in ('add', 'delete', 'override'): raise ValidationError( {'subject': ['this field must be one of add, delete, override']}) if not nodes: nodes = [] if node_type.lower() == 'dept': cls = Dept elif node_type.lower() == 'group': cls = Group else: raise ValueError(f'invalid node_type: {node_type}') for uid in uids: try: node = cls.valid_objects.get(uid=uid) nodes.append(node) except ObjectDoesNotExist: raise ValidationError( {'node_uids': ['node:{} does not exist'.format(uid)]}) cli = CLI() if action_subject == 'add': func = getattr(cli, 'add_user_to_{}s'.format(node_type)) func(user, nodes) elif action_subject == 'delete': func = getattr(cli, 'delete_user_from_{}s'.format(node_type)) func(user, nodes) elif action_subject == 'override': if (node_type == 'group') & (not user.is_intra): # 由于 `extern` 对外隐藏而又必须存在,在覆盖时常不会提供 # 故对没有显示说要从 `extern` 移除的,视为不移除 extern_group, _ = Group.valid_objects.get_or_create(uid='extern') nodes.append(extern_group) diff = operation.list_diff(nodes, getattr(user, '{}s'.format(node_type))) add_nodes = diff['>'] delete_nodes = diff['<'] add_func = getattr(cli, 'add_user_to_{}s'.format(node_type)) add_func(user, add_nodes) delete_func = getattr(cli, 'delete_user_from_{}s'.format(node_type)) delete_func(user, delete_nodes)
def save_model(self, request, obj, form, change): ''' 在原保存数据基础上增加密码同步 仅在编辑时进行,仅同步密码字段 输入明文密码即可,与密文不同即会被视为明文 ''' if change: ciphertext_pwd = User.valid_objects.get(id=obj.id).password new_pwd = request.POST.get('password') super(UserAdmin, self).save_model(request, obj, form, change) if ciphertext_pwd != new_pwd: CLI().set_user_password(obj, new_pwd) super(UserAdmin, self).save_model(request, obj, form, change)
def update_user_nodes(request, user, nodes, uids, node_type, action_subject): ''' :param oneid_meta.groups.User user: :param list nodes: :param list uids: 优先级低于`nodes` :param str node_type: group or dept :param str action_subject: enum(['add', 'delete', 'override']) ''' if action_subject not in ('add', 'delete', 'override'): raise ValidationError( {'subject': ['this field must be one of add, delete, override']}) if not nodes: nodes = [] if node_type.lower() == 'dept': cls = Dept elif node_type.lower() == 'group': cls = Group else: raise ValueError(f'invalid node_type: {node_type}') for uid in uids: try: node = cls.valid_objects.get(uid=uid) nodes.append(node) except ObjectDoesNotExist: raise ValidationError( {'node_uids': ['node:{} does not exist'.format(uid)]}) cli = CLI() if action_subject == 'add': func = getattr(cli, 'add_user_to_{}s'.format(node_type)) func(user, nodes) elif action_subject == 'delete': func = getattr(cli, 'delete_user_from_{}s'.format(node_type)) func(user, nodes) elif action_subject == 'override': diff = operation.list_diff(nodes, getattr(user, '{}s'.format(node_type))) add_nodes = diff['>'] delete_nodes = diff['<'] add_func = getattr(cli, 'add_user_to_{}s'.format(node_type)) add_func(user, add_nodes) delete_func = getattr(cli, 'delete_user_from_{}s'.format(node_type)) delete_func(user, delete_nodes)
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)
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)
def update(self, instance, validated_data): cli = CLI() cli.update_user(instance, validated_data) return instance
def update(self, instance, validated_data): # pylint: disable=too-many-locals, too-many-statements, too-many-branches company_config_data = validated_data.pop('company_config', None) if company_config_data: if not Dept.valid_objects.filter(parent__uid='root').exists(): uid = gen_uid(name=company_config_data.get('name_cn', ''), cls=Dept) parent_dept = Dept.valid_objects.filter(uid='root').first() cli = CLI() dept_data = { 'parent_uid': 'root', 'name': company_config_data.get('name_cn', ''), 'uid': uid, } child_dept = cli.create_dept(dept_data) cli.add_dept_to_dept(child_dept, parent_dept) else: company_dept = Dept.valid_objects.filter( parent__uid='root').first() company_dept.name = company_config_data.get('name_cn', '') company_dept.save() serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') config = SMSConfig.get_current() serializer = SMSConfigSerializer(config, sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'sms': ['invalid']}) config.is_valid = True config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') config = EmailConfig.get_current() serializer = EmailConfigSerializer(config, email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'email': ['invalid']}) config.is_valid = True config.save() alipay_config_data = validated_data.pop('alipay_config', None) if alipay_config_data: if alipay_config_data["app_id"] != '': serializer = AlipayConfigSerializer(AlipayConfig.get_current(), alipay_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() qq_config_data = validated_data.pop('qq_config', None) if qq_config_data: serializer = QQConfigSerializer(QQConfig.get_current(), qq_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() work_wechat_config_data = validated_data.pop('work_wechat_config', None) if work_wechat_config_data: serializer = WorkWechatConfigSerializer(WorkWechatConfig.get_current(),\ work_wechat_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() wechat_config_data = validated_data.pop('wechat_config', None) if wechat_config_data: serializer = WechatConfigSerializer(WechatConfig.get_current(),\ wechat_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() password_config_data = validated_data.pop('password_config', None) if password_config_data: config = PasswordComplexityConfig.get_current() serializer = PasswordConfigSerializer(config, password_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) config.save() github_config = validated_data.pop('github_config', None) if github_config: config = GithubConfig.get_current() serializer = GithubConfigSerializer(config, github_config, partial=True) serializer.is_valid(raise_exception=True) serializer.save() instance.refresh_from_db() return instance
def perform_destroy(self, instance): ''' 删除组 ''' CLI().delete_dept(instance)
def update(self, instance, validated_data): company_config_data = validated_data.pop('company_config', None) if company_config_data: if not Dept.valid_objects.filter(parent__uid='root').exists(): uid = gen_uid(name=company_config_data.get('name_cn', ''), cls=Dept) parent_dept = Dept.valid_objects.filter(uid='root').first() cli = CLI() dept_data = { 'parent_uid': 'root', 'name': company_config_data.get('name_cn', ''), 'uid': uid, } child_dept = cli.create_dept(dept_data) cli.add_dept_to_dept(child_dept, parent_dept) else: company_dept = Dept.valid_objects.filter(parent__uid='root').first() company_dept.name = company_config_data.get('name_cn', '') company_dept.save() serializer = CompanyConfigSerializer(CompanyConfig.get_current(), company_config_data) serializer.is_valid(raise_exception=True) serializer.save() ding_config_data = validated_data.pop('ding_config', None) if ding_config_data: serializer = DingConfigSerializer(DingConfig.get_current(), ding_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() account_config_data = validated_data.pop('account_config', None) if account_config_data: serializer = AccountConfigSerializer(AccountConfig.get_current(), account_config_data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() sms_config_data = validated_data.pop('sms_config', None) if sms_config_data: access_secret = sms_config_data.pop('access_secret', '') config = SMSConfig.get_current() serializer = SMSConfigSerializer(config, sms_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'sms': ['invalid']}) config.is_valid = True config.save() email_config_data = validated_data.pop('email_config', None) if email_config_data: access_secret = email_config_data.pop('access_secret', '') config = EmailConfig.get_current() serializer = EmailConfigSerializer(config, email_config_data, partial=True) serializer.is_valid(raise_exception=True) # pylint: disable=not-callable config.__dict__.update(serializer.validated_data) if access_secret: config.access_secret = access_secret if not config.check_valid(): raise ValidationError({'email': ['invalid']}) config.is_valid = True config.save() instance.refresh_from_db() return instance
def update(self, instance, validated_data): user = validated_data['user'] password = validated_data.get('new_password') CLI(user=user).set_user_password(user, password) user.invalidate_token() return user
def perform_destroy(self, instance): ''' 删除组 [DELETE] ''' CLI().delete_group(instance)