diff --git a/radicale/storage/multifilesystem/__init__.py b/radicale/storage/multifilesystem/__init__.py index 1f44d6b..f78458d 100644 --- a/radicale/storage/multifilesystem/__init__.py +++ b/radicale/storage/multifilesystem/__init__.py @@ -27,7 +27,7 @@ import contextlib import os import time from itertools import chain -from tempfile import NamedTemporaryFile +from tempfile import TemporaryDirectory from radicale import pathutils, storage from radicale.storage.multifilesystem.cache import CollectionCacheMixin @@ -69,21 +69,17 @@ class Collection( @contextlib.contextmanager def _atomic_write(self, path, mode="w", newline=None): - directory = os.path.dirname(path) - tmp = NamedTemporaryFile( - mode=mode, dir=directory, delete=False, prefix=".Radicale.tmp-", - newline=newline, encoding=None if "b" in mode else self._encoding) - try: - yield tmp - tmp.flush() - self._storage._fsync(tmp) - tmp.close() - os.replace(tmp.name, path) - except BaseException: - tmp.close() - os.remove(tmp.name) - raise - self._storage._sync_directory(directory) + parent_dir, name = os.path.split(path) + # Do not use mkstemp because it creates with permissions 0o600 + with TemporaryDirectory( + prefix=".Radicale.tmp-", dir=parent_dir) as tmp_dir: + with open(os.path.join(tmp_dir, name), mode, newline=newline, + encoding=None if "b" in mode else self._encoding) as tmp: + yield tmp + tmp.flush() + self._storage._fsync(tmp) + os.replace(os.path.join(tmp_dir, name), path) + self._storage._sync_directory(parent_dir) @property def last_modified(self):