# -*- coding: utf-8 -*- # # Copyright (C) 2020-2024 Graz University of Technology. # Copyright (C) 2025 I-Form Advanced Manufacturing Research Centre. # # invenio-config-iform is free software; you can redistribute it and/or # modify it under the terms of the MIT License; see LICENSE file for more # details. """I-Form permission-policy for RDMRecordService. To use, set config-variable `RDM_PERMISSION_POLICY` to `IformRDMRecordPermissionPolicy`. Policies list **what actions** can be done **by whom** over an implied category of objects (typically records). A Policy is instantiated on a per action basis and is a descendant of `Permission `_ in `invenio-access `_ . Generators are used to provide the "by whom" part and the implied category of object. Actions are class variables of the form: ``can_`` and the corresponding (dis-)allowed identities are a list of Generator instances. One can define any action as long as it follows that pattern and is verified at the moment it is undertaken. """ from invenio_administration.generators import Administration from invenio_communities.generators import CommunityCurators from invenio_rdm_records.services.generators import ( AccessGrant, CommunityInclusionReviewers, IfAtLeastOneCommunity, IfDeleted, IfExternalDOIRecord, IfFileIsLocal, IfNewRecord, IfOneCommunity, IfRecordDeleted, IfRestricted, RecordCommunitiesAction, RecordOwners, ResourceAccessToken, SecretLinks, SubmissionReviewer, ) from invenio_records_permissions.generators import AnyUser, Disable, IfConfig, SystemProcess from invenio_records_permissions.policies.records import RecordPermissionPolicy from invenio_users_resources.services.permissions import UserManager from .generators import AllowedFromIPNetwork, IformAuthenticatedUser, RecordSingleIP class IformRDMRecordPermissionPolicy(RecordPermissionPolicy): """Overwrite authenticatedness to mean `iform_authenticated` rather than *signed up*.""" NEED_LABEL_TO_ACTION = { "bucket-update": "update_files", "bucket-read": "read_files", "object-read": "read_files", } # # General permission-groups, to be used below # can_manage = [ RecordOwners(), RecordCommunitiesAction("curate"), AccessGrant("manage"), SystemProcess(), ] can_manage_internal = [SystemProcess()] can_curate = can_manage + [AccessGrant("edit"), SecretLinks("edit")] can_review = can_curate + [SubmissionReviewer()] can_preview = can_curate + [ AccessGrant("preview"), SecretLinks("preview"), SubmissionReviewer(), UserManager, ] can_view = can_preview + [ AccessGrant("view"), SecretLinks("view"), SubmissionReviewer(), CommunityInclusionReviewers(), RecordCommunitiesAction("view"), AllowedFromIPNetwork(), RecordSingleIP(), ] can_iform_authenticated = [IformAuthenticatedUser(), SystemProcess()] can_authenticated = can_iform_authenticated can_all = [ AnyUser(), SystemProcess(), AllowedFromIPNetwork(), RecordSingleIP(), ] # # Miscellaneous # # Allow for querying of statistics # - This is currently disabled because it's not needed and could potentially # open up surface for denial of service attacks can_query_stats = [Disable()] # # Records - reading and creating # can_search = can_all can_search_revisions = [Administration()] can_read = [IfRestricted("record", then_=can_view, else_=can_all)] can_read_deleted = [ IfRecordDeleted(then_=[UserManager, SystemProcess()], else_=can_read), ] can_read_deleted_files = can_read_deleted can_media_read_deleted_files = can_read_deleted_files can_read_files = [ IfRestricted("files", then_=can_view, else_=can_all), ResourceAccessToken("read"), ] can_get_content_files = [ IfFileIsLocal(then_=can_read_files, else_=[SystemProcess()]), ] can_create = can_iform_authenticated # # Drafts # can_search_drafts = can_iform_authenticated can_read_draft = can_preview can_draft_read_files = can_preview + [ResourceAccessToken("read")] can_update_draft = can_review can_draft_create_files = can_review can_draft_set_content_files = [ IfFileIsLocal(then_=can_review, else_=[SystemProcess()]), ] can_draft_get_content_files = [ IfFileIsLocal(then_=can_draft_read_files, else_=[SystemProcess()]), ] can_draft_commit_files = [IfFileIsLocal(then_=can_review, else_=[SystemProcess()])] can_draft_update_files = can_review can_draft_delete_files = can_review can_manage_files = [ IfConfig( "RDM_ALLOW_METADATA_ONLY_RECORDS", then_=[IfNewRecord(then_=can_iform_authenticated, else_=can_review)], else_=[], ), ] can_manage_record_access = [ IfConfig( "RDM_ALLOW_RESTRICTED_RECORDS", then_=[IfNewRecord(then_=can_iform_authenticated, else_=can_review)], else_=[], ), ] # # PIDs # can_pid_create = can_review can_pid_register = can_review can_pid_update = can_review can_pid_discard = can_review can_pid_delete = can_review can_pid_manage = [SystemProcess()] # # Actions # can_edit = [IfDeleted(then_=[Disable()], else_=can_curate)] can_delete_draft = can_curate can_new_version = [ IfConfig( "RDM_ALLOW_EXTERNAL_DOI_VERSIONING", then_=can_curate, else_=[IfExternalDOIRecord(then_=[Disable()], else_=can_curate)], ), ] can_publish = [ IfConfig( "RDM_COMMUNITY_REQUIRED_TO_PUBLISH", then_=[ IfAtLeastOneCommunity( then_=can_review, else_=[Administration(), SystemProcess()], ), ], else_=can_review, ), ] can_lift_embargo = can_manage # # Record communities # can_add_community = can_manage can_remove_community_ = [RecordOwners(), CommunityCurators(), SystemProcess()] can_remove_community = [ IfConfig( "RDM_COMMUNITY_REQUIRED_TO_PUBLISH", then_=[ IfOneCommunity( then_=[Administration(), SystemProcess()], else_=can_remove_community_, ), ], else_=can_remove_community_, ), ] can_remove_record = [CommunityCurators(), Administration(), SystemProcess()] can_bulk_add = [SystemProcess()] # # Media files - draft # 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()]), ] can_draft_media_get_content_files = [ IfFileIsLocal(then_=can_preview, else_=[SystemProcess()]), ] can_draft_media_commit_files = [ IfFileIsLocal(then_=can_preview, else_=[SystemProcess()]), ] can_draft_media_delete_files = can_review can_draft_media_update_files = can_review # # Media files - record # can_media_read_files = [ IfRestricted("record", then_=can_view, else_=can_all), ResourceAccessToken("read"), ] can_media_get_content_files = [ IfFileIsLocal(then_=can_read, else_=[SystemProcess()]), ] can_media_create_files = [Disable()] can_media_set_content_files = [Disable()] can_media_commit_files = [Disable()] can_media_update_files = [Disable()] can_media_delete_files = [Disable()] # # Record deletetion # can_delete = [Administration(), SystemProcess()] can_delete_files = [SystemProcess()] can_purge = [SystemProcess()] # # Quotas for records/users # can_manage_quota = [UserManager, SystemProcess()] # # Disabled # # - Records/files are updated/deleted via drafts so we don't support # using below actions. can_update = [Disable()] can_create_files = [Disable()] can_set_content_files = [Disable()] can_commit_files = [Disable()] can_update_files = [Disable()] # Used to hide at the moment the `parent.is_verified` field. It should be set to # correct permissions based on which the field will be exposed only to moderators can_moderate = [Disable()]