Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of RFC 0072 - Pluggable transfer types #1930

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions invenio_rdm_records/services/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

Expand Down Expand Up @@ -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."""

Expand Down
32 changes: 23 additions & 9 deletions invenio_rdm_records/services/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
Expand All @@ -34,7 +40,6 @@
IfCreate,
IfDeleted,
IfExternalDOIRecord,
IfFileIsLocal,
IfNewRecord,
IfOneCommunity,
IfRecordDeleted,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()]
Expand Down
Loading