From 1ff4c6ca0340e296f075ab5daf80c44bc76bd20c Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 19 Jul 2026 11:04:46 +0200 Subject: [PATCH] sharing: share-by-group: add share resolution for other methods beside propfind --- radicale/app/delete.py | 6 +++++- radicale/app/get.py | 7 +++++-- radicale/app/move.py | 12 +++++++++--- radicale/app/propfind.py | 5 ++++- radicale/app/proppatch.py | 5 ++++- radicale/app/put.py | 9 ++++++--- radicale/app/report.py | 7 +++++-- 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/radicale/app/delete.py b/radicale/app/delete.py index c1594fbb..69fd54e6 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -23,7 +23,7 @@ from http import client from typing import Optional, Union from urllib.parse import quote -from radicale import httputils, storage, types, xmlutils +from radicale import httputils, sharing, storage, types, xmlutils from radicale.app.base import Access, ApplicationBase from radicale.hook import HookNotificationItem, HookNotificationItemTypes from radicale.log import logger @@ -71,6 +71,10 @@ class ApplicationPartDelete(ApplicationBase): if self._sharing._enabled: # Sharing by token or map (if enabled) share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] diff --git a/radicale/app/get.py b/radicale/app/get.py index 542ff4d2..47f6b63c 100644 --- a/radicale/app/get.py +++ b/radicale/app/get.py @@ -23,7 +23,7 @@ from http import client from typing import Union from urllib.parse import quote -from radicale import httputils, pathutils, storage, types, xmlutils +from radicale import httputils, pathutils, sharing, storage, types, xmlutils from radicale.app.base import Access, ApplicationBase from radicale.log import logger @@ -89,7 +89,10 @@ class ApplicationPartGet(ApplicationBase): share = None if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] diff --git a/radicale/app/move.py b/radicale/app/move.py index 1d84c58b..4e4b7cd1 100644 --- a/radicale/app/move.py +++ b/radicale/app/move.py @@ -24,7 +24,7 @@ import re from http import client from urllib.parse import unquote, urlparse -from radicale import httputils, pathutils, storage, types +from radicale import httputils, pathutils, sharing, storage, types from radicale.app import base as app_base from radicale.app.base import Access, ApplicationBase from radicale.log import logger @@ -73,7 +73,10 @@ class ApplicationPartMove(ApplicationBase): permissions_filter = None if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] @@ -93,7 +96,10 @@ class ApplicationPartMove(ApplicationBase): to_path = to_path[len(base_prefix):] if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(to_path, to_user) + to_user_lookup = to_user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + to_user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(to_path, to_user_lookup) if share: # overwrite and run through extended permission check to_path = share['PathMapped'] diff --git a/radicale/app/propfind.py b/radicale/app/propfind.py index 531dd52e..7442f885 100644 --- a/radicale/app/propfind.py +++ b/radicale/app/propfind.py @@ -588,7 +588,10 @@ class ApplicationPartPropfind(ApplicationBase): allowed_items: list = [] if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] diff --git a/radicale/app/proppatch.py b/radicale/app/proppatch.py index ee7f8685..d6c29c78 100644 --- a/radicale/app/proppatch.py +++ b/radicale/app/proppatch.py @@ -107,7 +107,10 @@ class ApplicationPartProppatch(ApplicationBase): path_orig = path if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] diff --git a/radicale/app/put.py b/radicale/app/put.py index b6898103..1013504d 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -33,8 +33,8 @@ from typing import Iterator, List, Mapping, MutableMapping, Optional, Tuple import vobject import radicale.item as radicale_item -from radicale import (httputils, pathutils, rights, storage, types, utils, - xmlutils) +from radicale import (httputils, pathutils, rights, sharing, storage, types, + utils, xmlutils) from radicale.app.base import Access, ApplicationBase from radicale.hook import HookNotificationItem, HookNotificationItemTypes from radicale.log import logger @@ -188,7 +188,10 @@ class ApplicationPartPut(ApplicationBase): permissions_filter = None if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped'] diff --git a/radicale/app/report.py b/radicale/app/report.py index ed8a147d..8c0580cf 100644 --- a/radicale/app/report.py +++ b/radicale/app/report.py @@ -38,7 +38,7 @@ import vobject.base from vobject.base import ContentLine import radicale.item as radicale_item -from radicale import httputils, pathutils, storage, types, xmlutils +from radicale import httputils, pathutils, sharing, storage, types, xmlutils from radicale.app.base import Access, ApplicationBase from radicale.item import filter as radicale_filter from radicale.log import logger @@ -864,7 +864,10 @@ class ApplicationPartReport(ApplicationBase): share = None if self._sharing._enabled: # Sharing by token or map (if enabled) - share = self._sharing.sharing_collection_resolver(path, user) + user_lookup = user + if self._rights._user_groups is not None and len(self._rights._user_groups) > 0: + user_lookup += sharing.SHARING_SEPARATOR_GROUP + ','.join(self._rights._user_groups) + share = self._sharing.sharing_collection_resolver(path, user_lookup) if share: # overwrite and run through extended permission check path = share['PathMapped']