diff --git a/sonar/modules/config.py b/sonar/modules/config.py index 2cf87c97..a2ba24c5 100644 --- a/sonar/modules/config.py +++ b/sonar/modules/config.py @@ -47,3 +47,9 @@ command line or progams like postman.""" SONAR_APP_UI_VERSION = '0.1.11' + +SONAR_APP_INTERNAL_IPS = ['127.0.0.1'] +"""Internal IPs for accessing files.""" + +SONAR_APP_DEFAULT_ORGANISATION = 'sonar' +"""Default organisation key.""" diff --git a/sonar/modules/documents/cli/rerodoc.py b/sonar/modules/documents/cli/rerodoc.py index 020b1b8c..b238dbc5 100644 --- a/sonar/modules/documents/cli/rerodoc.py +++ b/sonar/modules/documents/cli/rerodoc.py @@ -58,7 +58,6 @@ def save_records(ids): indexer.bulk_index(ids) indexer.process_bulk_queue() - click.secho(permissions_file.name) try: with open(permissions_file.name, 'r') as file: reader = csv.reader(file, delimiter=';') diff --git a/sonar/modules/documents/marshmallow/json.py b/sonar/modules/documents/marshmallow/json.py index 53867d4a..3065caa6 100644 --- a/sonar/modules/documents/marshmallow/json.py +++ b/sonar/modules/documents/marshmallow/json.py @@ -22,7 +22,9 @@ from invenio_records_rest.schemas import StrictKeysMixin from invenio_records_rest.schemas.fields import PersistentIdentifier, \ SanitizedUnicode -from marshmallow import fields +from marshmallow import fields, pre_dump + +from sonar.modules.documents.views import is_file_restricted class DocumentMetadataSchemaV1(StrictKeysMixin): @@ -49,6 +51,29 @@ class DocumentMetadataSchemaV1(StrictKeysMixin): identifiedBy = fields.List(fields.Dict()) subjects = fields.List(fields.Dict()) + @pre_dump + def add_files_restrictions(self, item): + """Add restrictions to file before dumping data. + + :param item: Item object to process + :returns: Modified item + """ + if not item.get('_files'): + return item + + for key, file in enumerate(item['_files']): + if file['type'] == 'file': + restricted = is_file_restricted(file, item) + + # Format date before serialization + if restricted.get('date'): + restricted['date'] = restricted['date'].strftime( + '%Y-%m-%d') + + item['_files'][key]['restricted'] = restricted + + return item + class DocumentSchemaV1(StrictKeysMixin): """Document schema.""" diff --git a/sonar/modules/documents/views.py b/sonar/modules/documents/views.py index 15cf0abe..6478bc85 100644 --- a/sonar/modules/documents/views.py +++ b/sonar/modules/documents/views.py @@ -20,8 +20,9 @@ from __future__ import absolute_import, print_function import re +from datetime import datetime -from flask import Blueprint, current_app, g, render_template +from flask import Blueprint, current_app, g, render_template, request from flask_babelex import gettext as _ from sonar.modules.utils import change_filename_extension @@ -280,6 +281,45 @@ def part_of_format(part_of): return ', '.join(items) +@blueprint.app_template_filter() +def is_file_restricted(file, record): + """Check if current file can be displayed. + + :param file: File dict + :param record: Current record + :returns object containing result and possibly embargo date + """ + restricted = {'restricted': False, 'date': None} + + try: + embargo_date = datetime.strptime(file.get('embargo_date'), '%Y-%m-%d') + except Exception: + embargo_date = None + + # Store embargo date if greater than now + if embargo_date and embargo_date > datetime.now(): + restricted['restricted'] = True + restricted['date'] = embargo_date + + # File is restricted by institution + if file.get('restricted'): + if file['restricted'] in ['rero', 'internal']: + result = request.remote_addr not in current_app.config.get( + 'SONAR_APP_INTERNAL_IPS') + restricted['restricted'] = result + else: + # compare with current organisation + organisation = get_current_organisation() + restricted['restricted'] = organisation == current_app.config.get( + 'SONAR_APP_DEFAULT_ORGANISATION' + ) or organisation != record['institution']['pid'] + + if not restricted['restricted']: + restricted['date'] = None + + return restricted + + def get_language_from_bibliographic_code(language_code): """Return language code from bibliographic language. @@ -327,3 +367,15 @@ def get_preferred_languages(force_language=None): preferred_languages.insert(0, force_language) return list(dict.fromkeys(preferred_languages)) + + +def get_current_organisation(): + """Return current organisation by globals or query parameter.""" + organisation = request.args.get('view') + if organisation: + return organisation + + if g.get('ir'): + return g.ir + + return None diff --git a/sonar/theme/static/images/restricted.png b/sonar/theme/static/images/restricted.png new file mode 100644 index 00000000..bfc12f16 Binary files /dev/null and b/sonar/theme/static/images/restricted.png differ diff --git a/sonar/theme/templates/sonar/macros/macro.html b/sonar/theme/templates/sonar/macros/macro.html index 985d667a..f43113ad 100644 --- a/sonar/theme/templates/sonar/macros/macro.html +++ b/sonar/theme/templates/sonar/macros/macro.html @@ -68,6 +68,8 @@ {% set file_title = file | file_title %} {% set externalUrl = record | has_external_urls_for_files %}
{{ file_title }}
+ {% if restricted.date %} + + {{ _('Public access from') }} {{ restricted.date.strftime('%d/%m/%Y') }} + + {% endif %} + {% endif %}