diff --git a/radicale/app/delete.py b/radicale/app/delete.py index cd8b0c3a..ff22e0c5 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -58,6 +58,14 @@ class ApplicationPartDelete(ApplicationBase): path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage DELETE request.""" permissions_filter = 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("w"): return httputils.NOT_ALLOWED diff --git a/radicale/app/get.py b/radicale/app/get.py index 98e82f7a..cea26f31 100644 --- a/radicale/app/get.py +++ b/radicale/app/get.py @@ -77,6 +77,14 @@ class ApplicationPartGet(ApplicationBase): # Dispatch /.web path to web module return self._web.get(environ, base_prefix, path, user) permissions_filter = 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") and "i" not in access.permissions: return httputils.NOT_ALLOWED diff --git a/radicale/app/mkcalendar.py b/radicale/app/mkcalendar.py index bf6da1c8..b892aa6b 100644 --- a/radicale/app/mkcalendar.py +++ b/radicale/app/mkcalendar.py @@ -54,6 +54,13 @@ class ApplicationPartMkcalendar(ApplicationBase): logger.warning( "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST + if self._sharing._enabled: + # check for shared collections (active or inactive) + collections_shared_map = self._sharing.sharing_collection_map_list(user, active=False) + if collections_shared_map: + for sharing in collections_shared_map: + if sharing['PathOrToken'] == path: + return httputils.CONFLICT # TODO: use this? # timezone = props.get("C:calendar-timezone") with self._storage.acquire_lock("w", user, path=path, request="MKCALENDAR"): diff --git a/radicale/app/mkcol.py b/radicale/app/mkcol.py index 8d3b1755..6670349f 100644 --- a/radicale/app/mkcol.py +++ b/radicale/app/mkcol.py @@ -61,6 +61,13 @@ class ApplicationPartMkcol(ApplicationBase): if not props.get("tag") and "W" not in permissions: logger.warning("MKCOL request %r (type:%s): %s", path, collection_type, "rejected because of missing rights 'W'") return httputils.NOT_ALLOWED + if self._sharing._enabled: + # check for shared collections (active or inactive) + collections_shared_map = self._sharing.sharing_collection_map_list(user, active=False) + if collections_shared_map: + for sharing in collections_shared_map: + if sharing['PathOrToken'] == path: + return httputils.CONFLICT with self._storage.acquire_lock("w", user, path=path, request="MKCOL"): item = next(iter(self._storage.discover(path)), None) if item: diff --git a/radicale/app/move.py b/radicale/app/move.py index b4814234..b093aa25 100644 --- a/radicale/app/move.py +++ b/radicale/app/move.py @@ -70,6 +70,14 @@ class ApplicationPartMove(ApplicationBase): to_user = user to_permissions_filter = None permissions_filter = 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("w"): return httputils.NOT_ALLOWED @@ -79,6 +87,15 @@ class ApplicationPartMove(ApplicationBase): "start with base prefix", to_path, path) return httputils.NOT_ALLOWED to_path = to_path[len(base_prefix):] + if self._sharing._enabled: + # Sharing by token or map (if enabled) + sharing = self._sharing.sharing_collection_resolver(to_path, to_user) + if sharing: + # overwrite and run through extended permission check + to_path = sharing['PathMapped'] + to_user = sharing['Owner'] + to_permissions_filter = sharing['Permissions'] + to_access = Access(self._rights, to_user, to_path, to_permissions_filter) to_access = Access(self._rights, to_user, to_path, to_permissions_filter) if not to_access.check("w"): return httputils.NOT_ALLOWED