From 0b592294ad19990b48356f11caa10abd7e26c2b1 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 22 Feb 2026 16:15:11 +0100 Subject: [PATCH 1/6] use optional permissions filter --- radicale/app/put.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radicale/app/put.py b/radicale/app/put.py index 86e863ef..bd6db5ed 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -181,7 +181,8 @@ class ApplicationPartPut(ApplicationBase): def do_PUT(self, environ: types.WSGIEnviron, base_prefix: str, path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage PUT request.""" - access = Access(self._rights, user, path) + permissions_filter = None + access = Access(self._rights, user, path, permissions_filter) if not access.check("w"): return httputils.NOT_ALLOWED try: From 05e3b462c0d32fcf55b0b4a446639494891381a0 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 22 Feb 2026 16:15:23 +0100 Subject: [PATCH 2/6] extend copyright --- radicale/app/put.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radicale/app/put.py b/radicale/app/put.py index bd6db5ed..9ab87c94 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -4,7 +4,7 @@ # Copyright © 2008-2017 Guillaume Ayoub # Copyright © 2017-2020 Unrud # Copyright © 2020-2023 Tuna Celik -# Copyright © 2024-2025 Peter Bieringer +# Copyright © 2024-2026 Peter Bieringer # # This library is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From 9135ce69c0e53c662a959eab296cbc304a7d4166 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 22 Feb 2026 16:18:45 +0100 Subject: [PATCH 3/6] add bad_request function with extended information --- radicale/httputils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/radicale/httputils.py b/radicale/httputils.py index 81e01715..0e829c6b 100644 --- a/radicale/httputils.py +++ b/radicale/httputils.py @@ -106,6 +106,10 @@ MIMETYPES: Mapping[str, str] = { FALLBACK_MIMETYPE: str = "application/octet-stream" +def bad_request(additional_details: str) -> types.WSGIResponse: + return (client.BAD_REQUEST, (("Content-Type", "text/plain"),), f"Bad Request: {additional_details}", None) + + def decode_request(configuration: "config.Configuration", environ: types.WSGIEnviron, text: bytes) -> str: """Try to magically decode ``text`` according to given ``environ``.""" From 42e5f10d7db9669c69a25646c7403d8da50c5ac4 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 22 Feb 2026 16:19:18 +0100 Subject: [PATCH 4/6] extend copyright --- radicale/httputils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radicale/httputils.py b/radicale/httputils.py index 0e829c6b..d2829ea8 100644 --- a/radicale/httputils.py +++ b/radicale/httputils.py @@ -3,7 +3,7 @@ # Copyright © 2008 Pascal Halter # Copyright © 2008-2017 Guillaume Ayoub # Copyright © 2017-2022 Unrud -# Copyright © 2024-2025 Peter Bieringer +# Copyright © 2024-2026 Peter Bieringer # # This library is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From 3f66e9b76cccb450c91a860f13f43accabc83e82 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 22 Feb 2026 16:20:15 +0100 Subject: [PATCH 5/6] add options for content-type and accept --- radicale/tests/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/radicale/tests/__init__.py b/radicale/tests/__init__.py index 5b637159..30e8999d 100644 --- a/radicale/tests/__init__.py +++ b/radicale/tests/__init__.py @@ -89,6 +89,8 @@ class BaseTest: (str, type(http_if_match))) remote_useragent = kwargs.pop("remote_useragent", None) remote_host = kwargs.pop("remote_host", None) + content_type = kwargs.pop("content_type", None) + accept = kwargs.pop("accept", None) environ: Dict[str, Any] = {k.upper(): v for k, v in kwargs.items()} for k, v in environ.items(): if not isinstance(v, str): @@ -104,6 +106,10 @@ class BaseTest: environ["HTTP_USER_AGENT"] = remote_useragent if remote_host: environ["REMOTE_ADDR"] = remote_host + if content_type: + environ["CONTENT_TYPE"] = content_type + if accept: + environ["HTTP_ACCEPT"] = accept environ["REQUEST_METHOD"] = method.upper() environ["PATH_INFO"] = path if data is not None: From d2f52e72bb26bbba239cb3e0b822777c29df53cc Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Mon, 23 Feb 2026 07:45:59 +0100 Subject: [PATCH 6/6] initialize values earlier in code --- radicale/app/move.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radicale/app/move.py b/radicale/app/move.py index 5fce17c8..b4814234 100644 --- a/radicale/app/move.py +++ b/radicale/app/move.py @@ -67,6 +67,8 @@ class ApplicationPartMove(ApplicationBase): # Remote destination server, not supported return httputils.REMOTE_DESTINATION + to_user = user + to_permissions_filter = None permissions_filter = None access = Access(self._rights, user, path, permissions_filter) if not access.check("w"): @@ -77,8 +79,6 @@ class ApplicationPartMove(ApplicationBase): "start with base prefix", to_path, path) return httputils.NOT_ALLOWED to_path = to_path[len(base_prefix):] - to_user = user - to_permissions_filter = None to_access = Access(self._rights, to_user, to_path, to_permissions_filter) if not to_access.check("w"): return httputils.NOT_ALLOWED