From 1c7ff414a96a6024616f1ece1d473bebd0455206 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 16 Nov 2025 17:06:00 +0100 Subject: [PATCH] extend app calls with remote host+useragent --- radicale/app/__init__.py | 2 +- radicale/app/delete.py | 2 +- radicale/app/get.py | 2 +- radicale/app/head.py | 4 ++-- radicale/app/mkcalendar.py | 2 +- radicale/app/mkcol.py | 2 +- radicale/app/move.py | 2 +- radicale/app/options.py | 2 +- radicale/app/post.py | 2 +- radicale/app/propfind.py | 2 +- radicale/app/proppatch.py | 2 +- radicale/app/put.py | 2 +- radicale/app/report.py | 6 +++--- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 0b895820..940d15b5 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -371,7 +371,7 @@ class Application(ApplicationPartDelete, ApplicationPartHead, if not login or user: status, headers, answer = function( - environ, base_prefix, path, user) + environ, base_prefix, path, user, remote_host, remote_useragent) if (status, headers, answer) == httputils.NOT_ALLOWED: logger.info("Access to %r denied for %s", path, repr(user) if user else "anonymous user") diff --git a/radicale/app/delete.py b/radicale/app/delete.py index 060abb18..695de45f 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -55,7 +55,7 @@ def xml_delete(base_prefix: str, path: str, collection: storage.BaseCollection, class ApplicationPartDelete(ApplicationBase): def do_DELETE(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage DELETE request.""" access = Access(self._rights, user, path) if not access.check("w"): diff --git a/radicale/app/get.py b/radicale/app/get.py index d170d380..b8adb39a 100644 --- a/radicale/app/get.py +++ b/radicale/app/get.py @@ -59,7 +59,7 @@ class ApplicationPartGet(ApplicationBase): return value def do_GET(self, environ: types.WSGIEnviron, base_prefix: str, path: str, - user: str) -> types.WSGIResponse: + user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage GET request.""" # Redirect to /.web if the root path is requested if not pathutils.strip_path(path): diff --git a/radicale/app/head.py b/radicale/app/head.py index 718861e6..eec68bb5 100644 --- a/radicale/app/head.py +++ b/radicale/app/head.py @@ -26,7 +26,7 @@ from radicale.app.get import ApplicationPartGet class ApplicationPartHead(ApplicationPartGet, ApplicationBase): def do_HEAD(self, environ: types.WSGIEnviron, base_prefix: str, path: str, - user: str) -> types.WSGIResponse: + user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage HEAD request.""" # Body is dropped in `Application.__call__` for HEAD requests - return self.do_GET(environ, base_prefix, path, user) + return self.do_GET(environ, base_prefix, path, user, remote_host, remote_useragent) diff --git a/radicale/app/mkcalendar.py b/radicale/app/mkcalendar.py index 632d3c38..db14bfdc 100644 --- a/radicale/app/mkcalendar.py +++ b/radicale/app/mkcalendar.py @@ -33,7 +33,7 @@ from radicale.log import logger class ApplicationPartMkcalendar(ApplicationBase): def do_MKCALENDAR(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage MKCALENDAR request.""" if "w" not in self._rights.authorization(user, path): return httputils.NOT_ALLOWED diff --git a/radicale/app/mkcol.py b/radicale/app/mkcol.py index 169cb62c..72d5aa2b 100644 --- a/radicale/app/mkcol.py +++ b/radicale/app/mkcol.py @@ -33,7 +33,7 @@ from radicale.log import logger class ApplicationPartMkcol(ApplicationBase): def do_MKCOL(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage MKCOL request.""" permissions = self._rights.authorization(user, path) if not rights.intersect(permissions, "Ww"): diff --git a/radicale/app/move.py b/radicale/app/move.py index 77e56f3e..ba346762 100644 --- a/radicale/app/move.py +++ b/radicale/app/move.py @@ -48,7 +48,7 @@ def get_server_netloc(environ: types.WSGIEnviron, force_port: bool = False): class ApplicationPartMove(ApplicationBase): def do_MOVE(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage MOVE request.""" raw_dest = environ.get("HTTP_DESTINATION", "") to_url = urlparse(raw_dest) diff --git a/radicale/app/options.py b/radicale/app/options.py index 159584bf..a869e2ab 100644 --- a/radicale/app/options.py +++ b/radicale/app/options.py @@ -27,7 +27,7 @@ from radicale.app.base import ApplicationBase class ApplicationPartOptions(ApplicationBase): def do_OPTIONS(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage OPTIONS request.""" headers = { "Allow": ", ".join( diff --git a/radicale/app/post.py b/radicale/app/post.py index 1bb68a12..df944499 100644 --- a/radicale/app/post.py +++ b/radicale/app/post.py @@ -26,7 +26,7 @@ from radicale.app.base import ApplicationBase class ApplicationPartPost(ApplicationBase): def do_POST(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage POST request.""" if path == "/.web" or path.startswith("/.web/"): return self._web.post(environ, base_prefix, path, user) diff --git a/radicale/app/propfind.py b/radicale/app/propfind.py index 2ba4b5d1..b546c5e1 100644 --- a/radicale/app/propfind.py +++ b/radicale/app/propfind.py @@ -377,7 +377,7 @@ class ApplicationPartPropfind(ApplicationBase): yield item, permission def do_PROPFIND(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage PROPFIND request.""" access = Access(self._rights, user, path) if not access.check("r"): diff --git a/radicale/app/proppatch.py b/radicale/app/proppatch.py index 2e8eed47..9d6dc221 100644 --- a/radicale/app/proppatch.py +++ b/radicale/app/proppatch.py @@ -73,7 +73,7 @@ def xml_proppatch(base_prefix: str, path: str, class ApplicationPartProppatch(ApplicationBase): def do_PROPPATCH(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage PROPPATCH request.""" access = Access(self._rights, user, path) if not access.check("w"): diff --git a/radicale/app/put.py b/radicale/app/put.py index 6cfed1eb..de11589b 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -142,7 +142,7 @@ def prepare(vobject_items: List[vobject.base.Component], path: str, class ApplicationPartPut(ApplicationBase): def do_PUT(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage PUT request.""" access = Access(self._rights, user, path) if not access.check("w"): diff --git a/radicale/app/report.py b/radicale/app/report.py index e6dc45c0..dd59c373 100644 --- a/radicale/app/report.py +++ b/radicale/app/report.py @@ -149,7 +149,7 @@ def free_busy_report(base_prefix: str, path: str, xml_request: Optional[ET.Eleme def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element], collection: storage.BaseCollection, encoding: str, unlock_storage_fn: Callable[[], None], - max_occurrence: int = 0, user: str = "" + max_occurrence: int = 0, user: str = "", remote_addr: str = "", remote_useragent: str = "" ) -> Tuple[int, ET.Element]: """Read and answer REPORT requests that return XML. @@ -776,7 +776,7 @@ def test_filter(collection_tag: str, item: radicale_item.Item, class ApplicationPartReport(ApplicationBase): def do_REPORT(self, environ: types.WSGIEnviron, base_prefix: str, - path: str, user: str) -> types.WSGIResponse: + path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: """Manage REPORT request.""" access = Access(self._rights, user, path) if not access.check("r"): @@ -820,7 +820,7 @@ class ApplicationPartReport(ApplicationBase): try: status, xml_answer = xml_report( base_prefix, path, xml_content, collection, self._encoding, - lock_stack.close, max_occurrence, user) + lock_stack.close, max_occurrence, user, remote_host, remote_useragent) except ValueError as e: logger.warning( "Bad REPORT request on %r: %s", path, e, exc_info=True)