From 4fbfcf41c5f203545ce4a8b8c3f7e9ffb7cc8c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81bastien=20De=CC=81le=CC=80ze?= Date: Tue, 13 Jul 2021 08:20:46 +0200 Subject: [PATCH] documents: add `masked` property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds `marked` property to documents and hides masked documents on the public interface. * Closes #570. Co-Authored-by: Sébastien Délèze --- .../documents/document-v1.0.0_src.json | 14 +++++++++- .../v7/documents/document-v1.0.0.json | 3 ++ sonar/modules/documents/marshmallow/json.py | 1 + sonar/modules/documents/query.py | 3 ++ tests/api/documents/test_documents_query.py | 28 ++++++++++++++++++- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/sonar/modules/documents/jsonschemas/documents/document-v1.0.0_src.json b/sonar/modules/documents/jsonschemas/documents/document-v1.0.0_src.json index da170df0..d40edabf 100644 --- a/sonar/modules/documents/jsonschemas/documents/document-v1.0.0_src.json +++ b/sonar/modules/documents/jsonschemas/documents/document-v1.0.0_src.json @@ -1836,6 +1836,17 @@ "form": { "hide": true } + }, + "masked": { + "title": "Masked", + "type": "boolean", + "description": "A masked document is visible in the professional interface, but not in the public interface.", + "default": false, + "form": { + "expressionProperties": { + "templateOptions.required": "true" + } + } } }, "propertiesOrder": [ @@ -1866,7 +1877,8 @@ "oa_status", "customField1", "customField2", - "customField3" + "customField3", + "masked" ], "required": [ "$schema", diff --git a/sonar/modules/documents/mappings/v7/documents/document-v1.0.0.json b/sonar/modules/documents/mappings/v7/documents/document-v1.0.0.json index 5beef1b8..0b00d884 100644 --- a/sonar/modules/documents/mappings/v7/documents/document-v1.0.0.json +++ b/sonar/modules/documents/mappings/v7/documents/document-v1.0.0.json @@ -582,6 +582,9 @@ } } }, + "masked": { + "type": "boolean" + }, "_created": { "type": "date" }, diff --git a/sonar/modules/documents/marshmallow/json.py b/sonar/modules/documents/marshmallow/json.py index 2c94f61a..ce0a575a 100644 --- a/sonar/modules/documents/marshmallow/json.py +++ b/sonar/modules/documents/marshmallow/json.py @@ -105,6 +105,7 @@ class DocumentMetadataSchemaV1(StrictKeysMixin): customField1 = fields.List(fields.String(validate=validate.Length(min=1))) customField2 = fields.List(fields.String(validate=validate.Length(min=1))) customField3 = fields.List(fields.String(validate=validate.Length(min=1))) + masked = fields.Boolean() _bucket = SanitizedUnicode() _files = Nested(FileSchemaV1, many=True) _oai = fields.Dict() diff --git a/sonar/modules/documents/query.py b/sonar/modules/documents/query.py index 6c812adc..e9969b6d 100644 --- a/sonar/modules/documents/query.py +++ b/sonar/modules/documents/query.py @@ -81,6 +81,9 @@ def search_factory(self, search, query_parser=None): # Public search if view: + # Don't display masked records + search = search.filter('bool', must_not={'term': {'masked': True}}) + # Filter record by organisation view. if view != current_app.config.get('SONAR_APP_DEFAULT_ORGANISATION'): search = search.filter('term', organisation__pid=view) diff --git a/tests/api/documents/test_documents_query.py b/tests/api/documents/test_documents_query.py index 1511ae52..0203e04b 100644 --- a/tests/api/documents/test_documents_query.py +++ b/tests/api/documents/test_documents_query.py @@ -20,7 +20,7 @@ from flask import url_for -def test_collection_query(db, client, document, collection): +def test_collection_query(db, client, document, collection, es_clear): document['collections'] = [{ '$ref': 'https://sonar.ch/api/collections/{pid}'.format(pid=collection['pid']) @@ -36,3 +36,29 @@ def test_collection_query(db, client, document, collection): assert res.status_code == 200 assert res.json['hits']['total']['value'] == 1 assert not res.json['aggregations'].get('collection') + + +def test_masked_document(db, client, document, es_clear): + """Test masked document.""" + # Not masked (property not exists) + res = client.get(url_for('invenio_records_rest.doc_list', view='global')) + assert res.status_code == 200 + assert res.json['hits']['total']['value'] == 1 + + # Not masked + document['masked'] = False + document.commit() + document.reindex() + db.session.commit() + res = client.get(url_for('invenio_records_rest.doc_list', view='global')) + assert res.status_code == 200 + assert res.json['hits']['total']['value'] == 1 + + # Masked + document['masked'] = True + document.commit() + document.reindex() + db.session.commit() + res = client.get(url_for('invenio_records_rest.doc_list', view='global')) + assert res.status_code == 200 + assert res.json['hits']['total']['value'] == 0