From c9ac5f8a9e96d47c1f51a64267696a6642774ee5 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sat, 11 Apr 2026 17:03:59 +0200 Subject: [PATCH 1/3] storage/test: add share-by-softlink case --- radicale/tests/test_storage.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/radicale/tests/test_storage.py b/radicale/tests/test_storage.py index 9414108a..87046dac 100644 --- a/radicale/tests/test_storage.py +++ b/radicale/tests/test_storage.py @@ -1,7 +1,7 @@ # This file is part of Radicale - CalDAV and CardDAV server # Copyright © 2012-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 @@ -26,11 +26,13 @@ import logging import os import re import shutil +import sys from typing import ClassVar, cast import pytest import radicale.tests.custom.storage_simple_sync +from radicale import logger from radicale.tests import BaseTest from radicale.tests.helpers import get_file_content from radicale.tests.test_base import TestBaseRequests as _TestBaseRequests @@ -188,6 +190,34 @@ class TestMultiFileSystem(BaseTest): assert answer is not None assert "\r\nUID:%s\r\n" % uid in answer + @pytest.mark.skipif(sys.platform == 'win32', reason="Not supported on Windows") + def test_collection_sharing_by_softlink(self) -> None: + """Test collection sharing by softlink.""" + self.configure({"auth": {"type": "none"}}) + path_group_col = "/group/calendar-shared.ics/" + file_item = "event1.ics" + self.mkcalendar(path_group_col, login="group:grouppw") + event = get_file_content(file_item) + self.put(os.path.join(path_group_col, file_item), event) + fs_path_group_col = self.colpath + "/collection-root" + path_group_col + fs_path_group_col_rel = ".." + path_group_col + fs_path_user = self.colpath + "/collection-root/user" + fs_path_user_col = self.colpath + "/collection-root/user/calendar-group.ics" + logger.debug("colpath=%r fs_path_group_col=%r", self.colpath, fs_path_group_col) + assert os.path.isdir(fs_path_group_col) + # create user directory and check + logger.debug("create dir fs_path_user=%r", fs_path_user) + os.mkdir(fs_path_user) + assert os.path.isdir(fs_path_user) + # create relative symlink and check + logger.debug("create symlink src=%r dst=%r", fs_path_group_col_rel, fs_path_user_col) + os.symlink(fs_path_group_col_rel, fs_path_user_col) + logger.debug("test exists: fs_path_user_col=%r", fs_path_user_col) + assert os.path.exists(fs_path_user_col) + logger.debug("test is softlink: fs_path_user_col=%r", fs_path_user_col) + assert os.path.islink(fs_path_user_col) + self.propfind("/user/", login="user:userpw", HTTP_DEPTH="1") + @pytest.mark.skipif(not shutil.which("flock"), reason="flock command not found") @pytest.mark.skipif(radicale.log.logger.getEffectiveLevel() == logging.INFO, reason="requires loglevel DEBUG") def test_hook_placeholders_PUT(self, caplog) -> None: From 19302a6aab2008ccba15e2825487945519d6e190 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sat, 11 Apr 2026 17:04:29 +0200 Subject: [PATCH 2/3] tox: change test sequence --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cc3eeb91..f19f88a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ build-backend = "setuptools.build_meta" [tool.tox] min_version = "4.0" -envlist = ["py_loglevel_info", "py_radicale_loglevel_info", "py_radicale_loglevel_trace", "py", "flake8", "isort", "mypy", "integ_test", "html5validator"] +envlist = ["flake8", "isort", "mypy", "py_loglevel_info", "py_radicale_loglevel_info", "py_radicale_loglevel_trace", "py", "integ_test", "html5validator"] [tool.tox.env.py] extras = ["test"] From e12b387f181b423efa3cfceef6def34a188cc06b Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sat, 11 Apr 2026 17:28:35 +0200 Subject: [PATCH 3/3] doc: spelling fixes --- CHANGELOG.md | 14 +++++++------- DOCUMENTATION.md | 4 ++-- SHARING.md | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73618514..2e1176d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ * Cleanup: deprecate config option 'ldap_use_ssl' for good * Cleanup: WebUI is now split into smaller javascript files * Cleanup: WebUI is now fit for strict content security policy -* Cleanup: WebUI: Simplfied Caching and Navigation internally +* Cleanup: WebUI: Simplified Caching and Navigation internally * Cleanup: WebUI: Unified error handling * Cleanup: Added integration test for verification of end-to-end behavior of WebUI * Performance: improve `path_to_filesystem()` @@ -37,7 +37,7 @@ * Improve: add workaround to remove empty lines in item to avoid reject by vobject parser * Improve: check/enforce RECURRENCE-ID MUST have the same value type as DTSTART in the recurring component (RFC 5545 3.8.4.4) * Fix: RECURRENCE-ID comparison on all-day events -* Fix: format_ut problem on 32-bit systems (got lost inbetween since fixed in 3.5.8) +* Fix: format_ut problem on 32-bit systems (got lost in between since fixed in 3.5.8) * Maintain: Refactor Web UI Javascript into separate files * Maintain: code preparation for upcoming "sharing" extension and optimizations * Improve: check if hook is enabled before constructing hook notification items @@ -61,9 +61,9 @@ * Add: logging of broken contact items during PUT * Extend: [auth] imap: add fallback support for LOGIN towards remote IMAP server (replaced in 3.5.0) * Fix: improper detection of HTTP_X_FORWARDED_PORT on MOVE -* Extend: [logging] with profiling log per reqest or regular per request method +* Extend: [logging] with profiling log per request or regular per request method * Add: [logging] option to log response header on debug loglevel -* Adjust: [logging] header/content debug log indended by space to be skipped by logwatch +* Adjust: [logging] header/content debug log intended by space to be skipped by logwatch * Improve: remove unnecessary open+read for mtime+size cache * Extend: add selected XML query properties to request result log line for improved timing analysis incl. logwatch support * Add: [server] max_resource_size option @@ -657,7 +657,7 @@ One feature in this release is **not backward compatible**: Now, the first section matching the path and current user in your custom rights file is used. In the previous versions, the most permissive rights of all the matching sections were applied. This new behaviour gives a simple way to make -specific rules at the top of the file independant from the generic ones. +specific rules at the top of the file independent from the generic ones. Many **improvements in this release are related to security**, you should upgrade Radicale as soon as possible: @@ -670,10 +670,10 @@ upgrade Radicale as soon as possible: Some bugs have been fixed and little enhancements have been added: -* Assign new items to corret key (by Unrud) +* Assign new items to correct key (by Unrud) * Avoid race condition in PID file creation (by Unrud) * Improve the docker version (by cdpb) -* Encode message and commiter for git commits +* Encode message and committer for git commits * Test with Python 3.5 ## 1.0.1 - Sunflower Again diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index dce0af63..d9b803a2 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1226,7 +1226,7 @@ E.g. `member` for groups with objectclass `groupOfNames`. Using `ldap_group_members_attribute`, `ldap_group_base` and `ldap_group_filter` is an alternative approach to getting the user's groups. Instead of reading them from `ldap_groups_attribute` -in the user's entry, an additional query is performed to seach for those groups beneath `ldap_group_base`, +in the user's entry, an additional query is performed to search for those groups beneath `ldap_group_base`, that have the user's DN in their `ldap_group_members_attribute` and additionally fulfil `ldap_group_filter`. As with DN-valued `ldap_groups_attribute`, the value of the RDN is used to determine the group names. @@ -2279,7 +2279,7 @@ Add a new calendar on the network. Enter your username and the URL of the Radicale server (e.g. `http://localhost:5232`). After asking for your password, it will list the existing calendars. -##### Adress books with CardBook add-on +##### Address books with CardBook add-on Add a new address book on the network with CardDAV. Enter the URL of the Radicale server (e.g. `http://localhost:5232`) and your username and password. diff --git a/SHARING.md b/SHARING.md index 0a3ab314..29ce35da 100644 --- a/SHARING.md +++ b/SHARING.md @@ -10,7 +10,7 @@ With _3.7.0_ major extension was implemented ## Sharing Implementation -Implemenation of sharing collections is done by using a database to lookup the URI and in case entry exists by mapping to target URI and replacing provided data on request and adjust if required data in response. +Implementation of sharing collections is done by using a database to lookup the URI and in case entry exists by mapping to target URI and replacing provided data on request and adjust if required data in response. Permissions are filtered by provided `Permissions`. @@ -198,7 +198,7 @@ Token-based sharing can be accessed after retrieving the token via Token-URI: `/.token/` -Note: requests to not enabled or not even defined tokens will resul tin _401 Not Authorized_ +Note: requests to not enabled or not even defined tokens will result in _401 Not Authorized_ #### Permission Control