diff --git a/api/handlers/dataexplorerhandler.py b/api/handlers/dataexplorerhandler.py index a6568ca05a6bd56b3069499008994a5bd0ee056b..1e47702e6a4b266b36f002afbe031841dfda0435 100644 --- a/api/handlers/dataexplorerhandler.py +++ b/api/handlers/dataexplorerhandler.py @@ -374,6 +374,9 @@ class DataExplorerHandler(base.RequestHandler): if not request.get('all_data', False) and not self.superuser_request: modified_filters.append({'term': {'permissions._id': self.uid}}) + # Only return objects that have not been marked as deleted + modified_filters.append({'term': {'deleted': False}}) + # Parse and "validate" search_string, allowed to be non-existent search_string = str(request.get('search_string', '')) @@ -412,9 +415,9 @@ class DataExplorerHandler(base.RequestHandler): field_name = self.request.json_body['field_name'] except (KeyError, ValueError): self.abort(400, 'Field name is required') - filters = [] + filters = [{'term': {'deleted': False}}] if not self.superuser_request: - filters = [{'term': {'permissions._id': self.uid}}] + filters.append({'term': {'permissions._id': self.uid}}) try: field = config.es.get(index='data_explorer_fields', id=field_name, doc_type='flywheel_field') except TransportError as e: diff --git a/tests/unit_tests/python/test_dataexplorer.py b/tests/unit_tests/python/test_dataexplorer.py index 5679d4d4f894fcf7f962d4ee9169e7363c4ab911..ed8717235bcbf0eef40f0a95b1865d5bde85ca86 100644 --- a/tests/unit_tests/python/test_dataexplorer.py +++ b/tests/unit_tests/python/test_dataexplorer.py @@ -47,7 +47,8 @@ def test_search(as_public, as_drone, es): 'must': {'match': {'_all': 'search'}}, 'filter': {'bool': {'must': [ {'terms': {filter_key + '.raw': filter_value}}, - {'range': filter_range} + {'range': filter_range}, + {'term': {'deleted': False}} ]}}, }}, 'aggs': {'by_container': {'terms': @@ -69,7 +70,11 @@ def test_search(as_public, as_drone, es): es.search.assert_called_with( body={ 'size': 0, - 'query': {'match_all': {}}, + 'query': {'bool': { + 'filter': {'bool': {'must': [ + {'term': {'deleted': False}} + ]}}, + }}, 'aggs': {'by_container': {'terms': {'field': cont_type + '._id', 'size': 100}, 'aggs': {'by_top_hit': {'top_hits': { @@ -89,7 +94,11 @@ def test_search(as_public, as_drone, es): es.search.assert_called_with( body={ 'size': 0, - 'query': {'match_all': {}}, + 'query': {'bool': { + 'filter': {'bool': {'must': [ + {'term': {'deleted': False}} + ]}}, + }}, 'aggs': {'by_container': {'terms': {'field': cont_type + '._id', 'size': 100}, 'aggs': {'by_top_hit': {'top_hits': { @@ -113,7 +122,12 @@ def test_search(as_public, as_drone, es): es.search.assert_called_with( body={ '_source': deh.SOURCE[cont_type], - 'query': {'bool': {'filter': {'bool': {'must': [{'term': {'container_type': cont_type}}]}}}}, + 'query': {'bool': { + 'filter': {'bool': {'must': [ + {'term': {'container_type': cont_type}}, + {'term': {'deleted': False}} + ]}}, + }}, 'script_fields': {'info_exists': deh.INFO_EXISTS_SCRIPT}, 'size': 100}, doc_type='flywheel', @@ -136,6 +150,7 @@ def test_search(as_public, as_drone, es): {'term': {'container_type': cont_type}}, {'terms': {filter_key + '.raw': filter_value}}, {'range': filter_range}, + {'term': {'deleted': False}} ]}} }}, 'script_fields': {'info_exists': deh.INFO_EXISTS_SCRIPT}, @@ -160,6 +175,7 @@ def test_search(as_public, as_drone, es): {'term': {'container_type': cont_type}}, {'terms': {filter_key + '.raw': filter_value}}, {'range': filter_range}, + {'term': {'deleted': False}} ]}} }}, 'script_fields': {'info_exists': deh.INFO_EXISTS_SCRIPT}, @@ -199,7 +215,8 @@ def test_search(as_public, as_drone, es): {'terms': {filter_key + '.raw': [filter_value]}} ] } - } + }, + {'term': {'deleted': False}} ]}} }}, 'script_fields': {'info_exists': deh.INFO_EXISTS_SCRIPT}, @@ -233,6 +250,7 @@ def test_search(as_public, as_drone, es): 'filter': {'bool': {'must': [ {'term': {'container_type': cont_type}}, {'terms': {filter_key + '.raw': filter_value}}, + {'term': {'deleted': False}} ]}} }}, 'script_fields': {'info_exists': deh.INFO_EXISTS_SCRIPT}, @@ -411,7 +429,9 @@ def test_aggregate_field_values(as_public, as_drone, es): r = as_drone.post('/dataexplorer/search/fields/aggregate', json={'field_name': field_name}) es.search.assert_called_with( body={'aggs': {'results': {'terms': {'field': field_name + '.raw', 'size': 15, 'missing': 'null'}}}, - 'query': {'bool': {'must': {'match_all': {}}}}, + 'query': {'bool': { + 'filter': [{'term': {'deleted': False}}], + 'must': {'match_all': {}}}}, 'size': 0}, doc_type='flywheel', index='data_explorer') @@ -422,7 +442,9 @@ def test_aggregate_field_values(as_public, as_drone, es): r = as_drone.post('/dataexplorer/search/fields/aggregate', json={'field_name': field_name, 'search_string': search_str}) es.search.assert_called_with( body={'aggs': {'results': {'terms': {'field': field_name + '.raw', 'size': 15, 'missing': 'null'}}}, - 'query': {'bool': {'must': {'match': {'field': search_str}}}}, + 'query': {'bool': { + 'filter': [{'term': {'deleted': False}}], + 'must': {'match': {'field': search_str}}}}, 'size': 0}, doc_type='flywheel', index='data_explorer') @@ -434,7 +456,9 @@ def test_aggregate_field_values(as_public, as_drone, es): r = as_drone.post('/dataexplorer/search/fields/aggregate', json={'field_name': field_name}) es.search.assert_called_with( body={'aggs': {'results': {'stats': {'field': field_name}}}, - 'query': {'bool': {'must': {'match_all': {}}}}, + 'query': {'bool': { + 'filter': [{'term': {'deleted': False}}], + 'must': {'match_all': {}}}}, 'size': 0}, doc_type='flywheel', index='data_explorer') @@ -445,7 +469,9 @@ def test_aggregate_field_values(as_public, as_drone, es): r = as_drone.post('/dataexplorer/search/fields/aggregate', json={'field_name': field_name, 'search_string': search_str}) es.search.assert_called_with( body={'aggs': {'results': {'stats': {'field': field_name}}}, - 'query': {'bool': {'must': {'match': {'field': search_str}}}}, + 'query': {'bool': { + 'filter': [{'term': {'deleted': False}}], + 'must': {'match': {'field': search_str}}}}, 'size': 0}, doc_type='flywheel', index='data_explorer')