diff --git a/config b/config index 4f3443874..bf28479a2 100644 --- a/config +++ b/config @@ -79,6 +79,9 @@ # File for rights management from_file #file = /etc/radicale/rights +# Permit delete of a collection (global) +#permit_delete_collection = True + [storage] diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 6896bc701..37ab6a5e7 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -68,6 +68,7 @@ class Application(ApplicationPartDelete, ApplicationPartHead, _max_content_length: int _auth_realm: str _extra_headers: Mapping[str, str] + _permit_delete_collection: bool def __init__(self, configuration: config.Configuration) -> None: """Initialize Application. @@ -84,6 +85,8 @@ def __init__(self, configuration: config.Configuration) -> None: self._max_content_length = configuration.get( "server", "max_content_length") self._auth_realm = configuration.get("auth", "realm") + self._permit_delete_collection = configuration.get("rights", "permit_delete_collection") + logger.info("permit delete of collection: %s", self._permit_delete_collection) self._extra_headers = dict() for key in self.configuration.options("headers"): self._extra_headers[key] = configuration.get("headers", key) diff --git a/radicale/app/delete.py b/radicale/app/delete.py index 3d6870650..53d9bfd36 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -70,15 +70,18 @@ def do_DELETE(self, environ: types.WSGIEnviron, base_prefix: str, return httputils.PRECONDITION_FAILED hook_notification_item_list = [] if isinstance(item, storage.BaseCollection): - for i in item.get_all(): - hook_notification_item_list.append( - HookNotificationItem( - HookNotificationItemTypes.DELETE, - access.path, - i.uid + if self._permit_delete_collection: + for i in item.get_all(): + hook_notification_item_list.append( + HookNotificationItem( + HookNotificationItemTypes.DELETE, + access.path, + i.uid + ) ) - ) - xml_answer = xml_delete(base_prefix, path, item) + xml_answer = xml_delete(base_prefix, path, item) + else: + return httputils.NOT_ALLOWED else: assert item.collection is not None assert item.href is not None diff --git a/radicale/config.py b/radicale/config.py index b5f45086d..beb62fc18 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -184,6 +184,10 @@ def _convert_to_bool(value: Any) -> bool: "help": "rights backend", "type": str_or_callable, "internal": rights.INTERNAL_TYPES}), + ("permit_delete_collection", { + "value": "True", + "help": "permit delete of a collection", + "type": bool}), ("file", { "value": "/etc/radicale/rights", "help": "file for rights management from_file",