Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
 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)
Esempio n. 4
0
    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,
        })
Esempio n. 5
0
 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)
Esempio n. 6
0
 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)
Esempio n. 7
0
    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)
Esempio n. 8
0
    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),
        )
Esempio n. 9
0
    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)
Esempio n. 10
0
 def extern_to_intra(user, depts=[]):
     '''
     外部用户转化为内部用户
     '''
     cli = CLI()
     cli.delete_user_from_groups(user, user.groups)
     cli.add_user_to_depts(user, depts)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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)
Esempio n. 13
0
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)
Esempio n. 14
0
    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)
Esempio n. 15
0
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)
Esempio n. 16
0
File: app.py Progetto: justpic/arkid
 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)
Esempio n. 17
0
 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)
Esempio n. 18
0
 def update(self, instance, validated_data):
     cli = CLI()
     cli.update_user(instance, validated_data)
     return instance
Esempio n. 19
0
    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
Esempio n. 20
0
 def perform_destroy(self, instance):
     '''
     删除组
     '''
     CLI().delete_dept(instance)
Esempio n. 21
0
    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
Esempio n. 22
0
 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
Esempio n. 23
0
 def perform_destroy(self, instance):
     '''
     删除组 [DELETE]
     '''
     CLI().delete_group(instance)