Beispiel #1
0
def do(data, resource):
    body = {}
    params = data['params']
    user = data['user']

    partition = params.get('partition', None)
    query_instructions = params.get('query', [])
    start_key = params.get('start_key', None)
    limit = params.get('limit', 100)
    reverse = params.get('reverse', False)
    sort_key = params.get('sort_key', DEFAULT_SORT_KEY)
    if not sort_key:
        sort_key = DEFAULT_SORT_KEY
    join = params.get('join', {})
    projection_keys = params.get('projection_keys', None)

    if type(start_key) is str:
        start_key = json.loads(start_key)

    # 쿼리 유효성 검사
    policy_code = get_policy_code(resource, partition, 'query')
    if not match_policy(policy_code, user, query_instructions):
        body['items'] = None
        body['end_key'] = None
        body['error'] = error.QUERY_POLICY_VIOLATION
        return body

    # Join 유효성 검사
    policy_code = get_policy_code(resource, partition, 'join')
    if not match_policy(policy_code, user, join):
        body['items'] = None
        body['end_key'] = None
        body['error'] = error.JOIN_POLICY_VIOLATION
        return body

    if resource.db_has_partition(partition):
        index_keys = util.get_index_keys_to_index(resource, user, partition, 'r')
        items, end_key = resource.db_query(partition, query_instructions, start_key, limit,
                                           reverse, order_by=sort_key, index_keys=index_keys)
        policy_code = get_policy_code(resource, partition, 'read')
        filtered = []
        items = [item for item in items if item.get('id', None) and item.get('partition', None) == partition]
        for item in items:
            if match_policy(policy_code, user, item):
                filtered.append(item)

        if join:
            util.join_items(resource, user, filtered, join)

        items = [filter_projection_keys(item, projection_keys) for item in filtered]
        body['items'] = items
        body['end_key'] = end_key
        return body
    else:
        body['items'] = None
        body['end_key'] = None
        body['error'] = error.NO_SUCH_PARTITION
        return body
Beispiel #2
0
def do(data, resource):
    body = {}
    params = data['params']
    user = data['user']

    partition = params.get('partition', None)
    start_key = params.get('start_key', None)
    limit = params.get('limit', 100)
    reverse = params.get('reverse', False)

    if not limit:
        limit = 100

    if type(start_key) is str:
        start_key = json.loads(start_key)
    if resource.db_has_partition(partition):
        items, end_key = resource.db_get_items_in_partition(
            partition, start_key=start_key, limit=limit, reverse=reverse)
        policy_code = get_policy_code(resource, partition, 'read')
        filtered = []
        for item in items:
            if match_policy(policy_code, user, item):
                filtered.append(item)
        body['items'] = filtered
        body['end_key'] = end_key
        return body
    else:
        body['items'] = None
        body['end_key'] = None
        body['error'] = error.PERMISSION_DENIED
        return body
Beispiel #3
0
def do(data, resource):
    body = {}
    params = data['params']
    user = data['user']

    partition = params.get('partition', None)
    query_instructions = params.get('query', None)
    start_key = params.get('start_key', None)
    limit = params.get('limit', 100)
    reverse = params.get('reverse', False)

    if type(start_key) is str:
        start_key = json.loads(start_key)

    if resource.db_get_item(partition):
        items, end_key = resource.db_query(partition, query_instructions, start_key, limit, reverse)
        policy_code = get_policy_code(resource, partition, 'read')
        filtered = []
        for item in items:
            if match_policy(policy_code, user, item):
                filtered.append(item)

        body['items'] = filtered
        body['end_key'] = end_key
        return Response(body)
    else:
        body['items'] = None
        body['end_key'] = None
        body['error'] = error.NO_SUCH_PARTITION
        return Response(body)
Beispiel #4
0
def do(data, resource):
    body = {}
    params = data['params']
    user = data.get('user', None)

    if user:
        user_id = user.get('id', None)
    else:
        user_id = None

    partition = params.get('partition', None)
    max_workers = params.get('max_workers', None)

    if database_can_not_access_to_item(partition):
        body['error'] = error.PERMISSION_DENIED
        return body

    # Check partition has been existed
    if not resource.db_has_partition(partition):
        body['error'] = error.NO_SUCH_PARTITION
        return body

    items = params.get('items', [])
    error_list = [None] * len(items)
    item_ids = [None] * len(items)

    index_keys = util.get_index_keys_to_index(resource, user, partition, 'w')
    sort_keys = util.get_sort_keys(resource)
    policy_code = get_policy_code(resource, partition, 'create')

    def try_put_item(idx, item):
        item['id'] = uuid()
        if 'owner' not in item:
            item['owner'] = user_id
        item = {
            key: value
            for key, value in item.items()
            if value != '' and value != {} and value != []
        }
        if match_policy(policy_code, user, item):
            resource.db_put_item(partition,
                                 item,
                                 item_id=item['id'],
                                 index_keys=index_keys,
                                 sort_keys=sort_keys)
            item_ids[idx] = item.get('id', None)
        else:
            error_list[idx] = error.PERMISSION_DENIED

    if not max_workers:
        max_workers = len(items)
    max_workers = int(max_workers) + 1
    max_workers = min(32, max_workers)
    with ThreadPoolExecutor(max_workers=max_workers) as exc:
        for _idx, _item in enumerate(items):
            exc.submit(try_put_item, _idx, _item)

    body['error_list'] = error_list
    body['item_ids'] = item_ids
    return body
    def update_work(idx, item_id):
        new_item = pairs[item_id]
        item = resource.db_get_item(item_id)
        # 아이템 없는 경우
        if not item:
            error_list[idx] = error.NO_SUCH_ITEM
            return
        # 시스템 파티션 접근 제한
        if database_can_not_access_to_item(item['partition']):
            error_list[idx] = error.PERMISSION_DENIED
            return
        # 등록된 파티션이 아닌경우
        if item['partition'] not in partition_names:
            error_list[idx] = error.UNREGISTERED_PARTITION
            return

        if item['partition'] in policy_codes_by_partition:
            policy_code = policy_codes_by_partition[item['partition']]
        else:
            policy_code = get_policy_code(resource, item['partition'],
                                          'update')
            policy_codes_by_partition[item['partition']] = policy_code

        # Remove field if value is None
        # for key, value in new_item.copy().items():
        #     if value is None:
        #         new_item.pop(key)

        new_item = {
            key: value
            for key, value in new_item.items()
            if value != '' and value != {} and value != []
        }
        if use_simplify:
            new_item = util.simplify_item(item, new_item)
        new_item['partition'] = item.get('partition', None)
        new_item['creation_date'] = item.get('creation_date', None)

        if match_policy(policy_code, user, item, new_item=new_item):
            index_keys = util.get_index_keys_to_index(resource, user,
                                                      item['partition'], 'w')

            # 소트키는 무조건 업데이트시 포함해야함.
            for sort_key in sort_keys:
                s_key = sort_key.get('sort_key', None)
                if s_key and s_key not in new_item and item.get(
                        s_key, None) is not None:
                    new_item[s_key] = item.get(s_key, None)

            success = resource.db_update_item_v2(item_id,
                                                 new_item,
                                                 index_keys=index_keys,
                                                 sort_keys=sort_keys)
            success_list[idx] = success
        else:
            error_list[idx] = error.UPDATE_POLICY_VIOLATION
Beispiel #6
0
            def delete_item(item_id):
                item = resource.db_get_item(item_id)
                if item['partition'] in policy_codes_by_partition:
                    policy_code = policy_codes_by_partition[item['partition']]
                else:
                    policy_code = get_policy_code(resource, item['partition'],
                                                  'delete')
                    policy_codes_by_partition[item['partition']] = policy_code

                if item and match_policy(policy_code, user, item):
                    resource.db_delete_item(item_id)
Beispiel #7
0
def validate_policy(resource, user, joined_items, policy_code_cache):
    for idx, joined_item in enumerate(joined_items):
        partition = joined_item.get('partition')
        if partition in policy_code_cache:
            policy_code = policy_code_cache[partition]
        else:
            policy_code = get_policy_code(resource, partition, 'read')
            policy_code_cache[partition] = policy_code
        if not match_policy(policy_code, user, joined_item):
            joined_items[idx] = None
    return joined_items
    def get_item(idx, item_id):
        item = resource.db_get_item(item_id)

        # 시스템 파티션 접근 제한 읽기에선 허용.
        # if database_can_not_access_to_item(item['partition']):
        #     items_to_return[idx] = None
        #     errors[idx] = error.PERMISSION_DENIED
        #     return
        # 등록된 파티션이 아닌경우
        if not resource.db_has_partition(item['partition']):
            items_to_return[idx] = None
            errors[idx] = error.UNREGISTERED_PARTITION
            return

        if item['partition'] in read_policy_codes_by_partition:
            policy_code = read_policy_codes_by_partition[item['partition']]
        else:
            policy_code = get_policy_code(resource, item['partition'], 'read')
            read_policy_codes_by_partition[item['partition']] = policy_code

        if item and match_policy(policy_code, user, item):
            items_to_return[idx] = item
        else:
            errors[idx] = error.READ_POLICY_VIOLATION
            return

        # Join 유효성 검사
        if item['partition'] in join_policy_codes_by_partition:
            join_policy_code = join_policy_codes_by_partition[
                item['partition']]
        else:
            join_policy_code = get_policy_code(resource, item['partition'],
                                               'join')
            join_policy_codes_by_partition[
                item['partition']] = join_policy_code

        if match_policy(join_policy_code, user, join):
            util.join_item(resource, user, item, join)
        else:
            errors[idx] = error.JOIN_POLICY_VIOLATION
            return
Beispiel #9
0
def do(data, resource):
    body = {}
    params = data['params']
    user = data['user']

    item_id = params.get('item_id', None)
    join = params.get('join', {})
    if not item_id:
        body['item'] = None
        body['error'] = error.INVALID_ITEM_ID
        return body

    item = resource.db_get_item(item_id)

    if item is None:
        body['item'] = None
        body['error'] = error.NO_SUCH_ITEM
        return body

    # 등록된 파티션이 아닌경우
    if not resource.db_has_partition(item['partition']):
        body['item'] = None
        body['error'] = error.UNREGISTERED_PARTITION
        return body

    # Join 유효성 검사
    policy_code = get_policy_code(resource, item['partition'], 'join')
    if not match_policy(policy_code, user, join):
        body['item'] = None
        body['error'] = error.JOIN_POLICY_VIOLATION
        return body

    # 읽기 권한 검사
    if match_policy_after_get_policy_code(resource, 'read', item['partition'],
                                          user, item):
        if join:
            util.join_item(resource, user, item, join)
        body['item'] = item
    else:
        body['error'] = error.PERMISSION_DENIED

    return body
Beispiel #10
0
 def work_join(key, target):
     if '[]' in key:
         joined_item_ids = _get_joined_item_ids(item, key)
         if joined_item_ids:
             joined_items = fetch_joined_items(resource, joined_item_ids)
             joined_items = validate_policy(resource, user, joined_items, policy_code_cache)
             _put_joined_items(item, target, joined_items)
     else:
         joined_item_id = _get_joined_item_id(item, key)
         if joined_item_id:
             joined_item = resource.db_get_item(joined_item_id)
             if joined_item:
                 partition = joined_item.get('partition')
                 if partition in policy_code_cache:
                     policy_code = policy_code_cache[partition]
                 else:
                     policy_code = get_policy_code(resource, partition, 'read')
                     policy_code_cache[partition] = policy_code
                 if match_policy(policy_code, user, joined_item):
                     _put_joined_item(item, target, joined_item)
Beispiel #11
0
    def work_join(item_, key_, target_):
        if '[]' in key_:
            joined_item_ids_ = _get_joined_item_ids(item_, key_)
            if joined_item_ids_:
                joined_items = fetch_joined_items(resource, joined_item_ids_, joined_item_pairs)
                joined_items = validate_policy(resource, user, joined_items, policy_code_cache)
                _put_joined_items(item_, target_, joined_items)
        else:
            joined_item_id_ = _get_joined_item_id(item_, key_)
            if joined_item_id_:
                joined_item = joined_item_pairs[joined_item_id_]

                if joined_item:
                    partition = joined_item.get('partition')
                    if partition in policy_code_cache:
                        policy_code = policy_code_cache[partition]
                    else:
                        policy_code = get_policy_code(resource, partition, 'read')
                        policy_code_cache[partition] = policy_code
                    if match_policy(policy_code, user, joined_item):
                        _put_joined_item(item_, target_, joined_item)
Beispiel #12
0
def get_index_keys_to_index(resource, user, partition, mode):
    """
    인덱싱 할 키 목록 가져오기
    :param resource:
    :param user:
    :param partition:
    :param mode: 'r' | 'w' 읽기 / 쓰기
    :return:
    """
    policy_code = get_policy_code(resource, partition, 'index')
    index_keys = match_policy(policy_code, user, None)

    # 모드에 따라 인덱싱 키가 배정됨. 튜플일 경우만!
    if mode == 'r' and isinstance(index_keys, tuple) and len(index_keys) == 2:
        index_keys = index_keys[0]
    if mode == 'w' and isinstance(index_keys, tuple) and len(index_keys) == 2:
        index_keys = index_keys[1]

    if isinstance(index_keys, list):
        index_keys.extend(['partition'])
        index_keys = list(set(index_keys))
    return index_keys
    def delete_item(idx, item_id):
        item = resource.db_get_item(item_id)

        # 시스템 파티션 접근 제한
        if database_can_not_access_to_item(item['partition']):
            success_list[idx] = False
            return
        # 등록된 파티션이 아닌경우
        if not resource.db_has_partition(item['partition']):
            success_list[idx] = False
            return

        if item['partition'] in policy_codes_by_partition:
            policy_code = policy_codes_by_partition[item['partition']]
        else:
            policy_code = get_policy_code(resource, item['partition'],
                                          'delete')
            policy_codes_by_partition[item['partition']] = policy_code

        if item and match_policy(policy_code, user, item):
            success = resource.db_delete_item(item_id)
            success_list[idx] = success