From 51994bed00c74d93ceac758c1fd002aa0feb86c6 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Tue, 24 Feb 2026 06:45:00 +0100 Subject: [PATCH] sharing: add support for report --- radicale/app/report.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/radicale/app/report.py b/radicale/app/report.py index 526cb4d8..0ec79357 100644 --- a/radicale/app/report.py +++ b/radicale/app/report.py @@ -25,6 +25,7 @@ import contextlib import copy import datetime +import logging import posixpath import socket import xml.etree.ElementTree as ET @@ -149,14 +150,15 @@ def free_busy_report(base_prefix: str, path: str, xml_request: Optional[ET.Eleme def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element], collection: storage.BaseCollection, encoding: str, unlock_storage_fn: Callable[[], None], - max_occurrence: int = 0, user: str = "", remote_addr: str = "", remote_useragent: str = "" - ) -> Tuple[int, ET.Element]: + max_occurrence: int = 0, user: str = "", remote_addr: str = "", remote_useragent: str = "", + sharing: Union[dict, None] = None) -> Tuple[int, ET.Element]: """Read and answer REPORT requests that return XML. Read rfc3253-3.6 for info. """ - logger.debug("TRACE/REPORT/xml_report: base_prefix=%r path=%r", base_prefix, path) + if logger.isEnabledFor(logging.DEBUG): + logger.debug("TRACE/REPORT/xml_report: base_prefix=%r path=%r", base_prefix, path) multistatus = ET.Element(xmlutils.make_clark("D:multistatus")) if xml_request is None: return client.MULTI_STATUS, multistatus @@ -354,7 +356,7 @@ def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element], if found_props or not_found_props: multistatus.append(xml_item_response( base_prefix, uri, found_props=found_props, - not_found_props=not_found_props, found_item=True)) + not_found_props=not_found_props, found_item=True, sharing=sharing)) return client.MULTI_STATUS, multistatus @@ -705,11 +707,13 @@ def _find_overridden( def xml_item_response(base_prefix: str, href: str, found_props: Sequence[ET.Element] = (), not_found_props: Sequence[ET.Element] = (), - found_item: bool = True) -> ET.Element: + found_item: bool = True, sharing: Union[dict, None] = None) -> ET.Element: response = ET.Element(xmlutils.make_clark("D:response")) href_element = ET.Element(xmlutils.make_clark("D:href")) href_element.text = xmlutils.make_href(base_prefix, href) + if sharing: + href_element.text = href_element.text.replace(sharing['PathMapped'], sharing['PathOrToken']) response.append(href_element) if found_item: @@ -811,6 +815,15 @@ class ApplicationPartReport(ApplicationBase): path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage REPORT request.""" permissions_filter = None + sharing = None + if self._sharing._enabled: + # Sharing by token or map (if enabled) + sharing = self._sharing.sharing_collection_resolver(path, user) + if sharing: + # overwrite and run through extended permission check + path = sharing['PathMapped'] + user = sharing['Owner'] + permissions_filter = sharing['Permissions'] access = Access(self._rights, user, path, permissions_filter) if not access.check("r"): return httputils.NOT_ALLOWED @@ -853,7 +866,7 @@ class ApplicationPartReport(ApplicationBase): try: status, xml_answer = xml_report( base_prefix, path, xml_content, collection, self._encoding, - lock_stack.close, max_occurrence, user, remote_host, remote_useragent) + lock_stack.close, max_occurrence, user, remote_host, remote_useragent, sharing=sharing) except ValueError as e: logger.warning( "Bad REPORT request on %r: %s", path, e, exc_info=True)