diff --git a/lib/DAV/Locks/Plugin.php b/lib/DAV/Locks/Plugin.php index 110bfce06b..2443f204c3 100644 --- a/lib/DAV/Locks/Plugin.php +++ b/lib/DAV/Locks/Plugin.php @@ -295,6 +295,10 @@ public function afterUnbind($path) { $locks = $this->getLocks($path, $includeChildren = true); foreach ($locks as $lock) { + // don't delete a lock on a parent dir + if (0 !== strpos($lock->uri, $path)) { + continue; + } $this->unlockNode($path, $lock); } } diff --git a/tests/Sabre/DAV/Locks/PluginTest.php b/tests/Sabre/DAV/Locks/PluginTest.php index 835c17a565..fa0cccf39b 100644 --- a/tests/Sabre/DAV/Locks/PluginTest.php +++ b/tests/Sabre/DAV/Locks/PluginTest.php @@ -521,6 +521,45 @@ public function testLockDeleteSucceed() $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); } + /** + * @depends testLock + * Similar to testLockDeleteParent but don't lock the file but the Parent-DIR. + */ + public function testParentLockDelete() + { + $request = new HTTP\Request('LOCK', '/dir/'); + $request->setBody(' + + + + + http://example.org/~ejw/contact.html + +'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals(200, $this->response->status); + $lockToken = $this->response->getHeader('Lock-Token'); + + $request = new HTTP\Request('DELETE', '/dir/child.txt', [ + 'If' => '('.$lockToken.')', + ]); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals(204, $this->response->status); + + // verify that the LOCK on /dir/ itself continues to exist by unlocking: + $request = new HTTP\Request('UNLOCK', '/dir/', ['Lock-Token' => $lockToken]); + $this->server->httpRequest = $request; + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->invokeMethod($request, $this->server->httpResponse); + + $this->assertEquals(204, $this->server->httpResponse->status, 'Got an incorrect status code. Full response body: '.$this->response->getBodyAsString()); + } + /** * @depends testLock */