Commit cc5474b0 authored by Chris McDonough's avatar Chris McDonough

DAV: litmus' cond_put_corrupt_token test (#18) exposed a bug

        in webdav.Resource.dav__simpleifhandler.  If the resource is
        locked at all, and a DAV request contains an If header, and
        none of the lock tokens present in the header match a lock on
        the resource, we need to return a 423 Locked instead of 204 No
        Content.
parent 979bea8f
...@@ -97,6 +97,13 @@ Zope Changes ...@@ -97,6 +97,13 @@ Zope Changes
Bugs Fixed Bugs Fixed
- DAV: litmus' cond_put_corrupt_token test (#18) exposed a bug
in webdav.Resource.dav__simpleifhandler. If the resource is
locked at all, and a DAV request contains an If header, and
none of the lock tokens present in the header match a lock on
the resource, we need to return a 423 Locked instead of 204 No
Content.
- DAV: litmus "notowner_modify" tests warn during a MOVE request - DAV: litmus "notowner_modify" tests warn during a MOVE request
because we returned "412 Precondition Failed" instead of "423 because we returned "412 Precondition Failed" instead of "423
Locked" when the resource attempting to be moved was itself Locked" when the resource attempting to be moved was itself
......
...@@ -157,13 +157,12 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem): ...@@ -157,13 +157,12 @@ class Resource(ExtensionClass.Base, Lockable.LockableItem):
for token in wehave: self.wl_getLock(token).refresh() for token in wehave: self.wl_getLock(token).refresh()
found = 1; break found = 1; break
if resourcetagged and (not found): if resourcetagged and found:
raise PreconditionFailed, 'Condition failed.'
elif resourcetagged and found:
return 1 return 1
else: if (not resourcetagged) and (not found):
return 0 raise Locked('Resource locked and no recognized lock tokens in '
'If header')
raise PreconditionFailed('Condition failed')
# WebDAV class 1 support # WebDAV class 1 support
security.declareProtected(View, 'HEAD') security.declareProtected(View, 'HEAD')
......
...@@ -35,6 +35,13 @@ class TestResource(unittest.TestCase): ...@@ -35,6 +35,13 @@ class TestResource(unittest.TestCase):
verifyClass(IWriteLock, Resource) verifyClass(IWriteLock, Resource)
def test_MOVE_self_locked(self): def test_MOVE_self_locked(self):
"""
DAV: litmus"notowner_modify" tests warn during a MOVE request
because we returned "412 Precondition Failed" instead of "423
Locked" when the resource attempting to be moved was itself
locked. Fixed by changing Resource.Resource.MOVE to raise the
correct error.
"""
app = self.app app = self.app
request = DummyRequest({}, {}) request = DummyRequest({}, {})
response = DummyResponse() response = DummyResponse()
...@@ -49,6 +56,27 @@ class TestResource(unittest.TestCase): ...@@ -49,6 +56,27 @@ class TestResource(unittest.TestCase):
from webdav.common import Locked from webdav.common import Locked
self.assertRaises(Locked, inst.MOVE, request, response) self.assertRaises(Locked, inst.MOVE, request, response)
def test_dav__simpleifhandler_cond_put_corrupt_token(self):
"""
DAV: litmus' cond_put_corrupt_token test (#18) exposed a bug
in webdav.Resource.dav__simpleifhandler. If the resource is
locked at all, and a DAV request contains an If header, and
none of the lock tokens present in the header match a lock on
the resource, we need to return a 423 Locked instead of 204 No
Content.
"""
ifhdr = 'If: (<locktoken:foo>) (Not <DAV:no-lock>)'
request = DummyRequest({'URL':'http://example.com/foo/PUT'},
{'If':ifhdr})
response = DummyResponse()
inst = self._makeOne()
inst._dav_writelocks = {'a':DummyLock()}
from zope.interface import directlyProvides
from webdav.interfaces import IWriteLock
directlyProvides(inst, IWriteLock)
from webdav.common import Locked
self.assertRaises(Locked, inst.dav__simpleifhandler, request, response)
class DummyLock: class DummyLock:
def isValid(self): def isValid(self):
return True return True
...@@ -77,6 +105,9 @@ class DummyRequest: ...@@ -77,6 +105,9 @@ class DummyRequest:
def get(self, name, default): def get(self, name, default):
return self.form.get(name, default) return self.form.get(name, default)
def __getitem__(self, name):
return self.form[name]
def physicalPathFromURL(self, *arg): def physicalPathFromURL(self, *arg):
return [''] return ['']
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment