From 118c4a9c2f25e263922de68b0e9befeb158862fd Mon Sep 17 00:00:00 2001 From: Mirek Simek Date: Sun, 19 Jan 2025 19:23:27 +0100 Subject: [PATCH] Implementation of RFC 0072 - Pluggable transfer types * IfFileIsLocal is not used anymore as it was handling just one type of transport * Switched to IfTransferType permission generators * Note: needs https://github.com/inveniosoftware/invenio-records-resources/pull/604 --- invenio_rdm_records/services/generators.py | 27 +---------------- invenio_rdm_records/services/permissions.py | 32 +++++++++++++++------ 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/invenio_rdm_records/services/generators.py b/invenio_rdm_records/services/generators.py index 154fddc09..c48acc9b9 100644 --- a/invenio_rdm_records/services/generators.py +++ b/invenio_rdm_records/services/generators.py @@ -3,6 +3,7 @@ # Copyright (C) 2021 Graz University of Technology. # Copyright (C) 2021-2024 CERN. # Copyright (C) 2021 TU Wien. +# Copyright (C) 2024 CESNET. # # Invenio-RDM-Records is free software; you can redistribute it and/or modify # it under the terms of the MIT License; see LICENSE file for more details. @@ -14,19 +15,15 @@ from functools import partial, reduce from itertools import chain -from flask import g from flask_principal import UserNeed -from invenio_communities.config import COMMUNITIES_ROLES from invenio_communities.generators import CommunityRoleNeed, CommunityRoles from invenio_communities.proxies import current_roles from invenio_records_permissions.generators import ConditionalGenerator, Generator -from invenio_records_resources.services.files.transfer import TransferType from invenio_search.engine import dsl from ..records import RDMDraft from ..records.systemfields.access.grants import Grant from ..records.systemfields.deletion_status import RecordDeletionStatusEnum -from ..requests import CommunityInclusion from ..requests.access import AccessRequestTokenNeed from ..tokens.permissions import RATNeed @@ -98,28 +95,6 @@ def _condition(self, record, **kwargs): return isinstance(record, RDMDraft) -class IfFileIsLocal(ConditionalGenerator): - """Conditional generator for file storage class.""" - - def _condition(self, record, file_key=None, **kwargs): - """Check if the file is local.""" - is_file_local = True - if file_key: - file_record = record.files.get(file_key) - # file_record __bool__ returns false for `if file_record` - file = file_record.file if file_record is not None else None - is_file_local = not file or file.storage_class == TransferType.LOCAL - else: - file_records = record.files.entries - for file_record in file_records: - file = file_record.file - if file and file.storage_class != TransferType.LOCAL: - is_file_local = False - break - - return is_file_local - - class IfNewRecord(ConditionalGenerator): """Conditional generator for cases where we have a new record/draft.""" diff --git a/invenio_rdm_records/services/permissions.py b/invenio_rdm_records/services/permissions.py index 6c89de5e2..8ae1e9b5c 100644 --- a/invenio_rdm_records/services/permissions.py +++ b/invenio_rdm_records/services/permissions.py @@ -3,6 +3,7 @@ # Copyright (C) 2019-2024 CERN. # Copyright (C) 2019 Northwestern University. # Copyright (C) 2023 TU Wien. +# Copyright (C) 2024 CESNET. # # Invenio-RDM-Records is free software; you can redistribute it and/or modify # it under the terms of the MIT License; see LICENSE file for more details. @@ -19,6 +20,11 @@ SystemProcess, ) from invenio_records_permissions.policies.records import RecordPermissionPolicy +from invenio_records_resources.services.files.generators import IfTransferType +from invenio_records_resources.services.files.transfer import ( + LOCAL_TRANSFER_TYPE, + MULTIPART_TRANSFER_TYPE, +) from invenio_requests.services.generators import Receiver, Status from invenio_requests.services.permissions import ( PermissionPolicy as RequestPermissionPolicy, @@ -34,7 +40,6 @@ IfCreate, IfDeleted, IfExternalDOIRecord, - IfFileIsLocal, IfNewRecord, IfOneCommunity, IfRecordDeleted, @@ -131,7 +136,8 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy): can_get_content_files = [ # note: even though this is closer to business logic than permissions, # it was simpler and less coupling to implement this as permission check - IfFileIsLocal(then_=can_read_files, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_read_files), + SystemProcess(), ] # Allow submitting new record can_create = can_authenticated @@ -151,15 +157,19 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy): can_draft_create_files = can_review can_draft_set_content_files = [ # review is the same as create_files - IfFileIsLocal(then_=can_review, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_review), + SystemProcess(), ] can_draft_get_content_files = [ # preview is same as read_files - IfFileIsLocal(then_=can_draft_read_files, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_draft_read_files), + SystemProcess(), ] can_draft_commit_files = [ # review is the same as create_files - IfFileIsLocal(then_=can_review, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_review), + IfTransferType(MULTIPART_TRANSFER_TYPE, can_review), + SystemProcess(), ] can_draft_update_files = can_review can_draft_delete_files = can_review @@ -255,15 +265,18 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy): can_draft_media_create_files = can_review can_draft_media_read_files = can_review can_draft_media_set_content_files = [ - IfFileIsLocal(then_=can_review, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_review), + SystemProcess(), ] can_draft_media_get_content_files = [ # preview is same as read_files - IfFileIsLocal(then_=can_preview, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_preview), + SystemProcess(), ] can_draft_media_commit_files = [ # review is the same as create_files - IfFileIsLocal(then_=can_review, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_review), + SystemProcess(), ] can_draft_media_update_files = can_review can_draft_media_delete_files = can_review @@ -278,7 +291,8 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy): can_media_get_content_files = [ # note: even though this is closer to business logic than permissions, # it was simpler and less coupling to implement this as permission check - IfFileIsLocal(then_=can_read, else_=[SystemProcess()]) + IfTransferType(LOCAL_TRANSFER_TYPE, can_read), + SystemProcess(), ] can_media_create_files = [Disable()] can_media_set_content_files = [Disable()]