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
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
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)
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
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)
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
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
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
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)
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)
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