Skip to content
Snippets Groups Projects
Commit acaa67c1 authored by magicfelix's avatar magicfelix
Browse files

[DAV] Fix handling multiple children with same tag

parent d65c9966
No related branches found
No related tags found
1 merge request!1147Implement read-only CalDAV and CardDAV
......@@ -39,7 +39,7 @@ class ElementHandler(RegistryObject, is_registry=True):
self.invisible = invisible
else:
self.invisible = self.__class__.invisible
self.children = {}
self.children = []
@classmethod
def get_name(cls, attrs):
......@@ -49,14 +49,11 @@ class ElementHandler(RegistryObject, is_registry=True):
"""Create instance of ElementHandler `child_class` and append to
children or return existing child."""
name = child_class.get_name(attrs)
child = child_class(self.request, self, attrs, invisible=invisible)
self.children.append(child)
self.request.current_object = child
if name not in self.children:
child = child_class(self.request, self, attrs, invisible=invisible)
self.children[name] = child
self.request.current_object = self.children[name]
return self.children[name]
return child
def process(self, stage: str, base: "DAVMultistatus", response: "DAVResponse" = None):
"""Build elements of the DAV multistatus response."""
......@@ -77,7 +74,7 @@ class ElementHandler(RegistryObject, is_registry=True):
except Http404:
response.handle_unknown(self.name)
for name, child in self.children.items():
for child in self.children:
if child is not None:
child.process(stage, base, response)
else:
......@@ -176,7 +173,8 @@ class DAVRequest(ElementHandler, ContentHandler):
if hasattr(obj, "pre_handle"):
self.current_object.pre_handle()
else:
self.current_object.children[xml_sub] = None
child = NotImplementedObject(xml_sub)
self.current_object.children.append(child)
warnings.warn(f"DAVRequest could not parse {xml_sub}.")
def endElementNS(self, name, qname):
......@@ -221,10 +219,21 @@ class DAVMultistatus:
"""
for stage in ("xml",):
for child in self.request.children.values():
for child in self.request.children:
child.process(stage, self)
class NotImplementedObject:
"""Class to represent requested props that are not implemented."""
def __init__(self, xml_sub):
self.xml_sub = xml_sub
def process(self, stage, base, response = None):
pass
class NotFoundObject:
"""Class to represent requested objects that do not exist."""
......@@ -317,7 +326,7 @@ class QueryBase:
continue
base.current_xml = response.propstats[200]
for name, child in self.children.items():
for child in self.children:
if child is not None:
child.process(stage, base, response)
elif stage == "xml":
......
......@@ -16,7 +16,7 @@ class TimeRangeFilter(ElementHandler):
def post_handle(self):
filters = {}
report_base = next(iter(self.request.children.values()))
report_base = next(iter(self.request.children))
for k, v in self.attrs.items():
if k in [(None, "start"), (None, "end")]:
......@@ -43,7 +43,7 @@ class TextMatch(ElementHandler):
]
q = Q(pk__in=[objs])
report_base = next(iter(self.request.children.values()))
report_base = next(iter(self.request.children))
if "additional_filter" in report_base.get_objects_args:
q = report_base.get_objects_args["additional_filter"] & q
......@@ -110,11 +110,7 @@ class CalDAVComp(ElementHandler):
return f"{cls.name}-{name}"
def pre_handle(self):
if self.attrs.get((None, "name")) == "VCALENDAR":
self.children = {}
self.parent.params["VTIMEZONE"] = False
elif self.attrs.get((None, "name")) == "VTIMEZONE":
if self.attrs.get((None, "name")) == "VTIMEZONE":
self.parent.parent.params["VTIMEZONE"] = True
......@@ -123,7 +119,7 @@ class Expand(ElementHandler):
def post_handle(self):
filters = {}
report_base = next(iter(self.request.children.values()))
report_base = next(iter(self.request.children))
for k, v in self.attrs.items():
if k in [(None, "start"), (None, "end")]:
......@@ -137,21 +133,23 @@ class CalendarData(ElementHandler):
def pre_handle(self):
self.params = {}
attrs = {(None, "name"): "VCALENDAR"}
vcalendar = CalDAVComp(self.request, self, attrs)
self.children[CalDAVComp.name] = vcalendar
def post_handle(self):
if not self.params:
attrs = {(None, "name"): "VCALENDAR"}
vcalendar = CalDAVComp(self.request, self, attrs)
self.children.append(vcalendar)
self.params["VTIMEZONE"] = True
self.params["VTIMEZONE"] = True
for comp_name in ("VTIMEZONE", "VEVENT"):
attrs = {(None, "name"): comp_name}
comp = CalDAVComp(self.request, self, attrs)
vcalendar.children[CalDAVComp.name] = comp
for comp_name in ("VTIMEZONE", "VEVENT"):
attrs = {(None, "name"): comp_name}
comp = CalDAVComp(self.request, self, attrs)
vcalendar.children.append(comp)
def process_xml(self, base, response):
super().process_xml(base, response)
if not self.invisible:
report_base = next(iter(base.request.children.values()))
report_base = next(iter(base.request.children))
if response.obj is not None:
objects = response.resource.objects.filter(pk=response.obj.pk)
......@@ -241,10 +239,14 @@ class ReportBase(QueryBase):
self.request.objects = self.request.resource.get_objects(**self.get_objects_args)
if Timezone.name in self.children:
timezone = self.children.get(Timezone.name)
prop = self.children.get(DAVProp.name)
calendar_data = prop.children.get(CalendarData.name)
try:
timezone = next(filter(lambda child: isinstance(child, Timezone), self.children))
except StopIteration:
timezone = None
if timezone is not None:
prop = next(filter(lambda child: isinstance(child, DAVProp), self.children))
calendar_data = next(filter(lambda child: isinstance(child, CalendarData), prop.children))
calendar_data.params["timezone"] = timezone.content
......@@ -265,6 +267,6 @@ class CalendarMultiget(ReportBase, ElementHandler):
def post_handle(self):
super().post_handle()
for child in self.children.values():
for child in self.children:
if child.name == DAVHref.name:
child.invisible = True
......@@ -94,6 +94,6 @@ class AddressbookMultiget(QueryBase, ElementHandler):
self.request.objects = []
def post_handle(self):
for child in self.children.values():
for child in self.children:
if child.name == DAVHref.name:
child.invisible = True
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment