def xml_proppatch(base_prefix, path, xml_request, collection): """Read and answer PROPPATCH requests. Read rfc4918-9.2 for info. """ props_to_set = xmlutils.props_from_request(xml_request, actions=("set",)) props_to_remove = xmlutils.props_from_request(xml_request, actions=("remove",)) multistatus = ET.Element(xmlutils.make_tag("D", "multistatus")) response = ET.Element(xmlutils.make_tag("D", "response")) multistatus.append(response) href = ET.Element(xmlutils.make_tag("D", "href")) href.text = xmlutils.make_href(base_prefix, path) response.append(href) new_props = collection.get_meta() for short_name, value in props_to_set.items(): new_props[short_name] = value xml_add_propstat_to(response, short_name, 200) for short_name in props_to_remove: try: del new_props[short_name] except KeyError: pass xml_add_propstat_to(response, short_name, 200) radicale_item.check_and_sanitize_props(new_props) collection.set_meta(new_props) return multistatus
def do_MKCOL(self, environ, base_prefix, path, user): """Manage MKCOL request.""" if not self.Rights.authorized(user, path, "w"): return NOT_ALLOWED try: xml_content = self._read_xml_content(environ) except RuntimeError as e: self.logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) return BAD_REQUEST except socket.timeout as e: self.logger.debug("client timed out", exc_info=True) return REQUEST_TIMEOUT with self.Collection.acquire_lock("w", user): item = next(self.Collection.discover(path), None) if item: return WEBDAV_PRECONDITION_FAILED props = xmlutils.props_from_request(xml_content) try: storage.check_and_sanitize_props(props) self.Collection.create_collection(path, props=props) except ValueError as e: self.logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) return BAD_REQUEST return client.CREATED, {}, None
def mkcol(self, environ, collections, content, user): """Manage MKCOL request.""" collection = collections[0] props = xmlutils.props_from_request(content) with collection.props as collection_props: for key, value in props.items(): collection_props[key] = value collection.write() return client.CREATED, {}, None
def mkcalendar(self, environ, collections, content, user): """Manage MKCALENDAR request.""" collection = collections[0] props = xmlutils.props_from_request(content) timezone = props.get("C:calendar-timezone") if timezone: collection.replace("", timezone) del props["C:calendar-timezone"] with collection.props as collection_props: for key, value in props.items(): collection_props[key] = value collection.write() return client.CREATED, {}, None
def mkcalendar(self, environ, calendars, content, user): """Manage MKCALENDAR request.""" calendar = calendars[0] props = xmlutils.props_from_request(content) timezone = props.get('C:calendar-timezone') if timezone: calendar.replace('', timezone) del props['C:calendar-timezone'] with calendar.props as calendar_props: for key, value in props.items(): calendar_props[key] = value calendar.write() return client.CREATED, {}, None
def do_MKCOL(self, environ, base_prefix, path, user, context=None): """Manage MKCOL request.""" permissions = self._rights.authorization(user, path) if not rights.intersect(permissions, "Ww"): return httputils.NOT_ALLOWED try: xml_content = self._read_xml_request_body(environ) except RuntimeError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST except socket.timeout: logger.debug("Client timed out", exc_info=True) return httputils.REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) props = {k: v for k, v in props.items() if v is not None} try: radicale_item.check_and_sanitize_props(props) except ValueError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST if (props.get("tag") and "w" not in permissions or not props.get("tag") and "W" not in permissions): return httputils.NOT_ALLOWED with self._storage.acquire_lock("w", user): item = next(self._storage.discover(path), None) if item: return httputils.METHOD_NOT_ALLOWED parent_path = pathutils.unstrip_path( posixpath.dirname(pathutils.strip_path(path)), True) parent_item = next(self._storage.discover(parent_path), None) if not parent_item: return httputils.CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return httputils.FORBIDDEN try: self._storage.create_collection(path, props=props) except ValueError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST return client.CREATED, {}, None
def do_MKCALENDAR(self, environ, base_prefix, path, user): """Manage MKCALENDAR request.""" if "w" not in self._rights.authorization(user, path): return httputils.NOT_ALLOWED try: xml_content = self._read_xml_request_body(environ) except RuntimeError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST except socket.timeout: logger.debug("Client timed out", exc_info=True) return httputils.REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) props = {k: v for k, v in props.items() if v is not None} props["tag"] = "VCALENDAR" # TODO: use this? # timezone = props.get("C:calendar-timezone") try: radicale_item.check_and_sanitize_props(props) except ValueError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST with self._storage.acquire_lock("w", user): item = next(self._storage.discover(path), None) if item: return self._webdav_error_response(client.CONFLICT, "D:resource-must-be-null") parent_path = pathutils.unstrip_path( posixpath.dirname(pathutils.strip_path(path)), True) parent_item = next(self._storage.discover(parent_path), None) if not parent_item: return httputils.CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return httputils.FORBIDDEN try: self._storage.create_collection(path, props=props) except ValueError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST return client.CREATED, {}, None
def do_MKCOL(self, environ, base_prefix, path, user): """Manage MKCOL request.""" permissions = self.Rights.authorized(user, path, "Ww") if not permissions: return NOT_ALLOWED try: xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return BAD_REQUEST except socket.timeout as e: logger.debug("client timed out", exc_info=True) return REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) try: storage.check_and_sanitize_props(props) except ValueError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return BAD_REQUEST if (props.get("tag") and "w" not in permissions or not props.get("tag") and "W" not in permissions): return NOT_ALLOWED with self.Collection.acquire_lock("w", user): item = next(self.Collection.discover(path), None) if item: return METHOD_NOT_ALLOWED parent_path = storage.sanitize_path( "/%s/" % posixpath.dirname(path.strip("/"))) parent_item = next(self.Collection.discover(parent_path), None) if not parent_item: return CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return FORBIDDEN try: self.Collection.create_collection(path, props=props) except ValueError as e: logger.warning("Bad MKCOL request on %r: %s", path, e, exc_info=True) return BAD_REQUEST return client.CREATED, {}, None
def do_MKCALENDAR(self, environ, base_prefix, path, user): """Manage MKCALENDAR request.""" if not self.Rights.authorized(user, path, "w"): return NOT_ALLOWED try: xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return BAD_REQUEST except socket.timeout as e: logger.debug("client timed out", exc_info=True) return REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) props["tag"] = "VCALENDAR" # TODO: use this? # timezone = props.get("C:calendar-timezone") try: storage.check_and_sanitize_props(props) except ValueError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) with self.Collection.acquire_lock("w", user): item = next(self.Collection.discover(path), None) if item: return self._webdav_error_response("D", "resource-must-be-null") parent_path = storage.sanitize_path( "/%s/" % posixpath.dirname(path.strip("/"))) parent_item = next(self.Collection.discover(parent_path), None) if not parent_item: return CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return FORBIDDEN try: self.Collection.create_collection(path, props=props) except ValueError as e: logger.warning("Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return BAD_REQUEST return client.CREATED, {}, None
def do_MKCOL(self, environ, read_collections, write_collections, content, user): """Manage MKCOL request.""" _logger.info('do_MKCOL %s %s' % (content, user)) if not len(write_collections): return NOT_ALLOWED collection = write_collections[0] props = xmlutils.props_from_request(content) with collection.props as collection_props: for key, value in props.items(): collection_props[key] = value collection.write() return client.CREATED, {}, None
def do_MKCOL(self, environ, base_prefix, path, user): """Manage MKCOL request.""" permissions = self.Rights.authorized(user, path, "Ww") if not permissions: return httputils.NOT_ALLOWED try: xml_content = self.read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST except socket.timeout: logger.debug("client timed out", exc_info=True) return httputils.REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) try: radicale_item.check_and_sanitize_props(props) except ValueError as e: logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST if (props.get("tag") and "w" not in permissions or not props.get("tag") and "W" not in permissions): return httputils.NOT_ALLOWED with self.Collection.acquire_lock("w", user): item = next(self.Collection.discover(path), None) if item: return httputils.METHOD_NOT_ALLOWED parent_path = pathutils.unstrip_path( posixpath.dirname(pathutils.strip_path(path)), True) parent_item = next(self.Collection.discover(parent_path), None) if not parent_item: return httputils.CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return httputils.FORBIDDEN try: self.Collection.create_collection(path, props=props) except ValueError as e: logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST return client.CREATED, {}, None
def do_MKCALENDAR(self, environ, base_prefix, path, user): """Manage MKCALENDAR request.""" if not self.Rights.authorized(user, path, "w"): return httputils.NOT_ALLOWED try: xml_content = self.read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST except socket.timeout: logger.debug("client timed out", exc_info=True) return httputils.REQUEST_TIMEOUT # Prepare before locking props = xmlutils.props_from_request(xml_content) props["tag"] = "VCALENDAR" # TODO: use this? # timezone = props.get("C:calendar-timezone") try: radicale_item.check_and_sanitize_props(props) except ValueError as e: logger.warning( "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) with self.Collection.acquire_lock("w", user): item = next(self.Collection.discover(path), None) if item: return self.webdav_error_response( "D", "resource-must-be-null") parent_path = pathutils.unstrip_path( posixpath.dirname(pathutils.strip_path(path)), True) parent_item = next(self.Collection.discover(parent_path), None) if not parent_item: return httputils.CONFLICT if (not isinstance(parent_item, storage.BaseCollection) or parent_item.get_meta("tag")): return httputils.FORBIDDEN try: self.Collection.create_collection(path, props=props) except ValueError as e: logger.warning( "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST return client.CREATED, {}, None
def do_MKCALENDAR(self, environ, read_collections, write_collections, content, user): """Manage MKCALENDAR request.""" _logger.info('do_MKCALENDAR %s %s' % (content, user)) if not len(write_collections): return NOT_ALLOWED collection = write_collections[0] props = xmlutils.props_from_request(content) timezone = props.get("C:calendar-timezone") if timezone: collection.replace("", timezone) del props["C:calendar-timezone"] with collection.props as collection_props: for key, value in props.items(): collection_props[key] = value collection.write() return client.CREATED, {}, None