예제 #1
0
def pre_insert_bills(bills):
    '''
    Before insert bill:
        1. Make sure now user is at least writer of the bill book of this bill.
        2. Set now user as the creater of this bill.
        3. Check related categorys, create if not existing.
    '''
    user = get_data('user', 409)

    for num, bill in enumerate(bills):
        relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': bill['billbook']
        })

        if not relation:
            billbook = operator.get('billbooks', {'_id': bill['billbook']})
            if billbook['status'] > 0:
                abort(400)
        elif relation['status'] > 2:
            abort(400)

        bills[num]['creater'] = user['_id']
        bills[num]['creater_name'] = user['nickname']

        if get_transfer_billbook(user['_id']) != bill['billbook']:
            _check_bill_cats(bill)
예제 #2
0
def check_billbook_readable(billbook, user, relation=None):
    billbook = operator.get('billbooks', {'_id': billbook})
    status = billbook.get('status')
    if status <= 1:
        return True
    elif relation is not None:
        return billbook['_id'] in relation
    else:
        relation = operator.get('billbook_user_relation', {
            'user': user,
            'billbook': billbook['_id']
        })
        return relation is not None
    return False
예제 #3
0
def remove():
    jwt_status, jwt_result = check_jwt(request)
    if not jwt_status:
        return jwt_result

    _, _, _, payload = jwt_result

    # get user
    username = payload.get('username')
    user = operator.get('users', {'username': username})
    if not user:
        return jsonify({
            'message': '用户不存在'
        }), 401

    # get user info
    user_info = operator.get('user_infos', {'_id': user['info']})
    if user_info:
        # remove bill books
        # TODO
        # if there are other owners, remove user from owner list
        # if user not owners, remove user from corrensponding list
        relations = get_user_billbook_relation(
            operator.id2str(user_info['_id']),
            True
        )
        print(user['_id'], user['info'], relations, list(relations.keys()))
        operator.delete_many('billbooks', {
            '_id': {'$in': list(relations.keys())},
        })
        operator.delete_many('billbook_user_relation', {
            'user': user_info['_id']
        })

        # TODO
        # remove the avator if it was saved

        # remove user info
        operator.delete('user_infos', {'_id': user_info['_id']})

    # remove account
    operator.delete_many('accounts', {'user': user_info['_id']})

    operator.delete('users', {'_id': user['_id']})

    return jsonify({
        'message': '删除用户成功'
    }), 200
예제 #4
0
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    remember = data.get('remember', False)
    # get user
    user = operator.get('users', {'username': username})
    if not user:
        return jsonify({
            'message': '用户不存在'
        }), 401

    # check password
    if not bcrypt_checker(password, user['password']):
        return jsonify({
            'message': '密码错误'
        }), 401

    # get user info
    user_info = operator.get('user_infos', {'_id': user['info']})
    if not user_info:
        return jsonify({
            'message': '用户信息加载失败'
        }), 404

    # generate jwt
    status, new, message, jwt, payload = jwt_run(payload={
        'user': user_info['id'],
        'username': username,
        'remember': remember
    })
    if not status:
        return jsonify({
            'message': message
        }), 400

    return jsonify({
        'jwt': jwt if new else '',
        'message': message,
        'id': user_info['id'],
        'username': username,
        'nickname': user_info['nickname'],
        'avatar': user_info['avatar']
    }), 200
예제 #5
0
def pre_insert_bill_categorys(cats):
    '''
    Before insert category:
        1. If the same category exists, stop
    '''
    for num, cat in enumerate(cats):
        billbook = cat.get('billbook')
        text = cat.get('text')
        if operator.get('bill_categorys', {'billbook': billbook, 'text': text}):
            abort(400)
예제 #6
0
    def instance_auth(self, bill, method):
        user = get_data('user')
        if not user:
            return False

        creater = bill.get('creater')
        relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': bill['billbook']
        })
        billbook = operator.get('billbooks', {'_id': bill['billbook']})

        relation_status = relation['status'] if relation else 4
        billbook_status = billbook['status']
        # set_data('relation', relation)
        if method in ['PATCH', 'DELETE']:
            return billbook_status == 0 or relation_status <= 1 or (user['_id'] is creater and relation_status <= 2)
        elif method == 'GET':
            return billbook_status <= 1 or relation_status is not None
        return False
예제 #7
0
def _check_bill_cats(bill):
    billbook = bill.get('billbook')
    text = bill.get('cat_0')
    label = bill.get('cat_1', '')
    cat = operator.get('bill_categorys', {'billbook': billbook, 'text': text})
    if cat and label:
        if cat.get('labels', []):
            operator.patch('bill_categorys', {
                           '$push': {'labels': label}}, {'_id': cat['_id']})
        else:
            operator.patch('bill_categorys', {
                           '$set': {'labels': [label]}}, {'_id': cat['_id']})
예제 #8
0
def get_user_billbook_relation(user, with_transfer=False):
    relations = operator.get_many('billbook_user_relation', {'user': user})
    relation_dict = {}
    for relation in relations:
        if not with_transfer:
            billbook = operator.get('billbooks', {'_id': relation['billbook']})
            if billbook['name'] == '***transfer***':
                continue
        relation_dict[relation['billbook']] = relation['status']
    # relations = {
    #     relation['billbook']:relations['status']
    #     for relation in relations
    # }
    return relation_dict
예제 #9
0
    def instance_auth(self, cat, method):
        user = get_data('user')
        if not user:
            return False

        relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': cat['billbook']
        })

        if method in ['DELETE', 'PATCH']:
            return relation['status'] <= 1
        elif method == 'GET':
            return relation is not None
        return False
예제 #10
0
def pre_update_bill_categorys(updates, cat):
    '''
    Before update category:
        1. Remove immutable fields 'billbook'
        2. If text is going to be change, check whether the same
           category exsits. If not, change the all related bills
           and categorys.
    '''
    del_immutable_field(updates, ['billbook'])

    billbook = cat.get('billbook')
    text = updates.get('text', None)
    if text:
        if operator.get('bill_categorys', {'text': text, 'billbook': billbook}):
            abort(400)
예제 #11
0
def pre_insert_relation(relations):
    '''
    Before insert relation:
        1. Only owners or managers can add new user.
        2. Managers can only add writers or readers
    '''
    user = get_data('user', 409)
    for num, relation in enumerate(relations):
        user_relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': relation['billbook']
        })
        if not user_relation or user_relation['status'] > 1:
            abort(409)
        if relation['status'] <= 1 and user_relation['status'] == 1:
            abort(409)
예제 #12
0
    def instance_auth(self, relation, method):
        user = get_data('user')
        if not user:
            return False

        user_relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': relation['billbook']
        })
        set_data('relation', user_relation)

        if method in ['DELETE', 'PATCH']:
            return user_relation and user_relation['status'] <= 1
        elif method == 'GET':
            return True
        return False
예제 #13
0
    def check_auth(self, token, allowed_roles, resource, method):
        status, new, msg, jwt, payload = jwt_run(jwt=token)
        if not status:
            return False

        user_id = payload['user']
        user = operator.get('user_infos', {'_id': user_id})
        if not user:
            return False
        set_data('user', user)

        args = request.view_args
        if args:
            resource_instance = self.get_resource_instance(resource, args['_id'])
            return self.instance_auth(resource_instance, method)
        else:
            return self.resource_auth(method)
예제 #14
0
def forget():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    # get user
    user = operator.get('users', {'username': username})
    if not user:
        return jsonify({
            'message': '用户不存在'
        }), 401

    # save new password
    hashed = bcrypt_generator(password)
    operator.patch('users', {'$set': {'password': hashed}}, {
                   '_id': user['_id']})

    return jsonify({
        'message': '修改密码成功'
    }), 200
예제 #15
0
def login_jwt():
    jwt_status, jwt_result = check_jwt(request)
    if not jwt_status:
        return jwt_result

    new, message, jwt, payload = jwt_result
    user_id = payload.get('user')
    username = payload.get('username')
    user_info = operator.get('user_infos', {'_id': user_id})
    if not user_info:
        return jsonify({
            'message': 'JWT无效, 请重新登录'
        }), 401

    return jsonify({
        'jwt': jwt if new else '',
        'message': message,
        'id': user_info['id'],
        'username': username,
        'nickname': user_info['nickname'],
        'avatar': user_info['avatar']
    }), 200
예제 #16
0
    def instance_auth(self, billbook, method):
        user = get_data('user')
        if not user:
            return False

        relation = operator.get('billbook_user_relation', {
            'user': user['_id'],
            'billbook': billbook['_id']
        })
        if relation:
            set_data('relation', relation)
            relation_status = relation['status']
        else:
            relation_status = 4

        billbook_status = billbook['status']
        if method == 'DELETE':
            return relation_status <= 0
        elif method == 'PATCH':
            return relation_status <= 1
        elif method == 'GET':
            return billbook_status <= 1 or relation_status <= 3
        return False
예제 #17
0
 def get_resource_instance(self, resource, resource_id):
     return operator.get(resource, {'_id': resource_id})
예제 #18
0
def register():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    remember = data.get('remember', False)
    nickname = data.get('nickname')

    # check user
    user = operator.get('users', {'username': username})
    if user:
        return jsonify({
            'message': '用户已存在'
        }), 409

    # create user_info
    user_info = operator.post('user_infos', {'nickname': nickname})
    if not user_info:
        return jsonify({
            'message': '用户信息创建失败'
        }), 407

    # create user with hashed password
    hashed = bcrypt_generator(password)
    user = operator.post('users', {
        'username': username,
        'password': hashed,
        'info': user_info['_id']
    })
    if not user:
        operator.delete('user_infos', {'_id': user_info['_id']})
        return jsonify({
            'message': '注册失败'
        }), 407

    # create default account
    account = operator.post('accounts', {
        'name': '默认账户',
        'amount': 0.0,
        'default': True,
        'user': user_info['_id']
    })
    if not account:
        operator.delete('user_infos', {'_id': user_info['_id']})
        operator.delete('users', {'_id': user['_id']})
        return jsonify({
            'message': '用户账户创建失败'
        }), 407

    # creater transfer billbook
    transfer_billbook = operator.post('billbooks', {
        'name': '***transfer***',
        'status': 2,
        'default': False
    })
    operator.post('billbook_user_relation', {
        'user': user_info['_id'],
        'billbook': transfer_billbook['_id'],
        'status': 0
    })
    # generate jwt
    return jsonify({
        'message': '注册成功'
    }), 200
예제 #19
0
def get_transfer_billbook(user):
    relations = operator.get_many('billbook_user_relation', {'user': user})
    for relation in relations:
        billbook = operator.get('billbooks', {'_id': relation['billbook']})
        if billbook['name'] == '***transfer***':
            return billbook['_id']