Merge pull request #425 from Unrud/patch-19

Don't silently drop files
This commit is contained in:
Guillaume Ayoub 2016-07-30 15:28:35 +02:00 committed by GitHub
commit dc406c17fd

View File

@ -147,7 +147,8 @@ def path_to_filesystem(root, *paths):
continue continue
for part in path.split("/"): for part in path.split("/"):
if not is_safe_filesystem_path_component(part): if not is_safe_filesystem_path_component(part):
raise ValueError("Unsafe path") raise ValueError(
"Can't tranlate name safely to filesystem: %s" % part)
safe_path = os.path.join(safe_path, part) safe_path = os.path.join(safe_path, part)
return safe_path return safe_path
@ -439,56 +440,56 @@ class Collection(BaseCollection):
def get(self, href): def get(self, href):
if not href: if not href:
return return None
href = href.strip("{}").replace("/", "_") href = href.strip("{}").replace("/", "_")
if is_safe_filesystem_path_component(href): if not is_safe_filesystem_path_component(href):
path = os.path.join(self._filesystem_path, href) self.logger.debug(
if os.path.isfile(path): "Can't tranlate name safely to filesystem: %s", href)
return None
path = path_to_filesystem(self._filesystem_path, href)
if not os.path.isfile(path):
return None
with open(path, encoding=self.storage_encoding) as fd: with open(path, encoding=self.storage_encoding) as fd:
text = fd.read() text = fd.read()
last_modified = time.strftime( last_modified = time.strftime(
"%a, %d %b %Y %H:%M:%S GMT", "%a, %d %b %Y %H:%M:%S GMT",
time.gmtime(os.path.getmtime(path))) time.gmtime(os.path.getmtime(path)))
return Item(self, vobject.readOne(text), href, last_modified) return Item(self, vobject.readOne(text), href, last_modified)
else:
self.logger.debug(
"Can't tranlate name safely to filesystem, "
"skipping component: %s", href)
def has(self, href): def has(self, href):
return self.get(href) is not None return self.get(href) is not None
def upload(self, href, vobject_item): def upload(self, href, vobject_item):
# TODO: use returned object in code # TODO: use returned object in code
if is_safe_filesystem_path_component(href): if not is_safe_filesystem_path_component(href):
raise ValueError(
"Can't tranlate name safely to filesystem: %s" % href)
path = path_to_filesystem(self._filesystem_path, href) path = path_to_filesystem(self._filesystem_path, href)
if not os.path.exists(path): if os.path.exists(path):
raise ValueError("Component already exists: %s" % href)
item = Item(self, vobject_item, href) item = Item(self, vobject_item, href)
with self._atomic_write(path) as fd: with self._atomic_write(path) as fd:
fd.write(item.serialize()) fd.write(item.serialize())
return item return item
else:
self.logger.debug(
"Can't tranlate name safely to filesystem, "
"skipping component: %s", href)
def update(self, href, vobject_item, etag=None): def update(self, href, vobject_item, etag=None):
# TODO: use etag in code and test it here # TODO: use etag in code and test it here
# TODO: use returned object in code # TODO: use returned object in code
if is_safe_filesystem_path_component(href): if not is_safe_filesystem_path_component(href):
raise ValueError(
"Can't tranlate name safely to filesystem: %s" % href)
path = path_to_filesystem(self._filesystem_path, href) path = path_to_filesystem(self._filesystem_path, href)
if os.path.exists(path): if not os.path.isfile(path):
raise ValueError("Component doesn't exist: %s" % href)
with open(path, encoding=self.storage_encoding) as fd: with open(path, encoding=self.storage_encoding) as fd:
text = fd.read() text = fd.read()
if not etag or etag == get_etag(text): if etag and etag != get_etag(text):
raise ValueError(
"ETag doesn't match: %s != %s" % (etag, get_etag(text)))
item = Item(self, vobject_item, href) item = Item(self, vobject_item, href)
with self._atomic_write(path) as fd: with self._atomic_write(path) as fd:
fd.write(item.serialize()) fd.write(item.serialize())
return item return item
else:
self.logger.debug(
"Can't tranlate name safely to filesystem, "
"skipping component: %s", href)
def delete(self, href=None, etag=None): def delete(self, href=None, etag=None):
# TODO: use etag in code and test it here # TODO: use etag in code and test it here
@ -500,20 +501,20 @@ class Collection(BaseCollection):
props_path = self._filesystem_path + ".props" props_path = self._filesystem_path + ".props"
if os.path.isfile(props_path): if os.path.isfile(props_path):
os.remove(props_path) os.remove(props_path)
return else:
elif is_safe_filesystem_path_component(href):
# Delete an item # Delete an item
if not is_safe_filesystem_path_component(href):
raise ValueError(
"Can't tranlate name safely to filesystem: %s" % href)
path = path_to_filesystem(self._filesystem_path, href) path = path_to_filesystem(self._filesystem_path, href)
if os.path.isfile(path): if not os.path.isfile(path):
raise ValueError("Component doesn't exist: %s" % href)
with open(path, encoding=self.storage_encoding) as fd: with open(path, encoding=self.storage_encoding) as fd:
text = fd.read() text = fd.read()
if not etag or etag == get_etag(text): if etag and etag != get_etag(text):
raise ValueError(
"ETag doesn't match: %s != %s" % (etag, get_etag(text)))
os.remove(path) os.remove(path)
return
else:
self.logger.debug(
"Can't tranlate name safely to filesystem, "
"skipping component: %s", href)
def get_meta(self, key): def get_meta(self, key):
props_path = self._filesystem_path + ".props" props_path = self._filesystem_path + ".props"