add option for file creation mode

This commit is contained in:
2021-09-30 15:12:31 +02:00
parent 7de9cc1bb8
commit 60e3f49fe1
2 changed files with 32 additions and 5 deletions

View File

@@ -192,6 +192,7 @@ class StoreConfig(BaseConfig):
"properties": { "properties": {
"type": {"type": "string"}, "type": {"type": "string"},
"directory": {"type": "string"}, "directory": {"type": "string"},
"mode": {"type": "string"},
"metavar": {"type": "string"}, "metavar": {"type": "string"},
"original": {"type": "boolean", "default": True}}}} "original": {"type": "boolean", "default": True}}}}

View File

@@ -73,7 +73,7 @@ class FileMailStorage(BaseMailStorage):
_headersonly = False _headersonly = False
def __init__(self, directory, original=False, metadata=False, metavar=None, def __init__(self, directory, original=False, metadata=False, metavar=None,
pretend=False): mode=None, pretend=False):
super().__init__(original, metadata, metavar, pretend) super().__init__(original, metadata, metavar, pretend)
# check if directory exists and is writable # check if directory exists and is writable
if not os.path.isdir(directory) or \ if not os.path.isdir(directory) or \
@@ -82,6 +82,13 @@ class FileMailStorage(BaseMailStorage):
f"directory '{directory}' does not exist or is " f"directory '{directory}' does not exist or is "
f"not writable") f"not writable")
self.directory = directory self.directory = directory
try:
self.mode = int(mode, 8) if mode is not None else None
if self.mode is not None and self.mode > 511:
raise ValueError
except ValueError:
raise RuntimeError(f"invalid mode '{mode}'")
self._metadata_suffix = ".metadata" self._metadata_suffix = ".metadata"
def __str__(self): def __str__(self):
@@ -104,15 +111,33 @@ class FileMailStorage(BaseMailStorage):
def _save_datafile(self, datafile, data): def _save_datafile(self, datafile, data):
try: try:
if self.mode is None:
with open(datafile, "wb") as f: with open(datafile, "wb") as f:
f.write(data) f.write(data)
else:
umask = os.umask(0)
with open(
os.open(datafile, os.O_CREAT | os.O_WRONLY, self.mode),
"wb") as f:
f.write(data)
os.umask(umask)
except IOError as e: except IOError as e:
raise RuntimeError(f"unable save data file: {e}") raise RuntimeError(f"unable save data file: {e}")
def _save_metafile(self, metafile, metadata): def _save_metafile(self, metafile, metadata):
try: try:
if self.mode is None:
with open(metafile, "w") as f: with open(metafile, "w") as f:
json.dump(metadata, f, indent=2) json.dump(metadata, f, indent=2)
else:
umask = os.umask(0)
with open(
os.open(metafile, os.O_CREAT | os.O_WRONLY, self.mode),
"w") as f:
json.dump(metadata, f, indent=2)
os.umask(umask)
except IOError as e: except IOError as e:
raise RuntimeError(f"unable to save metadata file: {e}") raise RuntimeError(f"unable to save metadata file: {e}")
@@ -330,6 +355,7 @@ class Quarantine:
"pretend": cfg["pretend"], "pretend": cfg["pretend"],
"type": "store", "type": "store",
"args": cfg["args"]["store"].get_config()}) "args": cfg["args"]["store"].get_config()})
store_cfg["args"]["metadata"] = True
self.store = Store(store_cfg, local_addrs, debug) self.store = Store(store_cfg, local_addrs, debug)
self.notify = None self.notify = None