/** * This method is responsible for handling the 'ACL' event. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpAcl(RequestInterface $request, ResponseInterface $response) { $path = $request->getPath(); $body = $request->getBodyAsString(); $dom = DAV\XMLUtil::loadDOMDocument($body); $newAcl = Property\Acl::unserialize($dom->firstChild, $this->server->propertyMap)->getPrivileges(); // Normalizing urls foreach ($newAcl as $k => $newAce) { $newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']); } $node = $this->server->tree->getNodeForPath($path); if (!$node instanceof IACL) { throw new DAV\Exception\MethodNotAllowed('This node does not support the ACL method'); } $oldAcl = $this->getACL($node); $supportedPrivileges = $this->getFlatPrivilegeSet($node); /* Checking if protected principals from the existing principal set are not overwritten. */ foreach ($oldAcl as $oldAce) { if (!isset($oldAce['protected']) || !$oldAce['protected']) { continue; } $found = false; foreach ($newAcl as $newAce) { if ($newAce['privilege'] === $oldAce['privilege'] && $newAce['principal'] === $oldAce['principal'] && $newAce['protected']) { $found = true; } } if (!$found) { throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request'); } } foreach ($newAcl as $newAce) { // Do we recognize the privilege if (!isset($supportedPrivileges[$newAce['privilege']])) { throw new Exception\NotSupportedPrivilege('The privilege you specified (' . $newAce['privilege'] . ') is not recognized by this server'); } if ($supportedPrivileges[$newAce['privilege']]['abstract']) { throw new Exception\NoAbstract('The privilege you specified (' . $newAce['privilege'] . ') is an abstract privilege'); } // Looking up the principal try { $principal = $this->server->tree->getNodeForPath($newAce['principal']); } catch (DAV\Exception\NotFound $e) { throw new Exception\NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist'); } if (!$principal instanceof IPrincipal) { throw new Exception\NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal'); } } $node->setACL($newAcl); $response->setStatus(200); // Breaking the event chain, because we handled this method. return false; }
/** * @expectedException Sabre\DAV\Exception\BadRequest */ function testUnserializeMissingPriv() { $source = '<?xml version="1.0"?> <d:root xmlns:d="DAV:"> <d:ace> <d:grant> <d:privilege /> </d:grant> <d:principal><d:href>/principals/evert</d:href></d:principal> </d:ace> </d:root> '; $dom = DAV\XMLUtil::loadDOMDocument($source); Acl::unserialize($dom->firstChild, array()); }