/** * Performs unlocking. * * Performs a PROPFIND request with the $depth of the lock with $token on * the given $path (which must be the lock base). All affected resources * get the neccessary properties updated to reflect the change. Lock null * resources in the lock are removed. * * @param ezcWebdavUnlockRequest $request * @param string $token * @param int $depth * @return ezcWebdavResponse */ protected function performUnlock(ezcWebdavUnlockRequest $request, $token, $depth) { $path = $request->requestUri; $backend = ezcWebdavServer::getInstance()->backend; // Find alle resources affected by the unlock, including affected properties $propFindReq = new ezcWebdavPropFindRequest($path); $propFindReq->prop = new ezcWebdavBasicPropertyStorage(); $propFindReq->prop->attach(new ezcWebdavLockDiscoveryProperty()); ezcWebdavLockTools::cloneRequestHeaders($request, $propFindReq); $propFindReq->setHeader('Depth', $depth); $propFindReq->validateHeaders(); $propFindMultistatusRes = $backend->propFind($propFindReq); // Remove lock information for the lock identified by $token from each affected resource foreach ($propFindMultistatusRes->responses as $propFindRes) { // Takes properties to be updated $changeProps = new ezcWebdavFlaggedPropertyStorage(); foreach ($propFindRes->responses as $propStatRes) { if ($propStatRes->status === ezcWebdavResponse::STATUS_200) { // Remove affected active lock part from lockdiscovery property if ($propStatRes->storage->contains('lockdiscovery')) { $lockDiscoveryProp = clone $propStatRes->storage->get('lockdiscovery'); foreach ($lockDiscoveryProp->activeLock as $id => $activeLock) { if ($activeLock->token == $token) { $lockDiscoveryProp->activeLock->offsetUnset($id); $changeProps->attach($lockDiscoveryProp, ezcWebdavPropPatchRequest::SET); break; } } } } } // Perform the PROPPATCH if (count($changeProps) > 0) { $propPatchReq = new ezcWebdavPropPatchRequest($propFindRes->node->path); $propPatchReq->updates = $changeProps; ezcWebdavLockTools::cloneRequestHeaders($request, $propPatchReq); $propPatchReq->validateHeaders(); $propPatchRes = $backend->propPatch($propPatchReq); if (!$propPatchRes instanceof ezcWebdavPropPatchResponse) { throw new ezcWebdavInconsistencyException("Lock token {$token} could not be unlocked on resource {$propFindRes->node->path}."); } } } return new ezcWebdavUnlockResponse(ezcWebdavResponse::STATUS_204); }
public function testProppatchResourceWithInvalidETag() { $testPath = '/collection/test.txt'; $backend = new ezcWebdavFileBackend($this->tempDir . 'backend/'); $etag = $backend->getProperty($testPath, 'getetag')->etag; // Properties to patch $newProperties = new ezcWebdavFlaggedPropertyStorage(); $newProperties->attach($p1 = new ezcWebdavGetContentTypeProperty('text/xml'), ezcWebdavPropPatchRequest::SET); $newProperties->attach($p2 = new ezcWebdavDeadProperty('foo:', 'bar', "<?xml version=\"1.0\"?>\n<bar xmlns=\"foo:\">some content</bar>\n"), ezcWebdavPropPatchRequest::SET); $req = new ezcWebdavProppatchRequest($testPath); $req->updates = $newProperties; $req->setHeader('If-None-Match', array('abc23', $etag, 'foobar')); $req->validateHeaders(); $res = $backend->propPatch($req); $this->assertEquals(new ezcWebdavErrorResponse(ezcWebdavResponse::STATUS_412, $testPath, 'If-None-Match header check failed.'), $res, 'Expected response does not match real response.', 0, 20); }
public function testPropPatchCombinedSetDeleteValidationError() { $backend = new ezcWebdavMemoryBackend(true); $backend->addContents(array('foo' => 'bar', 'bar' => array('blubb' => 'Somme blubb blubbs.'))); // First add some custom properties. $newProperties = new ezcWebdavFlaggedPropertyStorage(); $newProperties->attach($p_bar = new ezcWebdavDeadProperty('foo:', 'bar', 'some content'), ezcWebdavPropPatchRequest::SET); $newProperties->attach($p_blubb = new ezcWebdavDeadProperty('foo:', 'blubb', 'some other content'), ezcWebdavPropPatchRequest::SET); $request = new ezcWebdavPropPatchRequest('/foo'); $request->updates = $newProperties; $request->validateHeaders(); $response = $backend->proppatch($request); $resProps = new ezcWebdavBasicPropertyStorage(); $resProps->attach(new ezcWebdavDeadProperty('foo:', 'bar')); $resProps->attach(new ezcWebdavDeadProperty('foo:', 'blubb')); $this->assertEquals(new ezcWebdavPropPatchResponse(new ezcWebdavResource('/foo'), new ezcWebdavPropStatResponse($resProps)), $response, 'Expected property adding PROPPATCH response does not match real response.', 0, 20); // Then remove them again, with one live property in the middle to // check for proper failed dependency response codes. $updateProperties = new ezcWebdavFlaggedPropertyStorage(); $updateProperties->attach($p_blubb, ezcWebdavPropPatchRequest::REMOVE); $updateProperties->attach($p_length = new ezcWebdavGetContentLengthProperty(), ezcWebdavPropPatchRequest::REMOVE); // Cause validation error $p_length->length = 'not a number'; $updateProperties->attach($p_foo = new ezcWebdavDeadProperty('foo:', 'foo', 'random content'), ezcWebdavPropPatchRequest::SET); $updateProperties->attach($p_bar, ezcWebdavPropPatchRequest::REMOVE); $request = new ezcWebdavPropPatchRequest('/foo'); $request->updates = $updateProperties; $request->validateHeaders(); $response = $backend->proppatch($request); $failed = new ezcWebdavBasicPropertyStorage(); $failed->attach($p_length); $depError = new ezcWebdavBasicPropertyStorage(); $depError->attach($p_foo); $depError->attach($p_bar); $failed->rewind(); $depError->rewind(); $this->assertEquals(new ezcWebdavMultistatusResponse(new ezcWebdavPropPatchResponse(new ezcWebdavResource('/foo'), new ezcWebdavPropStatResponse(new ezcWebdavBasicPropertyStorage(), ezcWebdavResponse::STATUS_403), new ezcWebdavPropStatResponse($failed, ezcWebdavResponse::STATUS_409), new ezcWebdavPropStatResponse($depError, ezcWebdavResponse::STATUS_424))), $response, 'Expected property removing PROPPATCH response does not match real response.', 0, 20); }
public function testDeadPropertyRetrieval() { $backend = new ezcWebdavFileBackend($this->tempDir . 'backend/'); $backend->options->useMimeExts = false; $newProperties = new ezcWebdavFlaggedPropertyStorage(); $newProperties->attach($prop = new ezcWebdavDeadProperty('foo:', 'bar', "<?xml version=\"1.0\"?>\n<bar xmlns=\"foo:\">some content</bar>\n"), ezcWebdavPropPatchRequest::SET); $request = new ezcWebdavPropPatchRequest('/resource'); $request->updates = $newProperties; $request->validateHeaders(); $response = $backend->proppatch($request); $this->assertTrue(is_file($this->tempDir . 'backend/.ezc/resource.xml'), 'Expected creation of property storage.'); $request = new ezcWebdavPropFindRequest('/resource'); $request->prop = $newProperties; $request->validateHeaders(); $response = $backend->propfind($request); $responseProperty = new ezcWebdavBasicPropertyStorage(); $responseProperty->attach($prop); $responseProperty->rewind(); $expectedResponse = new ezcWebdavMultistatusResponse(new ezcWebdavPropFindResponse(new ezcWebdavResource('/resource'), new ezcWebdavPropStatResponse($responseProperty))); $this->assertEquals($expectedResponse, $response, 'Expected response does not match real response.', 0, 20); $this->assertEquals(new ezcWebdavDeadProperty('foo:', 'bar', "<?xml version=\"1.0\"?>\n<bar xmlns=\"foo:\">some content</bar>\n"), $backend->getProperty('/resource', 'bar', 'foo:')); }
public function testPropPatchCombinedSetDeleteFail() { $backend = new ezcWebdavFileBackend($this->tempDir . 'backend/'); // First add some custom properties. $newProperties = new ezcWebdavFlaggedPropertyStorage(); $newProperties->attach($p_bar = new ezcWebdavDeadProperty('foo:', 'bar', "<?xml version=\"1.0\"?>\n<bar xmlns=\"foo:\">some content</bar>\n"), ezcWebdavPropPatchRequest::SET); $newProperties->attach($p_blubb = new ezcWebdavDeadProperty('foo:', 'blubb', "<?xml version=\"1.0\"?>\n<blubb xmlns=\"foo:\">some other content</blubb>\n"), ezcWebdavPropPatchRequest::SET); $request = new ezcWebdavPropPatchRequest('/resource'); $request->updates = $newProperties; $request->validateHeaders(); $response = $backend->proppatch($request); $this->assertEquals(new ezcWebdavPropPatchResponse(new ezcWebdavResource('/resource')), $response, 'Expected property adding PROPPATCH response does not match real response.', 0, 20); // Then remove them again, with one live property in the middle to // check for proper failed dependency response codes. $updateProperties = new ezcWebdavFlaggedPropertyStorage(); $updateProperties->attach($p_blubb, ezcWebdavPropPatchRequest::REMOVE); $updateProperties->attach($p_length = new ezcWebdavGetContentLengthProperty(), ezcWebdavPropPatchRequest::REMOVE); $updateProperties->attach($p_foo = new ezcWebdavDeadProperty('foo:', 'foo', "<?xml version=\"1.0\"?>\n<foo xmlns=\"foo:\">random content</foo>\n"), ezcWebdavPropPatchRequest::SET); $updateProperties->attach($p_bar, ezcWebdavPropPatchRequest::REMOVE); $request = new ezcWebdavPropPatchRequest('/resource'); $request->updates = $updateProperties; $request->validateHeaders(); $response = $backend->proppatch($request); $failed = new ezcWebdavBasicPropertyStorage(); $failed->attach($p_length); $depError = new ezcWebdavBasicPropertyStorage(); $depError->attach($p_foo); $depError->attach($p_bar); $failed->rewind(); $depError->rewind(); $this->assertEquals(new ezcWebdavMultistatusResponse(new ezcWebdavPropPatchResponse(new ezcWebdavResource('/resource'), new ezcWebdavPropStatResponse($failed, ezcWebdavResponse::STATUS_403), new ezcWebdavPropStatResponse(new ezcWebdavBasicPropertyStorage(), ezcWebdavResponse::STATUS_409), new ezcWebdavPropStatResponse($depError, ezcWebdavResponse::STATUS_424))), $response, 'Expected property removing PROPPATCH response does not match real response.', 0, 20); }
public function testDetachMultiplePropertiesOverwrite() { $storage = new ezcWebdavFlaggedPropertyStorage(); $liveProp = new ezcWebdavGetContentLengthProperty(); $liveProp2 = new ezcWebdavGetContentLengthProperty(); $deadProp = new ezcWebdavDeadProperty('http://example.com/foo/bar', 'foobar', 'some... content'); $deadProp2 = new ezcWebdavDeadProperty('http://example.com/foo/bar', 'foobar', 'some... other content'); $storage->attach($liveProp); $storage->attach($deadProp); $this->assertAttributeEquals(array('DAV:' => array('getcontentlength' => $liveProp), 'http://example.com/foo/bar' => array('foobar' => $deadProp)), 'properties', $storage); $storage->attach($liveProp2); $this->assertAttributeEquals(array('DAV:' => array('getcontentlength' => $liveProp2), 'http://example.com/foo/bar' => array('foobar' => $deadProp)), 'properties', $storage); $storage->detach('getcontentlength'); $this->assertAttributeEquals(array('DAV:' => array(), 'http://example.com/foo/bar' => array('foobar' => $deadProp)), 'properties', $storage); $storage->detach('foobar', 'http://example.com/foo/bar'); $this->assertAttributeEquals(array('DAV:' => array(), 'http://example.com/foo/bar' => array()), 'properties', $storage); $storage->attach($deadProp2); $this->assertAttributeEquals(array('DAV:' => array(), 'http://example.com/foo/bar' => array('foobar' => $deadProp2)), 'properties', $storage); $storage->detach('foobar', 'http://example.com/foo/bar'); $this->assertAttributeEquals(array('DAV:' => array(), 'http://example.com/foo/bar' => array()), 'properties', $storage); }