[Checkins] SVN: z3c.dav/trunk/src/z3c/dav/ Add check to see if the request managed to parse the xml body to avoid

Michael Kerrin michael.kerrin at openapp.ie
Mon May 7 09:35:53 EDT 2007


Log message for revision 75611:
  Add check to see if the request managed to parse the xml body to avoid
  attribute errors.
  
  Plus the resourcetype property should be read only and the proppatch method
  should only get a property's input widget if the property is not read only.
  

Changed:
  U   z3c.dav/trunk/src/z3c/dav/coreproperties.py
  U   z3c.dav/trunk/src/z3c/dav/proppatch.py
  U   z3c.dav/trunk/src/z3c/dav/tests/test_proppatch.py

-=-
Modified: z3c.dav/trunk/src/z3c/dav/coreproperties.py
===================================================================
--- z3c.dav/trunk/src/z3c/dav/coreproperties.py	2007-05-07 11:31:35 UTC (rev 75610)
+++ z3c.dav/trunk/src/z3c/dav/coreproperties.py	2007-05-07 13:35:52 UTC (rev 75611)
@@ -237,7 +237,7 @@
                            This element MUST NOT contain text or mixed content.
                            Any custom child element is considered to be an
                            identifier for a resource type."""),
-        readonly = False)
+        readonly = True)
 
 
 class IDAVSupportedlock(interface.Interface):
@@ -410,12 +410,20 @@
 
 class ResourceTypeAdapter(object):
     """
-      >>> from zope.app.file.file import File
-      >>> file = File('some data for a file', 'text/plain')
-      >>> adapter = ResourceTypeAdapter(file, None)
+
+    All content that doesn't implement the IReadContainer interface, their
+    resourcetype value is None.
+
+      >>> class Resource(object):
+      ...    pass
+      >>> resource = Resource()
+      >>> adapter = ResourceTypeAdapter(resource, None)
       >>> adapter.resourcetype is None
       True
 
+    If a content object implements IReadContainer then it value is a list
+    of types, just 'collection' in this case.
+
       >>> from zope.app.folder.folder import Folder
       >>> folder = Folder()
       >>> adapter = ResourceTypeAdapter(folder, None)

Modified: z3c.dav/trunk/src/z3c/dav/proppatch.py
===================================================================
--- z3c.dav/trunk/src/z3c/dav/proppatch.py	2007-05-07 11:31:35 UTC (rev 75610)
+++ z3c.dav/trunk/src/z3c/dav/proppatch.py	2007-05-07 13:35:52 UTC (rev 75611)
@@ -42,7 +42,8 @@
         self.request = request
 
     def PROPPATCH(self):
-        if self.request.content_type not in ("text/xml", "application/xml"):
+        if self.request.content_type not in ("text/xml", "application/xml") \
+               or self.request.xmlDataSource is None:
             raise z3c.dav.interfaces.BadRequest(
                 self.request,
                 message = "All PROPPATCH requests needs a XML body")
@@ -122,16 +123,16 @@
         davprop, adapter = z3c.dav.properties.getProperty(
             self.context, self.request, prop.tag)
 
-        widget = z3c.dav.properties.getWidget(
-            davprop, adapter, self.request,
-            type = z3c.dav.interfaces.IDAVInputWidget)
-
+        # Not all properties have a IDAVInputWidget defined
         field = davprop.field.bind(adapter)
-
         if field.readonly:
             raise z3c.dav.interfaces.ForbiddenError(
                 self.context, prop.tag, message = u"readonly field")
 
+        widget = z3c.dav.properties.getWidget(
+            davprop, adapter, self.request,
+            type = z3c.dav.interfaces.IDAVInputWidget)
+
         value = widget.getInputValue()
         field.validate(value)
 

Modified: z3c.dav/trunk/src/z3c/dav/tests/test_proppatch.py
===================================================================
--- z3c.dav/trunk/src/z3c/dav/tests/test_proppatch.py	2007-05-07 11:31:35 UTC (rev 75610)
+++ z3c.dav/trunk/src/z3c/dav/tests/test_proppatch.py	2007-05-07 13:35:52 UTC (rev 75611)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Test WebDAV propfind method.
+"""Test WebDAV proppatch method.
 
 It is easier to do this has a unit test has we have complete control over
 what properties are defined or not.
@@ -31,6 +31,7 @@
 from zope.security.interfaces import Unauthorized
 from zope.lifecycleevent.interfaces import IObjectModifiedEvent
 
+import z3c.dav.coreproperties
 import z3c.dav.proppatch
 import z3c.dav.publisher
 import z3c.dav.interfaces
@@ -146,9 +147,17 @@
 
     def test_noxml(self):
         request = z3c.dav.publisher.WebDAVRequest(StringIO(""), {})
+        request.processInputs()
         propp = PROPPATCHHandler(Resource(), request)
         self.assertRaises(z3c.dav.interfaces.BadRequest, propp.PROPPATCH)
 
+    def test_nodata_but_xmlcontenttype(self):
+        request = z3c.dav.publisher.WebDAVRequest(
+            StringIO(""), {"CONTENT_TYPE": "application/xml"})
+        request.processInputs()
+        propp = PROPPATCHHandler(Resource(), request)
+        self.assertRaises(z3c.dav.interfaces.BadRequest, propp.PROPPATCH)
+
     def test_notxml(self):
         request = z3c.dav.publisher.WebDAVRequest(
             StringIO("content"), {"CONTENT_TYPE": "text/plain",
@@ -426,6 +435,11 @@
         gsm.registerAdapter(DummyResourceURL,
                             (IResource, z3c.dav.interfaces.IWebDAVRequest))
 
+        # PROPPATCH and the resourcetype properties highlighted a bug
+        gsm.registerUtility(z3c.dav.coreproperties.resourcetype,
+                            name = "{DAV:}resourcetype")
+        gsm.registerAdapter(z3c.dav.coreproperties.ResourceTypeAdapter)
+
         self.events = []
         zope.event.subscribers.append(self.eventLog)
 
@@ -462,6 +476,10 @@
                               (IResource,
                                z3c.dav.interfaces.IWebDAVRequest))
 
+        gsm.unregisterUtility(z3c.dav.coreproperties.resourcetype,
+                              name = "{DAV:}resourcetype")
+        gsm.unregisterAdapter(z3c.dav.coreproperties.ResourceTypeAdapter)
+
         self.events = []
         zope.event.subscribers.remove(self.eventLog)
 
@@ -610,7 +628,33 @@
         propp = z3c.dav.proppatch.PROPPATCH(resource, request)
         self.assertRaises(Unauthorized, propp.PROPPATCH)
 
+    def test_set_readonly_resourcetype(self):
+        # When trying to set a value on the `{DAV:}resourcetype` property
+        # we need to first check that the field is readonly as the resourcetype
+        # property has no input widget registered for it.
+        etree = z3c.etree.getEngine()
+        resourcetype = etree.Element("{DAV:}resourcetype")
+        resourcetype.append(etree.Element("{DAV:}collection"))
+        request = TestRequest(set_properties = """<D:resourcetype />""")
+        resource = Resource("Test prop", 10)
 
+        propp = z3c.dav.proppatch.PROPPATCH(resource, request)
+        self.assertRaises(z3c.dav.interfaces.ForbiddenError,
+                          propp.handleSet, resourcetype)
+
+    def test_set_readonly_resourcetype_samevalue(self):
+        # Make sure we get the same error as the previous test but this time
+        # trying to set the resourcetype to same value.
+        etree = z3c.etree.getEngine()
+        resourcetype = etree.Element("{DAV:}resourcetype")
+        request = TestRequest(set_properties = """<D:resourcetype />""")
+        resource = Resource("Test prop", 10)
+
+        propp = z3c.dav.proppatch.PROPPATCH(resource, request)
+        self.assertRaises(z3c.dav.interfaces.ForbiddenError,
+                          propp.handleSet, resourcetype)
+
+
 class DEADProperties(object):
     interface.implements(z3c.dav.interfaces.IOpaquePropertyStorage)
 



More information about the Checkins mailing list