[Checkins] SVN: zope.webdav/trunk/src/zope/webdav/ Improve the
handling of Unauthorized exceptions to be
Michael Kerrin
michael.kerrin at openapp.biz
Tue Aug 29 14:04:41 EDT 2006
Log message for revision 69877:
Improve the handling of Unauthorized exceptions to be
more in line with the WebDAV specification.
Changed:
U zope.webdav/trunk/src/zope/webdav/exceptions/__init__.py
U zope.webdav/trunk/src/zope/webdav/exceptions/configure.zcml
U zope.webdav/trunk/src/zope/webdav/exceptions/tests/test_simpleviews.py
U zope.webdav/trunk/src/zope/webdav/ftests/test_propfind.py
U zope.webdav/trunk/src/zope/webdav/ftests/test_proppatch.py
U zope.webdav/trunk/src/zope/webdav/propfind.py
U zope.webdav/trunk/src/zope/webdav/proppatch.py
U zope.webdav/trunk/src/zope/webdav/tests/test_propfind.py
U zope.webdav/trunk/src/zope/webdav/tests/test_proppatch.py
-=-
Modified: zope.webdav/trunk/src/zope/webdav/exceptions/__init__.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/exceptions/__init__.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/exceptions/__init__.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -68,6 +68,10 @@
class AlreadyLockedError(DAVError):
status = 423
+
+class UnauthorizedError(DAVError):
+ status = 401
+
################################################################################
#
# Multi-status error view
Modified: zope.webdav/trunk/src/zope/webdav/exceptions/configure.zcml
===================================================================
--- zope.webdav/trunk/src/zope/webdav/exceptions/configure.zcml 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/exceptions/configure.zcml 2006-08-29 18:04:40 UTC (rev 69877)
@@ -46,6 +46,13 @@
provides="zope.webdav.interfaces.IDAVErrorWidget"
/>
+ <adapter
+ factory="zope.webdav.exceptions.UnauthorizedError"
+ for="zope.security.interfaces.IUnauthorized
+ zope.webdav.interfaces.IWebDAVRequest"
+ provides="zope.webdav.interfaces.IDAVErrorWidget"
+ />
+
<!--
Some default errors that can make it back to the publisher.
-->
Modified: zope.webdav/trunk/src/zope/webdav/exceptions/tests/test_simpleviews.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/exceptions/tests/test_simpleviews.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/exceptions/tests/test_simpleviews.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -136,7 +136,15 @@
self.assertEqual(errorview.propstatdescription, "")
self.assertEqual(errorview.responsedescription, "")
+ def test_unauthorized_error(self):
+ errorview = zope.webdav.exceptions.UnauthorizedError(None, None)
+ self.assertEqual(errorview.status, 401)
+ self.assertEqual(errorview.errors, [])
+ self.assertEqual(errorview.propstatdescription, "")
+ self.assertEqual(errorview.responsedescription, "")
+
+
class DummyTemplate(object):
def __init__(self, context):
Modified: zope.webdav/trunk/src/zope/webdav/ftests/test_propfind.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/ftests/test_propfind.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/ftests/test_propfind.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -25,8 +25,32 @@
from zope import component
import zope.webdav.interfaces
+from zope.webdav.tests.test_proppatch import unauthProperty, \
+ UnauthorizedPropertyStorage, IUnauthorizedPropertyStorage
+
class PROPFINDTests(dav.DAVTestCase):
+ def setUp(self):
+ super(PROPFINDTests, self).setUp()
+
+ gsm = component.getGlobalSiteManager()
+ gsm.registerUtility(unauthProperty, name = "{DAVtest:}unauthprop")
+ unauthProperty.restricted = True
+ gsm.registerAdapter(UnauthorizedPropertyStorage,
+ (dav.IResource,
+ zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
+
+ def tearDown(self):
+ super(PROPFINDTests, self).tearDown()
+
+ gsm = component.getGlobalSiteManager()
+ gsm.unregisterUtility(unauthProperty, name = "{DAVtest:}unauthprop")
+ gsm.unregisterAdapter(UnauthorizedPropertyStorage,
+ (dav.IResource,
+ zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
+
def test_badcontent(self):
response = self.publish("/", env = {"REQUEST_METHOD": "PROPFIND"},
request_body = "some content",
@@ -449,6 +473,41 @@
self.assertMSPropertyValue(response, "{DAVtest:}exampletextprop",
text_value = "EXAMPLE TEXT PROP")
+ def test_allprop_with_include_on_unauthorized(self):
+ file = self.addResource("/r", "some content", title = "Test Resource")
+
+ body = """<?xml version="1.0" encoding="utf-8" ?>
+<propfind xmlns:D="DAV:" xmlns="DAV:">
+ <D:allprop />
+ <D:include>
+ <Dtest:unauthprop xmlns:Dtest="DAVtest:" />
+ </D:include>
+</propfind>"""
+
+ httpresponse, xmlbody = self.checkPropfind(
+ "/r", env = {"DEPTH": "0", "CONTENT_TYPE": "application/xml"},
+ properties = """<D:allprop />
+<D:include>
+ <Dtest:unauthprop xmlns:Dtest="DAVtest:" />
+</D:include>
+""")
+
+ responses = xmlbody.findall("{DAV:}response")
+ self.assertEqual(len(responses), 1)
+ response = responses[0]
+
+ hrefs = response.findall("{DAV:}href")
+ self.assertEqual(len(hrefs), 1)
+ self.assertEqual(hrefs[0].text, "http://localhost/r")
+
+ propstats = response.findall("{DAV:}propstat")
+ self.assertEqual(len(propstats), 2)
+ props = propstats[0].findall("{DAV:}prop")
+ self.assertEqual(len(props), 1)
+
+ self.assertMSPropertyValue(response, "{DAVtest:}unauthprop",
+ status = 401)
+
def test_propfind_onfile(self):
self.addFile("/testfile", "some file content", "text/plain")
httpresponse, xmlbody = self.checkPropfind(
Modified: zope.webdav/trunk/src/zope/webdav/ftests/test_proppatch.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/ftests/test_proppatch.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/ftests/test_proppatch.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -21,6 +21,7 @@
import transaction
from zope import component
+from zope.security.interfaces import Unauthorized
import dav
@@ -53,6 +54,27 @@
self.assertEqual(response.getStatus(), 422)
self.assertEqual(response.getBody(), "")
+ def test_setdisplayname_unauthorized(self):
+ file = self.addResource("/r", "some content", "Test Resource")
+
+ self.assertEqual(self.getRootFolder()["r"].title, "Test Resource")
+
+ body = """<?xml version="1.0" encoding="utf-8" ?>
+<D:propertyupdate xmlns:D="DAV:" xmlns="DAV:">
+ <D:set><D:prop>
+ <D:displayname>Test File</D:displayname>
+ </D:prop></D:set>
+</D:propertyupdate>"""
+
+ response = self.publish("/r", env = {"REQUEST_METHOD": "PROPPATCH",
+ "CONTENT_TYPE": "application/xml",
+ "CONTENT_LENGTH": len(body)},
+ request_body = body,
+ handle_errors = True)
+
+ # we need to be logged in to set the DAV:displayname property.
+ self.assertEqual(response.getStatus(), 401)
+
def test_setdisplayname(self):
set_properties = "<D:displayname>Test File</D:displayname>"
file = self.addResource("/r", "some content", "Test Resource")
Modified: zope.webdav/trunk/src/zope/webdav/propfind.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/propfind.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/propfind.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -42,6 +42,7 @@
from zope import component
from zope.app.container.interfaces import IReadContainer
from zope.app.error.interfaces import IErrorReportingUtility
+from zope.security.interfaces import Unauthorized
from zope.etree.interfaces import IEtree
import zope.webdav.utils
@@ -145,7 +146,32 @@
return responses
+ def handleException(self, proptag, exc_info, request, response):
+ error_view = component.queryMultiAdapter(
+ (exc_info[1], request), zope.webdav.interfaces.IDAVErrorWidget)
+ if error_view is None:
+ ## An unexpected error occured here. This errr should be
+ ## fixed. In order to easily debug the problem we will
+ ## log the error with the ErrorReportingUtility
+ errUtility = component.getUtility(IErrorReportingUtility)
+ errUtility.raising(exc_info, request)
+ propstat = response.getPropstat(500) # Internal Server Error
+ else:
+ propstat = response.getPropstat(error_view.status)
+ ## XXX - needs testing
+ propstat.responsedescription += error_view.propstatdescription
+ response.responsedescription += error_view.responsedescription
+
+ etree = component.getUtility(IEtree)
+ propstat.properties.append(etree.Element(proptag))
+
def renderPropnames(self, ob, req, ignore):
+ """
+ See doc string for the renderAllProperties method. Note that we don't
+ need to worry about the security in this method has the permissions on
+ the storage adapters should be enough to hide any properties that users
+ don't have permission to see.
+ """
response = zope.webdav.utils.Response(
zope.webdav.utils.getObjectURL(ob, req))
@@ -160,19 +186,49 @@
return response
def renderAllProperties(self, ob, req, include):
+ """
+ The specification says:
+
+ Properties may be subject to access control. In the case of
+ 'allprop' and 'propname' requests, if a principal does not have the
+ right to know whether a particular property exists then the property
+ MAY be silently excluded from the response.
+
+ """
response = zope.webdav.utils.Response(
zope.webdav.utils.getObjectURL(ob, req))
for davprop, adapter in \
zope.webdav.properties.getAllProperties(ob, req):
- if davprop.restricted:
- if include is None or \
- include.find("{%s}%s" %(davprop.namespace,
- davprop.__name__)) is None:
- continue
+ isIncluded = False
+ if include is not None and \
+ include.find("{%s}%s" %(davprop.namespace,
+ davprop.__name__)) is not None:
+ isIncluded = True
+ elif davprop.restricted:
+ continue
- davwidget = zope.webdav.properties.getWidget(davprop, adapter, req)
- response.addProperty(200, davwidget.render())
+ try:
+ # getWidget and render are two possible areas where the
+ # property is silently ignored because of security concerns.
+ davwidget = zope.webdav.properties.getWidget(
+ davprop, adapter, req)
+ response.addProperty(200, davwidget.render())
+ except Unauthorized:
+ if isIncluded:
+ self.handleException(
+ "{%s}%s" %(davprop.namespace, davprop.__name__),
+ sys.exc_info(), req,
+ response)
+ # Users don't have the permission to view this property and
+ # since they didn't explicitly ask for the named property
+ # we will silently ignore this property.
+ pass
+ except Exception:
+ self.handleException(
+ "{%s}%s" %(davprop.namespace, davprop.__name__),
+ sys.exc_info(), req,
+ response)
return response
@@ -180,8 +236,6 @@
response = zope.webdav.utils.Response(
zope.webdav.utils.getObjectURL(ob, req))
- etree = component.getUtility(IEtree)
-
for prop in props:
try:
davprop, adapter = zope.webdav.properties.getProperty(
@@ -189,29 +243,8 @@
davwidget = zope.webdav.properties.getWidget(
davprop, adapter, req)
propstat = response.getPropstat(200)
- rendered_el = davwidget.render()
- except Exception, error:
- exc_info = sys.exc_info()
+ propstat.properties.append(davwidget.render())
+ except Exception:
+ self.handleException(prop.tag, sys.exc_info(), req, response)
- error_view = component.queryMultiAdapter(
- (error, req), zope.webdav.interfaces.IDAVErrorWidget)
- if error_view is None:
- ## An unexpected error occured here. This errr should be
- ## fixed. In order to easily debug the problem we will
- ## log the error with the ErrorReportingUtility
- errUtility = component.getUtility(IErrorReportingUtility)
- errUtility.raising(exc_info, req)
- propstat = response.getPropstat(500) # Internal Server Error
- else:
- propstat = response.getPropstat(error_view.status)
- ## XXX - needs testing
- propstat.responsedescription += \
- error_view.propstatdescription
- response.responsedescription += \
- error_view.responsedescription
-
- rendered_el = etree.Element(prop.tag)
-
- propstat.properties.append(rendered_el)
-
return response
Modified: zope.webdav/trunk/src/zope/webdav/proppatch.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/proppatch.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/proppatch.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -27,6 +27,7 @@
import zope.webdav.interfaces
import zope.webdav.properties
from zope.etree.interfaces import IEtree
+from zope.security.interfaces import Unauthorized
class PROPPATCH(object):
@@ -76,6 +77,11 @@
self.handleSet(prop)
else:
self.handleRemove(prop)
+ except Unauthorized:
+ # If the use doesn't have the correct permission to modify
+ # a property then we need to re-raise the Unauthorized
+ # exception in order to ask the user to log in.
+ raise
except Exception, error:
isError = True
propErrors.append((prop.tag, error))
Modified: zope.webdav/trunk/src/zope/webdav/tests/test_propfind.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/tests/test_propfind.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/tests/test_propfind.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -30,6 +30,7 @@
from zope.traversing.browser.interfaces import IAbsoluteURL
from zope.app.container.interfaces import IReadContainer
from zope.app.error.interfaces import IErrorReportingUtility
+from zope.security.interfaces import IUnauthorized
import zope.webdav.properties
import zope.webdav.publisher
@@ -40,6 +41,8 @@
from zope.etree.testing import etreeSetup, etreeTearDown, assertXMLEqual
from zope.etree.interfaces import IEtree
+from test_proppatch import unauthProperty, UnauthorizedPropertyStorage, \
+ IUnauthorizedPropertyStorage
from utils import TestMultiStatusBody
class TestRequest(zope.webdav.publisher.WebDAVRequest):
@@ -300,6 +303,10 @@
name = "{DAV:}resourcetype")
gsm.registerUtility(brokenProperty, name = "{DAVtest:}brokenprop",
provided = zope.webdav.interfaces.IDAVProperty)
+ gsm.registerUtility(unauthProperty, name = "{DAVtest:}unauthprop")
+ # make sure that this property is always restricted so that we
+ # only try and render this property whenever we want to.
+ unauthProperty.restricted = True
gsm.registerAdapter(ExamplePropertyStorage,
(IResource, zope.webdav.interfaces.IWebDAVRequest),
@@ -307,6 +314,9 @@
gsm.registerAdapter(BrokenPropertyStorage,
(IResource, zope.webdav.interfaces.IWebDAVRequest),
provided = IBrokenPropertyStorage)
+ gsm.registerAdapter(UnauthorizedPropertyStorage,
+ (IResource, zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
gsm.registerAdapter(zope.webdav.coreproperties.ResourceTypeAdapter)
gsm.registerAdapter(DummyResourceURL,
@@ -327,6 +337,9 @@
gsm.registerAdapter(zope.webdav.exceptions.PropertyNotFoundError,
(zope.webdav.interfaces.IPropertyNotFound,
zope.webdav.interfaces.IWebDAVRequest))
+ gsm.registerAdapter(zope.webdav.exceptions.UnauthorizedError,
+ (IUnauthorized,
+ zope.webdav.interfaces.IWebDAVRequest))
def propfindTearDown():
etreeTearDown()
@@ -345,7 +358,8 @@
gsm.unregisterUtility(zope.webdav.coreproperties.resourcetype,
name = "{DAV:}resourcetype")
gsm.unregisterUtility(brokenProperty, name = "{DAVtest:}brokenprop",
- provided = zope.webdav.interfaces.IDAVProperty)
+ provided = zope.webdav.interfaces.IDAVProperty)
+ gsm.unregisterUtility(unauthProperty, name = "{DAVtest:}unauthprop")
gsm.unregisterAdapter(ExamplePropertyStorage,
(IResource, zope.webdav.interfaces.IWebDAVRequest),
@@ -353,6 +367,9 @@
gsm.unregisterAdapter(BrokenPropertyStorage,
(IResource, zope.webdav.interfaces.IWebDAVRequest),
provided = IBrokenPropertyStorage)
+ gsm.registerAdapter(UnauthorizedPropertyStorage,
+ (IResource, zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
gsm.unregisterAdapter(zope.webdav.coreproperties.ResourceTypeAdapter)
gsm.unregisterAdapter(DummyResourceURL,
@@ -369,6 +386,9 @@
gsm.unregisterAdapter(zope.webdav.exceptions.PropertyNotFoundError,
(zope.webdav.interfaces.IPropertyNotFound,
zope.webdav.interfaces.IWebDAVRequest))
+ gsm.unregisterAdapter(zope.webdav.exceptions.UnauthorizedError,
+ (IUnauthorized,
+ zope.webdav.interfaces.IWebDAVRequest))
gsm.unregisterAdapter(zope.webdav.widgets.ListDAVWidget,
(zope.schema.interfaces.IList,
zope.webdav.interfaces.IWebDAVRequest))
@@ -415,14 +435,16 @@
self.assertMSPropertyValue(response, "{DAVtest:}exampleintprop")
self.assertMSPropertyValue(response, "{DAV:}resourcetype")
self.assertMSPropertyValue(response, "{DAVtest:}brokenprop")
+ self.assertMSPropertyValue(response, "{DAVtest:}unauthprop")
assertXMLEqual(response, """<ns0:response xmlns:ns0="DAV:">
<ns0:href xmlns:ns0="DAV:">/resource</ns0:href>
<ns0:propstat xmlns:ns0="DAV:" xmlns:ns01="DAVtest:">
<ns0:prop xmlns:ns0="DAV:">
- <ns01:brokenprop xmlns:ns0="DAVtest:"/>
- <ns01:exampletextprop xmlns:ns0="DAVtest:"/>
- <ns01:exampleintprop xmlns:ns0="DAVtest:"/>
+ <ns1:brokenprop xmlns:ns1="DAVtest:"/>
+ <ns1:exampletextprop xmlns:ns1="DAVtest:"/>
+ <ns1:exampleintprop xmlns:ns1="DAVtest:"/>
+ <ns1:unauthprop xmlns:ns1="DAVtest:"/>
<ns0:resourcetype />
</ns0:prop>
<ns0:status xmlns:ns0="DAV:">HTTP/1.1 200 OK</ns0:status>
@@ -578,11 +600,66 @@
error = self.errUtility.errors[0]
self.assertEqual(isinstance(error[0][1], NotImplementedError), True)
+ def test_renderUnauthorizedProperty(self):
+ resource = Resource("some text", 10)
+ request = zope.webdav.publisher.WebDAVRequest(StringIO(""), {})
+ propf = PROPFIND(None, None)
+ etree = component.getUtility(IEtree)
+ props = etree.fromstring("""<prop xmlns="DAV:" xmlns:D="DAVtest:">
+<D:unauthprop />
+<D:exampletextprop />
+</prop>""")
+
+ response = propf.renderSelectedProperties(resource, request, props)
+ response = response()
+
+ # The PROPFIND method should return a 401 when the user is unauthorized
+ # to view a property.
+ self.assertMSPropertyValue(response, "{DAVtest:}exampletextprop",
+ text_value = "some text")
+ self.assertMSPropertyValue(response, "{DAVtest:}unauthprop",
+ status = 401)
+
+ # PROPFIND does catch all exceptions during the main PROPFIND method
+ # but instead we need to make sure that the renderSelectedProperties
+ # does throw the exception.
+
+ def test_renderAllProperties_unauthorized(self):
+ resource = Resource("some text", 10)
+ request = zope.webdav.publisher.WebDAVRequest(StringIO(""), {})
+ propf = PROPFIND(None, request)
+
+ # Set the unauthproperty as un-restricted so that the
+ # renderAllProperties will render all the properties.
+ unauthProperty.restricted = False
+
+ # PROPFIND does catch all exceptions during the main PROPFIND method
+ # but instead we need to make sure that the renderSelectedProperties
+ # does throw the exception.
+ response = propf.renderAllProperties(resource, request, None)
+ response = response()
+
+ self.assertEqual(len(response.findall("{DAV:}propstat")), 1)
+ self.assertEqual(len(response.findall("{DAV:}propstat/{DAV:}prop")), 1)
+
+ foundUnauthProp = False
+ for prop in response.findall("{DAV:}propstat/{DAV:}prop")[0]:
+ if prop.tag == "{DAVtest:}unauthprop":
+ foundUnauthProp = True
+
+ self.assert_(not foundUnauthProp,
+ "The unauthprop should not be included in the all " \
+ "property response since it has security restrictions.")
+
+
class PROPFINDRecuseTest(unittest.TestCase):
def setUp(self):
propfindSetUp()
+ # make sure the unauthProperty is restricted has otherwise it will
+ # break all the renderAllProperties methods.
+ unauthProperty.restricted = True
def tearDown(self):
propfindTearDown()
Modified: zope.webdav/trunk/src/zope/webdav/tests/test_proppatch.py
===================================================================
--- zope.webdav/trunk/src/zope/webdav/tests/test_proppatch.py 2006-08-29 17:50:32 UTC (rev 69876)
+++ zope.webdav/trunk/src/zope/webdav/tests/test_proppatch.py 2006-08-29 18:04:40 UTC (rev 69877)
@@ -27,6 +27,7 @@
from zope import schema
import zope.schema.interfaces
from zope.traversing.browser.interfaces import IAbsoluteURL
+from zope.security.interfaces import Unauthorized
import zope.webdav.proppatch
import zope.webdav.publisher
@@ -344,13 +345,22 @@
extratextprop = schema.Text(
title = u"Property with no storage")
+class IUnauthorizedPropertyStorage(interface.Interface):
+
+ unauthprop = schema.TextLine(
+ title = u"Property that you are not allowed to set")
+
exampleIntProperty = zope.webdav.properties.DAVProperty(
"{DAVtest:}exampleintprop", IExamplePropertyStorage)
exampleTextProperty = zope.webdav.properties.DAVProperty(
"{DAVtest:}exampletextprop", IExamplePropertyStorage)
extraTextProperty = zope.webdav.properties.DAVProperty(
"{DAVtest:}extratextprop", IExtraPropertyStorage)
+unauthProperty = zope.webdav.properties.DAVProperty(
+ "{DAVtest:}unauthprop", IUnauthorizedPropertyStorage)
+unauthProperty.restricted = True
+
class ExamplePropertyStorage(object):
interface.implements(IExamplePropertyStorage)
@@ -370,6 +380,21 @@
exampletextprop = _getproperty("text", default = u"")
+class UnauthorizedPropertyStorage(object):
+ interface.implements(IUnauthorizedPropertyStorage)
+
+ def __init__(self, context, request):
+ pass
+
+ @apply
+ def unauthprop():
+ def get(self):
+ raise Unauthorized("You are not allowed to read this property")
+ def set(self, value):
+ raise Unauthorized("You are not allowed to set this property!")
+ return property(get, set)
+
+
class PROPPATCHHandlePropertyModification(unittest.TestCase):
def setUp(self):
@@ -387,10 +412,14 @@
gsm.registerUtility(extraTextProperty,
name = "{DAVtest:}extratextprop",
provided = zope.webdav.interfaces.IDAVProperty)
+ gsm.registerUtility(unauthProperty, name = "{DAVtest:}unauthprop")
gsm.registerAdapter(ExamplePropertyStorage,
(IResource, zope.webdav.interfaces.IWebDAVRequest),
provided = IExamplePropertyStorage)
+ gsm.registerAdapter(UnauthorizedPropertyStorage,
+ (IResource, zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
gsm.registerAdapter(zope.webdav.widgets.TextDAVInputWidget,
(zope.schema.interfaces.IText,
@@ -410,11 +439,16 @@
gsm.unregisterUtility(extraTextProperty,
name = "{DAVtest:}extratextprop",
provided = zope.webdav.interfaces.IDAVProperty)
+ gsm.unregisterUtility(unauthProperty, name = "{DAVtest:}unauthprop")
gsm.unregisterAdapter(ExamplePropertyStorage,
(IResource,
zope.webdav.interfaces.IWebDAVRequest),
provided = IExamplePropertyStorage)
+ gsm.unregisterAdapter(UnauthorizedPropertyStorage,
+ (IResource,
+ zope.webdav.interfaces.IWebDAVRequest),
+ provided = IUnauthorizedPropertyStorage)
gsm.unregisterAdapter(zope.webdav.widgets.TextDAVInputWidget,
(zope.schema.interfaces.IText,
@@ -450,6 +484,18 @@
propp.handleSet,
propel)
+ def test_handleSet_unauthorized(self):
+ etree = component.getUtility(IEtree)
+ propel = etree.Element("{DAVtest:}unauthprop")
+ propel.text = "Example Text Prop"
+
+ request = TestRequest(
+ set_properties = """<Dt:unauthprop xmlns:Dt="DAVtest:">Example Text Prop</Dt:unauthprop>""")
+ resource = Resource("Text Prop", 10)
+
+ propp = zope.webdav.proppatch.PROPPATCH(resource, request)
+ self.assertRaises(Unauthorized, propp.handleSet, propel)
+
def test_handleSet_property_notfound(self):
etree = component.getUtility(IEtree)
propel = etree.Element("{DAVtest:}exampletextpropmissing")
More information about the Checkins
mailing list