diff --git a/CHANGELOG.md b/CHANGELOG.md index 728e63bf..b5b1c05d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.5.5.dev * Improve: [auth] ldap: do not read server info by bind to avoid needless network traffic +* Fix: [storage] broken support of 'folder_umask' ## 3.5.4 * Improve: item filter enhanced for 3rd level supporting VALARM and honoring TRIGGER (offset or absolute) diff --git a/radicale/storage/multifilesystem/__init__.py b/radicale/storage/multifilesystem/__init__.py index c8e3316e..005e6af1 100644 --- a/radicale/storage/multifilesystem/__init__.py +++ b/radicale/storage/multifilesystem/__init__.py @@ -146,6 +146,21 @@ class Storage( def __init__(self, configuration: config.Configuration) -> None: super().__init__(configuration) + if sys.platform != "win32": + if not self._folder_umask: + # retrieve current umask by setting a dummy umask + current_umask = os.umask(0o0022) + logger.info("Storage folder umask (from system): '%04o'", current_umask) + # reset to original + os.umask(current_umask) + else: + try: + config_umask = int(self._folder_umask, 8) + except Exception: + logger.critical("storage folder umask defined but invalid: '%s'", self._folder_umask) + raise + logger.info("storage folder umask defined: '%04o'", config_umask) + self._config_umask = config_umask logger.info("Storage location: %r", self._filesystem_folder) if not os.path.exists(self._filesystem_folder): logger.warning("Storage location: %r does not exist, creating now", self._filesystem_folder) @@ -178,18 +193,3 @@ class Storage( if not os.path.exists(self._get_collection_cache_folder()): logger.warning("Storage cache subfolder: %r does not exist, creating now", self._get_collection_cache_folder()) self._makedirs_synced(self._get_collection_cache_folder()) - if sys.platform != "win32": - if not self._folder_umask: - # retrieve current umask by setting a dummy umask - current_umask = os.umask(0o0022) - logger.info("Storage folder umask (from system): '%04o'", current_umask) - # reset to original - os.umask(current_umask) - else: - try: - config_umask = int(self._folder_umask, 8) - except Exception: - logger.critical("storage folder umask defined but invalid: '%s'", self._folder_umask) - raise - logger.info("storage folder umask defined: '%04o'", config_umask) - self._config_umask = config_umask diff --git a/radicale/tests/test_storage.py b/radicale/tests/test_storage.py index 2fcfe717..89572bca 100644 --- a/radicale/tests/test_storage.py +++ b/radicale/tests/test_storage.py @@ -46,6 +46,12 @@ class TestMultiFileSystem(BaseTest): self.configure({"storage": {"filesystem_folder": folder}}) assert os.path.isdir(folder) + def test_folder_creation_with_umask(self) -> None: + """Verify that the folder is created with umask.""" + folder = os.path.join(self.colpath, "subfolder") + self.configure({"storage": {"filesystem_folder": folder, "folder_umask": "0077"}}) + assert os.path.isdir(folder) + def test_fsync(self) -> None: """Create a directory and file with syncing enabled.""" self.configure({"storage": {"_filesystem_fsync": "True"}})