Skip to content

Commit cbc524c

Browse files
docs(events): describe the paginated share-review source API
Document the Nextcloud 36 additions to the share-review events: the IPaginatedShareReviewSource interface collected through RegisterShareReviewSourceEvent (page-wise listing with sorting, search, filters and counts, keyed lookup, localized label, optional remediation and snapshot capabilities) and the action, acting user and scope carried by ShareReviewAccessCheckEvent. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
1 parent fadd9f1 commit cbc524c

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

developer_manual/basics/_available_events_ocp.rst

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,13 +828,30 @@ Event that allows to register a feature policy header to a request.
828828

829829
.. versionadded:: 34.0.2
830830

831-
Authorization gate for deleting an app-managed share through a share-review app. Dispatched by the app that owns
831+
Authorization gate for acting on an app-managed share through a share-review app. Dispatched by the app that owns
832832
the share (its ``OCP\Share\ShareReview\IShareReviewSource`` implementation) at the beginning of ``deleteShare()``,
833833
before anything is deleted. The share-review app listens to this event and answers with ``grantAccess()`` or
834834
``denyAccess()`` depending on whether the current user is an authorized share-review operator; apps that merely
835835
expose shares must not listen to it. The event is default-deny: if no listener responds, the share must not be
836836
deleted. Once denied, further grants are ignored and event propagation is stopped.
837837

838+
.. versionchanged:: 36
839+
840+
The event carries the operation being authorized (``getAction()``: ``ACTION_DELETE``, ``ACTION_REMEDIATE`` for
841+
the password/expiration mutators of ``OCP\Share\ShareReview\IShareReviewSourceRemediation``, ``ACTION_RESTORE``
842+
for ``OCP\Share\ShareReview\IShareReviewSourceSnapshot::restoreShare()``), the acting user (``getActingUserId()``,
843+
``null`` for the session user) and the scope (``getScope()``: ``SCOPE_OPERATOR`` for an instance-wide review,
844+
``SCOPE_SELF`` for a user reviewing their own shares, where the listener must additionally verify that the acting
845+
user is the share's initiator). The acting user and the scope reach the owning app through an optional
846+
``OCP\Share\ShareReview\ShareReviewActionContext`` that the share-review app passes to ``deleteShare()`` and to
847+
the mutators of the two capability interfaces; the owning app forwards both values into this event verbatim and
848+
never decides them itself. Passing no context means the session user acts as an operator, exactly as in 34.0.2.
849+
Listeners written against the 34.0.2 event keep working and keep failing closed
850+
for non-operators — but for operators the new actions extend the granted capability set: ``ACTION_REMEDIATE``
851+
includes removing a link share's password, which can expose content deletion never could. A listener that
852+
distinguishes reviewers with delete-only rights must check ``getAction()`` and deny actions it does not
853+
recognize.
854+
838855
``OCP\Share\ShareReview\RegisterShareReviewSourceEvent``
839856
********************************************************
840857

@@ -844,6 +861,34 @@ Event dispatched by a share-review app to collect share sources from other apps.
844861
of their ``OCP\Share\ShareReview\IShareReviewSource`` implementation, whose ``getShares()`` method returns a list of
845862
``OCP\Share\ShareReview\ShareReviewEntry`` objects.
846863

864+
.. versionchanged:: 36
865+
866+
Sources with many shares should implement ``OCP\Share\ShareReview\IPaginatedShareReviewSource`` instead, which
867+
extends ``IShareReviewSource`` and lists shares page by page: ``queryShares()`` takes an
868+
``OCP\Share\ShareReview\ShareReviewQuery`` (page size and offset, sort field and direction, a case-insensitive
869+
substring search across object, initiator and recipient, and filters for share types, password protection,
870+
expiration date and range, modification range, scoped identity substrings, exact initiator, recipient and access
871+
token lists, and opaque permission ids) and returns an ``OCP\Share\ShareReview\ShareReviewPage`` carrying the
872+
entries and the total and filtered counts (``ShareReviewCounts``); ``countShares()``, ``countSharesByType()`` and
873+
``countSharesByInitiator()`` return counts without rows, ``getShare()`` looks a single share up by its deletion
874+
identifier, and ``getDisplayName()`` provides a localized label while ``getName()`` stays a stable, untranslated
875+
identifier. The share-review app detects the paginated interface with ``instanceof`` and falls back to
876+
``getShares()`` otherwise.
877+
878+
The contract is identical for every source, so a share-review app can offer the same table controls on every tab.
879+
An implementation evaluates it in the database rather than in PHP and must honour the rules the interface
880+
docblocks state: append the primary key as a secondary sort so equal-keyed rows never straddle a page boundary,
881+
order NULL sort keys last in both directions, escape LIKE wildcards in every substring input, compare access
882+
tokens exactly (never as a prefix — they are bearer credentials), treat an empty list filter as matching nothing,
883+
and answer the grouped counts with a single ``GROUP BY`` scan rather than a count per group.
884+
885+
Two optional capability interfaces can be implemented alongside: ``IShareReviewSourceRemediation`` sets or removes
886+
passwords and expiration dates (declared per source through ``canSetPassword()`` and ``canSetExpiration()``;
887+
because only link and mail shares carry them, a mutator called for an entry of any other type returns ``false``
888+
without dispatching the access check), and ``IShareReviewSourceSnapshot`` serializes a share before deletion and
889+
restores it later from that opaque, app-owned string. Both are discovered with ``instanceof`` and gated by the
890+
access-check event with ``ACTION_REMEDIATE`` and ``ACTION_RESTORE`` respectively.
891+
847892
``OCP\SpeechToText\Events\TranscriptionFailedEvent``
848893
****************************************************
849894

0 commit comments

Comments
 (0)