From a58964db6a2eacbd91da057a7e1cea18560571fb Mon Sep 17 00:00:00 2001
From: Maximilian Johannes Moser <maximilian.moser@tuwien.ac.at>
Date: Thu, 12 Sep 2024 11:52:22 +0200
Subject: [PATCH] Update record permission policy

* fix preview permissions not granting access to the draft's files if
  they are restricted
* also refactor the permission levels for shared access (links & grants)
  to be easier to handle
* the latter unfortunately introduces duplicate generators in the policy
  and is thus a bit wasteful - if that turns out to be a problem, that
  should be updated in the future (e.g. via sets)
---
 invenio_config_tuw/permissions/policies.py | 31 ++++++++++++++++------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/invenio_config_tuw/permissions/policies.py b/invenio_config_tuw/permissions/policies.py
index 78a81cf..1b7cc02 100644
--- a/invenio_config_tuw/permissions/policies.py
+++ b/invenio_config_tuw/permissions/policies.py
@@ -54,11 +54,26 @@ def IfRestrictedAllowed(then_):
 
 
 secret_links = {
+    "manage": [],  # "manage" permissions can't be shared with links
     "edit": [SecretLinks("edit")],
     "view": [SecretLinks("edit"), SecretLinks("view")],
     "preview": [SecretLinks("edit"), SecretLinks("preview")],
 }
 
+access_grants = {
+    "manage": [AccessGrant("manage")],
+    "edit": [AccessGrant("manage"), AccessGrant("edit")],
+    "view": [AccessGrant("manage"), AccessGrant("edit"), AccessGrant("view")],
+    "preview": [AccessGrant("manage"), AccessGrant("edit"), AccessGrant("preview")],
+}
+
+shared_access = {
+    "manage": secret_links["manage"] + access_grants["manage"],
+    "edit": secret_links["edit"] + access_grants["edit"],
+    "view": secret_links["view"] + access_grants["view"],
+    "preview": secret_links["preview"] + access_grants["preview"],
+}
+
 
 class TUWRecordPermissionPolicy(RDMRecordPermissionPolicy):
     """Record permission policy of TU Wien."""
@@ -83,14 +98,14 @@ class TUWRecordPermissionPolicy(RDMRecordPermissionPolicy):
     #                         and get more permissive from top to bottom
     #
     # fmt: off
-    can_manage             = [TrustedRecordOwners(), RecordCommunitiesAction("curate"), AccessGrant("manage"), SystemProcess()      ]                            # noqa
-    can_access_draft       = can_manage       + [RecordOwners(), SubmissionReviewer(), AccessGrant("edit")                          ]                            # noqa
-    can_curate             = can_manage       + [AccessGrant("edit")                                                                ] + secret_links["edit"]     # noqa
-    can_review             = can_curate       + [SubmissionReviewer()                                                               ]                            # noqa
-    can_preview            = can_access_draft + [AccessGrant("preview"), UserManager                                                ] + secret_links["preview"]  # noqa
-    can_view               = can_access_draft + [AccessGrant("view"), RecordCommunitiesAction("view"), CommunityInclusionReviewers()] + secret_links["view"]     # noqa
-    can_authenticated      = [AuthenticatedUser(), SystemProcess()                                                                  ]                            # noqa
-    can_all                = [AnyUser(), SystemProcess()                                                                            ]                            # noqa
+    can_manage             = [TrustedRecordOwners(), RecordCommunitiesAction("curate"), SystemProcess()        ] + shared_access["manage"]   # noqa
+    can_access_draft       = can_manage       + [RecordOwners(), SubmissionReviewer()                          ] + shared_access["preview"]  # noqa
+    can_curate             = can_manage       + [                                                              ] + shared_access["edit"]     # noqa
+    can_review             = can_curate       + [SubmissionReviewer()                                          ]                             # noqa
+    can_preview            = can_access_draft + [UserManager                                                   ]                             # noqa
+    can_view               = can_access_draft + [RecordCommunitiesAction("view"), CommunityInclusionReviewers()] + shared_access["view"]     # noqa
+    can_authenticated      =                    [AuthenticatedUser(), SystemProcess()                          ]                             # noqa
+    can_all                =                    [AnyUser(), SystemProcess()                                    ]                             # noqa
 
     # records
     can_search                   = can_all                                                                                           # noqa
-- 
GitLab