From a272d3039e8fd28764c922687db3a4b997067f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dipl=2E=20Ing=2E=20P=C3=A9ter=20Varkoly?= Date: Sun, 22 Sep 2024 16:56:53 +0200 Subject: [PATCH] Implement using group calenders. Based on the ldap groups the user is member of group calender usage is implemented. The group calenders must be placed in the GROUPS directory based under collection_root_folder. The name of the group calender directory is the base64 encoded name of the group to avoid trouble with spaces and special characters in name. If the directory does not exist the group will be ignored. --- radicale/app/propfind.py | 3 ++- radicale/storage/multifilesystem/discover.py | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/radicale/app/propfind.py b/radicale/app/propfind.py index 009c61dc..6a3cea6d 100644 --- a/radicale/app/propfind.py +++ b/radicale/app/propfind.py @@ -392,7 +392,8 @@ class ApplicationPartPropfind(ApplicationBase): return httputils.REQUEST_TIMEOUT with self._storage.acquire_lock("r", user): items_iter = iter(self._storage.discover( - path, environ.get("HTTP_DEPTH", "0"))) + path, environ.get("HTTP_DEPTH", "0"), + None, self._rights._user_groups)) # take root item for rights checking item = next(items_iter, None) if not item: diff --git a/radicale/storage/multifilesystem/discover.py b/radicale/storage/multifilesystem/discover.py index 00316141..9a951764 100644 --- a/radicale/storage/multifilesystem/discover.py +++ b/radicale/storage/multifilesystem/discover.py @@ -18,6 +18,7 @@ import os import posixpath +import base64 from typing import Callable, ContextManager, Iterator, Optional, cast from radicale import pathutils, types @@ -36,7 +37,8 @@ class StoragePartDiscover(StorageBase): def discover( self, path: str, depth: str = "0", child_context_manager: Optional[ - Callable[[str, Optional[str]], ContextManager[None]]] = None + Callable[[str, Optional[str]], ContextManager[None]]] = None, + user_groups: Set[str] = set([]) ) -> Iterator[types.CollectionOrItem]: # assert isinstance(self, multifilesystem.Storage) if child_context_manager is None: @@ -102,3 +104,13 @@ class StoragePartDiscover(StorageBase): with child_context_manager(sane_child_path, None): yield self._collection_class( cast(multifilesystem.Storage, self), child_path) + for group in user_groups: + href = base64.b64encode(group.encode('utf-8')).decode('ascii') + logger.debug(f"searching for group calendar {group} {href}") + sane_child_path = f"GROUPS/{href}" + if not os.path.isdir(pathutils.path_to_filesystem(folder, sane_child_path)): + continue + child_path = f"/GROUPS/{href}/" + with child_context_manager(sane_child_path, None): + yield self._collection_class( + cast(multifilesystem.Storage, self), child_path)