Remove obsolete worklist-modify ACL exemption: local Modify no longer required

Removes the "worklist exemption" workaround from _fetch_patient_policy, the last piece of a chain of changes across four repos that removes worklist creation/update's dependency on local Modify permission. Also includes an unrelated Dockerfile.local local-build fix found while rebuilding this plugin to test the change.

Background

Worklist operations (POST/PUT to /studies/{id}/worklists/{wid}) previously required both the server/group-level worklist permission and local Modify on the study. That dependency was never a deliberate security decision — it was a side effect of how the Orthanc Advanced Authorization plugin explodes a nested resource request into its full patient → study ancestor hierarchy and requires every level to independently authorize the same method.

Under the plugin's IncludeResourceUri option, only the leaf (study) resource carries the request URI; the patient-ancestor call arrived with an empty resource and no signal distinguishing "this is a worklist request" from "this is a genuine modify request." So the ancestor call fell through to the generic modify-traversal branch, and _fetch_patient_policy's "worklist exemption" papered over the gap: if the local study ACL had Modify: True and the group's global policy had worklist: True, it granted the patient a Modify permission the user never actually had, purely to satisfy that ancestor-traversal requirement.

Modify is documented as "Modify DICOM resources on the server" — the ability to directly edit DICOM tag/pixel data, a distinct and far more powerful capability than reviewing or working a worklist item. The old docstring even carried a TODO acknowledging this: "Add URI to the request made by the authorization plugin so it is possible to understand which resource is being requested and ONLY provide the modify permission for worklist requests."

What changed here

sonador_orthanc/auth/web.py — removed the "worklist exemption" block from _fetch_patient_policy (the code that inspected the global worklist permission and conditionally set policy[ACL_PERM_MODIFY] = True). Updated the surrounding docstrings and the module-level ACL_PERM_MODIFY_TRAVERSE docblock to describe the new mechanism instead of the retired workaround. No other behavior changes — the rest of _fetch_patient_policy (view propagation, direct patient-ACL modify/remove, and the ancestor-traversal flags for genuine modify/remove requests) is untouched.

Dockerfile.local — while rebuilding this plugin locally to verify the fix above, the build stage failed during CMake configure: -DUSE_SYSTEM_GOOGLE_TEST=OFF forces CMake to download and extract gtest-1.8.1.tar.gz, and that tar extraction failed uniformly (Cannot open: Function not implemented, i.e. ENOSYS) on a host with an older kernel. The build stage's base image (orthancteam/orthanc:26.6.1-full, built for GCC 15/Python 3.14) ships a glibc that unconditionally issues the fchmodat2 syscall (Linux ≥6.6 only) while tar restores permissions; on older host kernels that syscall doesn't exist and the kernel returns ENOSYS for it. Containers share the host kernel, so no in-container package or flag can add a missing syscall — the fix is to avoid needing it: added googletest/libgtest-dev to the apt-get install list and switched USE_SYSTEM_GOOGLE_TEST to ON, so CMake links the system Google Test instead of downloading/extracting it. This mirrors the same working pattern already used by the sibling orthanc-s3 Dockerfile. No change to the runtime stage or the compiled plugin's behavior.

Companion changes (other repos, already merged/pushed)

  • orthanc-authorization (C++ plugin) — DefaultAuthorizationParser::ClassifyAction() now recognizes the worklists path segment and tags the request action="worklist", mirroring the existing "comments""comment" handling. This is the source of the token this fix depends on. Already on master as commit 7ac8fb1.
  • oak-tree/medical-imaging/sonador!90 (lib/orthancapi) — ResourceAuthorization.resource_perm()'s new branch that resolves the action="worklist" ancestor call via ordinary view instead of the generic modify-traversal check. This MR's fix only makes sense once that branch exists — without it, the ancestor call would fall through with nothing granting it, and worklist requests would start failing entirely rather than just requiring Modify.
  • oak-tree/medical-imaging/sonador-client!73 and oak-tree/medical-imaging/sonador-ftests!12 — functional-test updates proving a user with local View (and Modify explicitly False) can create and update worklist items, where the same tests previously asserted a 403.
  • oak-tree/medical-imaging/orthanc-sonador#54 (originating feature work; this fix was uncovered while reviewing that feature's ACL model)
Edited by Sonador Claude

Merge request reports

Loading