[CalendarServer-changes] [86] CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method

source_changes at macosforge.org source_changes at macosforge.org
Wed Aug 30 13:03:45 PDT 2006


Revision: 86
Author:   cdaboo at apple.com
Date:     2006-08-30 13:03:39 -0700 (Wed, 30 Aug 2006)

Log Message:
-----------
Fixes to defer operations in reports for new twisted branch merge.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_calquery.py
    CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_common.py
    CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_freebusy.py
    CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_multiget.py

Modified: CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_calquery.py
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_calquery.py	2006-08-30 20:00:15 UTC (rev 85)
+++ CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_calquery.py	2006-08-30 20:03:39 UTC (rev 86)
@@ -24,6 +24,7 @@
 
 __all__ = ["report_urn_ietf_params_xml_ns_caldav_calendar_query"]
 
+from twisted.internet.defer import deferredGenerator, succeed, waitForDeferred
 from twisted.python import log
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
@@ -32,6 +33,7 @@
 from twisted.web2.dav.method.report import NumberOfMatchesWithinLimits
 from twisted.web2.dav.method.report import max_number_of_matches
 from twisted.web2.dav.util import joinURL
+from twisted.web2.http import HTTPError, StatusResponse
 
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.method import report_common
@@ -43,7 +45,7 @@
     """
     if not self.isCollection() and not self.locateParent(request, request.uri).isPseudoCalendarCollection():
         log.err("calendar-query report is not allowed on a resource outside of a calendar collection %s" % (self,))
-        return responsecode.FORBIDDEN
+        raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Must be calendar collection or calendar resource"))
 
     if calendar_query.qname() != (caldav_namespace, "calendar-query"):
         raise ValueError("{CalDAV:}calendar-query expected as root element, not %s." % (calendar_query.sname(),))
@@ -59,7 +61,7 @@
     query_tz = calendar_query.timezone
     if query_tz is not None and not query_tz.valid():
         log.err("CalDAV:timezone must contain one VTIMEZONE component only: %s" % (query_tz,))
-        return ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data"))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
     if query_tz:
         filter.settimezone(query_tz)
 
@@ -76,7 +78,7 @@
         result, message = report_common.validPropertyListCalendarDataTypeVersion(query)
         if not result:
             log.err(message)
-            return ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "supported-calendar-data"))
+            raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "supported-calendar-data")))
         
     else:
         raise AssertionError("We shouldn't be here")
@@ -84,7 +86,7 @@
     # Verify that the filter element is valid
     if (filter is None) or not filter.valid():
         log.err("Invalid filter element: %r" % (filter,))
-        return ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-filter"))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-filter")))
 
     matchcount = [0]
     def doQuery(calresource, uri):
@@ -115,52 +117,86 @@
                 else:
                     href = davxml.HRef.fromString(uri)
             
-                report_common.responseForHref(request, responses, href, resource, calendar, propertiesForResource, query)
+                return report_common.responseForHref(request, responses, href, resource, calendar, propertiesForResource, query)
+            else:
+                return succeed(None)
     
         # Check whether supplied resource is a calendar or a calendar object resource
         if calresource.isPseudoCalendarCollection():
             # Get the timezone property from the collection if one was not set in the query,
             # and store in the query filter for later use
-            if query_tz is None and calresource.hasProperty((caldav_namespace, "calendar-timezone"), request):
-                tz = calresource.readProperty((caldav_namespace, "calendar-timezone"), request)
+            has_prop = waitForDeferred(calresource.hasProperty((caldav_namespace, "calendar-timezone"), request))
+            yield has_prop
+            has_prop = has_prop.getResult()
+            if query_tz is None and has_prop:
+                tz = waitForDeferred(calresource.readProperty((caldav_namespace, "calendar-timezone"), request))
+                yield tz
+                tz = tz.getResult()
                 filter.settimezone(tz)
 
             # Do some optimisation of access control calculation by determining any inherited ACLs outside of
             # the child resource loop and supply those to the checkAccess on each child.
-            filteredaces = calresource.inheritedACEsforChildren(request)
+            filteredaces = waitForDeferred(calresource.inheritedACEsforChildren(request))
+            yield filteredaces
+            filteredaces = filteredaces.getResult()
         
             # Check for disabled access
             if filteredaces is not None:
                 for name, uid, type in calresource.index().search(filter): #@UnusedVariable
                     # Check privileges - must have at least DAV:read
-                    child = calresource.getChild(name)
-                    error = child.checkAccess(request, (davxml.Read(),), inheritedaces=filteredaces)
+                    child_url = joinURL(uri, name)
+                    child = waitForDeferred(request.locateResource(child_url))
+                    yield child
+                    child = child.getResult()
+
+                    error = waitForDeferred(child.checkAccess(request, (davxml.Read(),), inheritedaces=filteredaces))
+                    yield error
+                    error = error.getResult()
                     if error:
                         continue
     
                     calendar = calresource.iCalendar(name)
                     assert calendar is not None, "Calendar %s is missing from calendar collection %r" % (name, self)
                     
-                    queryCalendarObjectResource(calresource.getChild(name), uri, name, calendar)
+                    d = waitForDeferred(queryCalendarObjectResource(child, uri, name, calendar))
+                    yield d
+                    d.getResult()
         else:
             # Get the timezone property from the collection if one was not set in the query,
             # and store in the query object for later use
             if query_tz is None:
-                parent = calresource.locateParent(request, uri)
+
+                parent = waitForDeferred(calresource.locateParent(request, uri))
+                yield parent
+                parent = parent.getResult()
                 assert parent is not None and parent.isPseudoCalendarCollection()
-                if parent.hasProperty((caldav_namespace, "calendar-timezone"), request):
-                    tz = parent.readProperty((caldav_namespace, "calendar-timezone"), request)
+
+                has_prop = waitForDeferred(parent.hasProperty((caldav_namespace, "calendar-timezone"), request))
+                yield has_prop
+                has_prop = has_prop.getResult()
+                if has_prop:
+                    tz = waitForDeferred(parent.readProperty((caldav_namespace, "calendar-timezone"), request))
+                    yield tz
+                    tz = tz.getResult()
                     filter.settimezone(tz)
 
             calendar = calresource.iCalendar()
-            queryCalendarObjectResource(calresource, uri, None, calendar)
+            d = waitForDeferred(queryCalendarObjectResource(calresource, uri, None, calendar))
+            yield d
+            d.getResult()
 
+    doQuery = deferredGenerator(doQuery)
+
     # Run report taking depth into account
     try:
         depth = request.headers.getHeader("depth", "0")
-        report_common.applyToCalendarCollections(self, request, request.uri, depth, doQuery, (davxml.Read(),))
+        d = waitForDeferred(report_common.applyToCalendarCollections(self, request, request.uri, depth, doQuery, (davxml.Read(),)))
+        yield d
+        d.getResult()
     except NumberOfMatchesWithinLimits:
         log.err("Too many matching components in calendar-query report")
-        return ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits"))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits")))
     
-    return MultiStatusResponse(responses)
+    yield MultiStatusResponse(responses)
+
+report_urn_ietf_params_xml_ns_caldav_calendar_query = deferredGenerator(report_urn_ietf_params_xml_ns_caldav_calendar_query)

Modified: CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_common.py	2006-08-30 20:00:15 UTC (rev 85)
+++ CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_common.py	2006-08-30 20:03:39 UTC (rev 86)
@@ -28,6 +28,7 @@
     "buildFreeBusyResult",
 ]
 
+from twisted.internet.defer import deferredGenerator, waitForDeferred
 from twisted.python import log
 from twisted.python.failure import Failure
 from twisted.web2 import responsecode
@@ -68,9 +69,9 @@
     """
 
     # First check the privilege on this resource
-    error = resource.checkAccess(request, privileges)
-    if error:
-        return
+    d = waitForDeferred(resource.checkAccess(request, privileges))
+    yield d
+    d.getResult()
 
     # When scanning we only go down as far as a calendar collection - not into one
     if resource.isPseudoCalendarCollection():
@@ -81,14 +82,20 @@
         doJoin = False
     else:
         resources = []
-        resources.extend(resource.findCalendarCollectionsWithPrivileges(depth, privileges, request))
+        d = waitForDeferred(resource.findCalendarCollections(depth, request, lambda x, y: resources.append((x, y)), privileges = privileges))
+        yield d
+        d.getResult()
         doJoin = True
         
     for calresource, uri in resources:
         if doJoin:
             uri = joinURL(request_uri, uri)
-        apply(calresource, uri)
+        d = waitForDeferred(apply(calresource, uri))
+        yield d
+        d.getResult()
 
+applyToCalendarCollections = deferredGenerator(applyToCalendarCollections)
+
 def responseForHref(request, responses, href, resource, calendar, propertiesForResource, propertyreq):
     """
     Create an appropriate property status response for the given resource.
@@ -104,21 +111,24 @@
     @param propertyreq: the L{PropertyContainer} element for the properties of interest.
     """
 
-    properties_by_status = propertiesForResource(request, propertyreq, resource, calendar)
-    
-    for status in properties_by_status:
-        properties = properties_by_status[status]
-        if properties:
-            responses.append(
-                davxml.PropertyStatusResponse(
-                    href,
-                    davxml.PropertyStatus(
-                        davxml.PropertyContainer(*properties),
-                        davxml.Status.fromResponseCode(status)
+    def _defer(properties_by_status):
+        for status in properties_by_status:
+            properties = properties_by_status[status]
+            if properties:
+                responses.append(
+                    davxml.PropertyStatusResponse(
+                        href,
+                        davxml.PropertyStatus(
+                            davxml.PropertyContainer(*properties),
+                            davxml.Status.fromResponseCode(status)
+                        )
                     )
                 )
-            )
 
+    d = propertiesForResource(request, propertyreq, resource, calendar)
+    d.addCallback(_defer)
+    return d
+
 def allPropertiesForResource(request, prop, resource, calendar=None): #@UnusedVariable
     """
     Return all (non-hidden) properties for the specified resource.
@@ -130,10 +140,14 @@
                      will be used to get the calendar if needed.
     @return: a map of OK and NOT FOUND property values.
     """
-    props = resource.listAllprop(request)
 
-    return _namedPropertiesForResource(request, props, resource, calendar)
+    def _defer(props):
+        return _namedPropertiesForResource(request, props, resource, calendar)
 
+    d = resource.listAllprop(request)
+    d.addCallback(_defer)
+    return d
+
 def propertyNamesForResource(request, prop, resource, calendar=None): #@UnusedVariable
     """
     Return property names for all properties on the specified resource.
@@ -145,11 +159,16 @@
                      will be used to get the calendar if needed.
     @return: a map of OK and NOT FOUND property values.
     """
-    properties_by_status = {
-        responsecode.OK: [propertyName(p) for p in resource.listProperties(request)]
-    }
+
+    def _defer(props):
+        properties_by_status = {
+            responsecode.OK: [propertyName(p) for p in props]
+        }
+        return properties_by_status
     
-    return properties_by_status
+    d = resource.listProperties(request)
+    d.addCallback(_defer)
+    return d
 
 def propertyListForResource(request, prop, resource, calendar=None):
     """
@@ -218,9 +237,16 @@
         else:
             qname = property
     
-        if qname in resource.listProperties(request):
+        props = waitForDeferred(resource.listProperties(request))
+        yield props
+        props = props.getResult()
+
+        if qname in props:
             try:
-                properties_by_status[responsecode.OK].append(resource.readProperty(qname, request))
+                prop = waitForDeferred(resource.readProperty(qname, request))
+                yield prop
+                prop = prop.getResult()
+                properties_by_status[responsecode.OK].append(prop)
             except:
                 f = Failure()
     
@@ -233,7 +259,9 @@
             log.err("Can't find property %r for resource %s" % (qname, request.uri))
             properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
     
-    return properties_by_status
+    yield properties_by_status
+
+_namedPropertiesForResource = deferredGenerator(_namedPropertiesForResource)
     
 def generateFreeBusyInfo(request, calresource, fbinfo, timerange, matchtotal, excludeuid=None):
     """
@@ -249,9 +277,13 @@
     """
     
     # First check the privilege on this collection
-    error = calresource.checkAccess(request, (caldavxml.ReadFreeBusy(),))
-    if error:
-        return matchtotal
+    try:
+        d = waitForDeferred(calresource.checkAccess(request, (caldavxml.ReadFreeBusy(),)))
+        yield d
+        d.getResult()
+    except:
+        yield matchtotal
+        return
 
     #
     # What we do is a fake calendar-query for VEVENT/VFREEBUSYs in the specified time-range.
@@ -276,16 +308,24 @@
 
     # Get the timezone property from the collection, and store in the query filter
     # for use during the query itself.
-    if calresource.hasProperty((caldav_namespace, "calendar-timezone"), request):
-        tz = calresource.readProperty((caldav_namespace, "calendar-timezone"), request)
+    has_prop = waitForDeferred(calresource.hasProperty((caldav_namespace, "calendar-timezone"), request))
+    yield has_prop
+    has_prop = has_prop.getResult()
+    if has_prop:
+        tz = waitForDeferred(calresource.readProperty((caldav_namespace, "calendar-timezone"), request))
+        yield tz
+        tz = tz.getResult()
     else:
         tz = None
     tzinfo = filter.settimezone(tz)
 
     # Do some optimisation of access control calculation by determining any inherited ACLs outside of
     # the child resource loop and supply those to the checkAccess on each child.
-    filteredaces = calresource.inheritedACEsforChildren(request)
+    filteredaces = waitForDeferred(calresource.inheritedACEsforChildren(request))
+    yield filteredaces
+    filteredaces = filteredaces.getResult()
 
+    uri = request.urlForResource(calresource)
     for name, uid, type in calresource.index().search(filter): #@UnusedVariable
         
         # Ignore ones of this UID
@@ -293,9 +333,16 @@
             continue
 
         # Check privileges - must have at least CalDAV:read-free-busy
-        child = calresource.getChild(name)
-        error = child.checkAccess(request, (caldavxml.ReadFreeBusy(),), inheritedaces=filteredaces)
-        if error:
+        child_url = joinURL(uri, name)
+        child = waitForDeferred(request.locateResource(child_url))
+        yield child
+        child = child.getResult()
+
+        try:
+            d = waitForDeferred(child.checkAccess(request, (caldavxml.ReadFreeBusy(),), inheritedaces=filteredaces))
+            yield d
+            d.getResult()
+        except:
             continue
 
         calendar = calresource.iCalendar(name)
@@ -314,8 +361,10 @@
             else:
                 assert "Free-busy query returned unwanted component: %s in %r", (name, calresource,)
     
-    return matchtotal
+    yield matchtotal
 
+generateFreeBusyInfo = deferredGenerator(generateFreeBusyInfo)
+
 def processEventFreeBusy(calendar, fbinfo, timerange, tzinfo):
     """
     Extract free busy data from a VEVENT component.

Modified: CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_freebusy.py
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_freebusy.py	2006-08-30 20:00:15 UTC (rev 85)
+++ CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_freebusy.py	2006-08-30 20:03:39 UTC (rev 86)
@@ -24,12 +24,13 @@
 
 __all__ = ["report_urn_ietf_params_xml_ns_caldav_free_busy_query"]
 
+from twisted.internet.defer import deferredGenerator, waitForDeferred
 from twisted.python import log
 from twisted.web2 import responsecode
 from twisted.web2.dav.element.base import dav_namespace
 from twisted.web2.dav.http import ErrorResponse
 from twisted.web2.dav.method.report import NumberOfMatchesWithinLimits
-from twisted.web2.http import Response
+from twisted.web2.http import HTTPError, Response, StatusResponse
 from twisted.web2.http_headers import MimeType
 from twisted.web2.stream import MemoryStream
 
@@ -43,14 +44,14 @@
     """
     if not self.isCollection():
         log.err("freebusy report is only allowed on collection resources %s" % (self,))
-        return responsecode.FORBIDDEN
+        raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Not a calendar collection"))
 
     if freebusy.qname() != (caldavxml.caldav_namespace, "free-busy-query"):
         raise ValueError("{CalDAV:}free-busy-query expected as root element, not %s." % (freebusy.sname(),))
 
     timerange = freebusy.timerange
     if not timerange.valid():
-        return responsecode.BAD_REQUEST
+        raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Invalid time-range specified"))
 
     # First list is BUSY, second BUSY-TENTATIVE, third BUSY-UNAVAILABLE
     fbinfo = ([], [], [])
@@ -63,15 +64,21 @@
         @param calresource: the L{CalDAVFile} for a calendar collection.
         @param uri: the uri for the calendar collecton resource.
         """
-        matchcount[0] = report_common.generateFreeBusyInfo(request, calresource, fbinfo, timerange, matchcount[0])
+        d = waitForDeferred(report_common.generateFreeBusyInfo(request, calresource, fbinfo, timerange, matchcount[0]))
+        yield d
+        matchcount[0] = d.getResult()
     
+    generateFreeBusyInfo = deferredGenerator(generateFreeBusyInfo)
+
     # Run report taking depth into account
     try:
         depth = request.headers.getHeader("depth", "0")
-        report_common.applyToCalendarCollections(self, request, request.uri, depth, generateFreeBusyInfo, (caldavxml.ReadFreeBusy(),))
+        d = waitForDeferred(report_common.applyToCalendarCollections(self, request, request.uri, depth, generateFreeBusyInfo, (caldavxml.ReadFreeBusy(),)))
+        yield d
+        d.getResult()
     except NumberOfMatchesWithinLimits:
         log.err("Too many matching components in free-busy report")
-        return ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits"))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits")))
     
     # Now build a new calendar object with the free busy info we have
     fbcalendar = report_common.buildFreeBusyResult(fbinfo, timerange)
@@ -80,4 +87,6 @@
     response.stream = MemoryStream(str(fbcalendar))
     response.headers.setHeader("content-type", MimeType.fromString("text/calendar; charset=utf-8"))
 
-    return response
+    yield response
+
+report_urn_ietf_params_xml_ns_caldav_free_busy_query = deferredGenerator(report_urn_ietf_params_xml_ns_caldav_free_busy_query)
\ No newline at end of file

Modified: CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_multiget.py
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_multiget.py	2006-08-30 20:00:15 UTC (rev 85)
+++ CalendarServer/branches/users/cdaboo/acl-merge/twistedcaldav/method/report_multiget.py	2006-08-30 20:03:39 UTC (rev 86)
@@ -24,12 +24,14 @@
 
 __all__ = ["report_urn_ietf_params_xml_ns_caldav_calendar_multiget"]
 
+from twisted.internet.defer import deferredGenerator, waitForDeferred
 from twisted.python import log
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
 from twisted.web2.dav.element.base import dav_namespace
 from twisted.web2.dav.http import ErrorResponse, MultiStatusResponse
 from twisted.web2.dav.method.report import max_number_of_matches
+from twisted.web2.http import HTTPError, StatusResponse
 
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.method import report_common
@@ -39,13 +41,20 @@
     Generate a multiget REPORT.
     (CalDAV-access-09, section 7.7)
     """
-    if not self.isCollection() and not self.locateParent(request, request.uri).isPseudoCalendarCollection():
-        log.err("calendar-multiget report is not allowed on a resource outside of a calendar collection %s" % (self,))
-        return responsecode.FORBIDDEN
 
+    # Verify root element
     if multiget.qname() != (caldav_namespace, "calendar-multiget"):
         raise ValueError("{CalDAV:}calendar-multiget expected as root element, not %s." % (multiget.sname(),))
 
+    # Make sure target resource is of the right type
+    if not self.isCollection():
+        parent = waitForDeferred(self.locateParent(request, request.uri))
+        yield parent
+        parent = parent.getresult()
+        if not parent.isPseudoCalendarCollection():
+            log.err("calendar-multiget report is not allowed on a resource outside of a calendar collection %s" % (self,))
+            raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "Must be calendar resource"))
+
     responses = []
 
     propertyreq = multiget.property
@@ -64,14 +73,14 @@
         result, message = report_common.validPropertyListCalendarDataTypeVersion(propertyreq)
         if not result:
             log.err(message)
-            return ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "supported-calendar-data"))
+            raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "supported-calendar-data")))
     else:
         raise AssertionError("We shouldn't be here")
 
     # Check size of results is within limit
     if len(resources) > max_number_of_matches:
         log.err("Too many results in multiget report: %d" % len(resources))
-        return ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits"))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (dav_namespace, "number-of-matches-within-limits")))
 
     """
     Three possibilities exist:
@@ -94,7 +103,9 @@
 
         # Do some optimisation of access control calculation by determining any inherited ACLs outside of
         # the child resource loop and supply those to the checkAccess on each child.
-        filteredaces = self.inheritedACEsforChildren(request)
+        filteredaces = waitForDeferred(self.inheritedACEsforChildren(request))
+        yield filteredaces
+        filteredaces = filteredaces.getResult()
     
         # Check for disabled access
         if filteredaces is None:
@@ -113,9 +124,9 @@
             # Do href checks
             if requestURIis == "calendar":
                 # Verify that href is an immediate child of the request URI and that resource exists.
-                resource = str(href)
-                name = resource[resource.rfind("/") + 1:]
-                if not self._isChildURI(request, resource) or self.getChild(name) is None:
+                resource_uri = str(href)
+                name = resource_uri[resource_uri.rfind("/") + 1:]
+                if not self._isChildURI(request, resource_uri) or self.getChild(name) is None:
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_FOUND)))
                     continue
                 
@@ -124,44 +135,63 @@
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
                     continue
                 
-                child = self.getChild(name)
+                child = waitForDeferred(request.locateResource(resource_uri))
+                yield child
+                child = child.getResult()
     
             elif requestURIis == "collection":
-                resource = str(href)
-                name = resource[resource.rfind("/") + 1:]
-                if not self._isChildURI(request, resource, False):
+                resource_uri = str(href)
+                name = resource_uri[resource_uri.rfind("/") + 1:]
+                if not self._isChildURI(request, resource_uri, False):
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_FOUND)))
                     continue
-                child = self.locateSiblingResource(request, resource)
+ 
+                child = waitForDeferred(request.locateResource(resource_uri))
+                yield child
+                child = child.getResult()
+
                 if not child or not child.exists():
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_FOUND)))
                     continue
-                parent = child.locateParent(request, resource)
+
+                parent = waitForDeferred(child.locateParent(request, resource_uri))
+                yield parent
+                parent = parent.getResult()
+
                 if not parent.isCalendarCollection() or not parent.index().resourceExists(name):
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
                     continue
                 
                 # Check privileges on parent - must have at least DAV:read
-                error = parent.checkAccess(request, (davxml.Read(),))
-                if error:
+                try:
+                    d = waitForDeferred(parent.checkAccess(request, (davxml.Read(),)))
+                    yield d
+                    d.getResult()
+                except:
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
                     continue
                 
-                # Cache the last parents inherited aces for checkAccess optimization
+                # Cache the last parent's inherited aces for checkAccess optimization
                 if lastParent != parent:
                     lastParent = parent
             
                     # Do some optimisation of access control calculation by determining any inherited ACLs outside of
                     # the child resource loop and supply those to the checkAccess on each child.
-                    filteredaces = parent.inheritedACEsforChildren(request)
+                    filteredaces = waitForDeferred(parent.inheritedACEsforChildren(request))
+                    yield filteredaces
+                    filteredaces = filteredaces.getResult()
     
             else:
-                resource = str(href)
-                name = resource[resource.rfind("/") + 1:]
-                if (resource != request.uri) or not self.exists():
+                resource_uri = str(href)
+                name = resource_uri[resource_uri.rfind("/") + 1:]
+                if (resource_uri != request.uri) or not self.exists():
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_FOUND)))
                     continue
-                parent = self.locateParent(request, resource)
+
+                parent = waitForDeferred(self.locateParent(request, resource_uri))
+                yield parent
+                parent = parent.getResult()
+
                 if not parent.isPseudoCalendarCollection() or not parent.index().resourceExists(name):
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
                     continue
@@ -169,14 +199,23 @@
         
                 # Do some optimisation of access control calculation by determining any inherited ACLs outside of
                 # the child resource loop and supply those to the checkAccess on each child.
-                filteredaces = parent.inheritedACEsforChildren(request)
+                filteredaces = waitForDeferred(parent.inheritedACEsforChildren(request))
+                yield filteredaces
+                filteredaces = filteredaces.getResult()
     
             # Check privileges - must have at least DAV:read
-            error = child.checkAccess(request, (davxml.Read(),), inheritedaces=filteredaces)
-            if error:
+            try:
+                d = waitForDeferred(child.checkAccess(request, (davxml.Read(),), inheritedaces=filteredaces))
+                yield d
+                d.getResult()
+            except:
                 responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.NOT_ALLOWED)))
                 continue
     
-            report_common.responseForHref(request, responses, href, child, None, propertiesForResource, propertyreq)
+            d = waitForDeferred(report_common.responseForHref(request, responses, href, child, None, propertiesForResource, propertyreq))
+            yield d
+            d.getResult()
 
-    return MultiStatusResponse(responses)
+    yield MultiStatusResponse(responses)
+
+report_urn_ietf_params_xml_ns_caldav_calendar_multiget = deferredGenerator(report_urn_ietf_params_xml_ns_caldav_calendar_multiget)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20060830/c115d328/attachment.html


More information about the calendarserver-changes mailing list