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

[DAV] Add handleable but unavailable props to 404 propstat

parent 0b1624d1
No related branches found
No related tags found
1 merge request!1147Implement read-only CalDAV and CardDAV
......@@ -5,7 +5,7 @@ from xml.sax.handler import ContentHandler, feature_namespaces
from xml.sax.xmlreader import InputSource
from django.core.exceptions import BadRequest
from django.http import HttpRequest
from django.http import HttpRequest, Http404
from django.urls import reverse
from defusedxml.sax import make_parser
......@@ -72,7 +72,10 @@ class ElementHandler(RegistryObject, is_registry=True):
if hasattr(self, stage_method_name) and callable(
stage_method := getattr(self, stage_method_name)
):
stage_method(base, response)
try:
stage_method(base, response)
except Http404:
response.handle_unknown(self.name)
for name, child in self.children.items():
if child is not None:
......@@ -221,10 +224,9 @@ class DAVMultistatus:
There are the following stages, optionally implemented
by ElementHandlers using methods named `process_{stage}`:
`xml`: Build the response by adding an element to the XML tree.
`data`: Add content to the XML elements.
"""
for stage in ("xml", "data"):
for stage in ("xml",):
for child in self.request.children.values():
child.process(stage, self)
......
from datetime import datetime
from xml.etree import ElementTree
from django.http import Http404
from django.urls import reverse
from .base import ElementHandler, QueryBase
......@@ -87,7 +88,8 @@ class CalendarData(ElementHandler):
vcalendar = CalDAVComp(self.request, self, attrs)
self.children[CalDAVComp.name] = vcalendar
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
if not self.invisible:
objects = [response.obj] if response.obj is not None else []
ical = response.resource.get_dav_file_content(
......@@ -99,24 +101,30 @@ class CalendarData(ElementHandler):
class CalendarColor(ElementHandler):
name = "{http://apple.com/ns/ical/}calendar-color"
def process_data(self, base, response):
if hasattr(response.resource, "get_color"):
base.current_xml.text = response.resource.get_color()
def process_xml(self, base, response):
if not hasattr(response.resource, "get_color"):
raise Http404
super().process_xml(base, response)
base.current_xml.text = response.resource.get_color()
class CalendarDescription(ElementHandler):
name = "{urn:ietf:params:xml:ns:caldav}calendar-description"
def process_data(self, base, response):
if hasattr(response.resource, "get_description"):
response.resource.get_description()
base.current_xml.text = response.resource.get_description()
def process_xml(self, base, response):
if not hasattr(response.resource, "get_description"):
raise Http404
super().process_xml(base, response)
base.current_xml.text = response.resource.get_description()
class CalendarHomeSet(ElementHandler):
name = "{urn:ietf:params:xml:ns:caldav}calendar-home-set"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
href = ElementTree.SubElement(base.current_xml, "{DAV:}href")
href.text = reverse("dav_subregistry", args=["calendar"])
......@@ -124,7 +132,8 @@ class CalendarHomeSet(ElementHandler):
class SupportedCalendarComponentSet(ElementHandler):
name = "{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
comp = ElementTree.SubElement(base.current_xml, "{urn:ietf:params:xml:ns:caldav}comp")
comp.set("name", "VEVENT")
......
from xml.etree import ElementTree
from django.http import Http404
from django.urls import reverse
from .base import ElementHandler, QueryBase
......@@ -35,7 +36,8 @@ class AddressData(ElementHandler):
def pre_handle(self):
self.params = {}
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
if not self.invisible:
objects = [response.obj] if response.obj is not None else []
vcf = response.resource.get_dav_file_content(
......@@ -47,16 +49,20 @@ class AddressData(ElementHandler):
class AddressbookDescription(ElementHandler):
name = "{urn:ietf:params:xml:ns:carddav}addressbook-description"
def process_data(self, base, response):
if hasattr(response.resource, "get_description"):
response.resource.get_description()
base.current_xml.text = response.resource.get_description()
def process_xml(self, base, response):
if not hasattr(response.resource, "get_description"):
raise Http404
response.resource.get_description()
base.current_xml.text = response.resource.get_description()
super().process_xml(base, response)
class AddressbookHomeSet(ElementHandler):
name = "{urn:ietf:params:xml:ns:carddav}addressbook-home-set"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
href = ElementTree.SubElement(base.current_xml, "{DAV:}href")
href.text = reverse("dav_subregistry", args=["contact"])
......@@ -64,7 +70,8 @@ class AddressbookHomeSet(ElementHandler):
class SupportedAddressData(ElementHandler):
name = "{urn:ietf:params:xml:ns:carddav}supported-address-data"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
comp = ElementTree.SubElement(
base.current_xml, "{urn:ietf:params:xml:ns:carddav}address-data-type"
)
......
from xml.etree import ElementTree
from django.http import Http404
from django.urls import resolve
from ...mixins import DAVResource
......@@ -9,7 +10,8 @@ from .base import DAVMultistatus, DAVResponse, ElementHandler, QueryBase
class DAVEtag(ElementHandler):
name = "{DAV:}getetag"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
objects = [response.obj] if response.obj is not None else []
etag = response.resource.getetag(base.request._request, objects)
base.current_xml.text = f'"{etag}"'
......@@ -18,14 +20,16 @@ class DAVEtag(ElementHandler):
class DAVDisplayname(ElementHandler):
name = "{DAV:}displayname"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
base.current_xml.text = response.resource.get_dav_verbose_name()
class DAVResourcetype(ElementHandler):
name = "{DAV:}resourcetype"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
resource_types = ["{DAV:}collection"]
if not getattr(response.resource, "_is_registry", False):
resource_types += response.resource.dav_resource_types
......@@ -38,7 +42,8 @@ class DAVResourcetype(ElementHandler):
class DAVCurrentUserPrincipal(ElementHandler):
name = "{DAV:}current-user-principal"
def process_data(self, base, response):
def process_xml(self, base, response):
super().process_xml(base, response)
href = ElementTree.SubElement(base.current_xml, "{DAV:}href")
person_pk = base.request._request.user.person.pk
href.text = f"/dav/contact/person/{person_pk}.vcf" # FIXME: Implement principals
......@@ -47,22 +52,31 @@ class DAVCurrentUserPrincipal(ElementHandler):
class DAVGetcontenttype(ElementHandler):
name = "{DAV:}getcontenttype"
def process_data(self, base, response):
def process_xml(self, base, response):
resource = response.resource
if response.obj is not None:
resource = response.obj
base.current_xml.text = resource.get_dav_content_type()
content_type = resource.get_dav_content_type()
if not content_type:
raise Http404
super().process_xml(base, response)
base.current_xml.text = content_type
class DAVGetcontentlength(ElementHandler):
name = "{DAV:}getcontentlength"
def process_data(self, base, response):
def process_xml(self, base, response):
obj = response.obj
if obj is not None:
base.current_xml.text = str(
len(response.resource.get_dav_file_content(base.request._request, [obj]))
)
if obj is None:
raise Http404
super().process_xml(base, response)
base.current_xml.text = str(
len(response.resource.get_dav_file_content(base.request._request, [obj]))
)
class DAVSupportedReportSet(ElementHandler):
......
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