/** * aclPrincipalPropSet REPORT * * This method is responsible for handling the {DAV:}acl-principal-prop-set * REPORT, as defined in: * * https://tools.ietf.org/html/rfc3744#section-9.2 * * This REPORT allows a user to quickly fetch information about all * principals specified in the access control list. Most commonly this * is used to for example generate a UI with ACL rules, allowing you * to show names for principals for every entry. * * @param string $path * @param Xml\Request\AclPrincipalPropSetReport $report * @return void */ protected function aclPrincipalPropSetReport($path, Xml\Request\AclPrincipalPropSetReport $report) { if ($this->server->getHTTPDepth(0) !== 0) { throw new BadRequest('The {DAV:}acl-principal-prop-set REPORT only supports Depth 0'); } // Fetching ACL rules for the given path. We're using the property // API and not the local getACL, because it will ensure that all // business rules and restrictions are applied. $acl = $this->server->getProperties($path, '{DAV:}acl'); if (!$acl || !isset($acl['{DAV:}acl'])) { throw new Forbidden('Could not fetch ACL rules for this path'); } $principals = []; foreach ($acl['{DAV:}acl']->getPrivileges() as $ace) { if ($ace['principal'][0] === '{') { // It's not a principal, it's one of the special rules such as {DAV:}authenticated continue; } $principals[] = $ace['principal']; } $properties = $this->server->getPropertiesForMultiplePaths($principals, $report->properties); $this->server->httpResponse->setStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->setBody($this->server->generateMultiStatus($properties)); }
/** * Adds all CardDAV-specific properties * * @param DAV\PropFind $propFind * @param DAV\INode $node * @return void */ function propFindEarly(DAV\PropFind $propFind, DAV\INode $node) { $ns = '{' . self::NS_CARDDAV . '}'; if ($node instanceof IAddressBook) { $propFind->handle($ns . 'max-resource-size', $this->maxResourceSize); $propFind->handle($ns . 'supported-address-data', function () { return new Property\SupportedAddressData(); }); $propFind->handle($ns . 'supported-collation-set', function () { return new Property\SupportedCollationSet(); }); } if ($node instanceof DAVACL\IPrincipal) { $path = $propFind->getPath(); $propFind->handle('{' . self::NS_CARDDAV . '}addressbook-home-set', function () use($path) { return new DAV\Property\Href($this->getAddressBookHomeForPrincipal($path) . '/'); }); if ($this->directories) { $propFind->handle('{' . self::NS_CARDDAV . '}directory-gateway', function () { return new DAV\Property\HrefList($this->directories); }); } } if ($node instanceof ICard) { // The address-data property is not supposed to be a 'real' // property, but in large chunks of the spec it does act as such. // Therefore we simply expose it as a property. $propFind->handle('{' . self::NS_CARDDAV . '}address-data', function () use($node) { $val = $node->get(); if (is_resource($val)) { $val = stream_get_contents($val); } return $val; }); } if ($node instanceof UserAddressBooks) { $propFind->handle('{http://calendarserver.org/ns/}me-card', function () use($node) { $props = $this->server->getProperties($node->getOwner(), ['{http://sabredav.org/ns}vcard-url']); if (isset($props['{http://sabredav.org/ns}vcard-url'])) { return new DAV\Property\Href($props['{http://sabredav.org/ns}vcard-url']); } }); } }
/** * Adds all CardDAV-specific properties * * @param string $path * @param DAV\INode $node * @param array $requestedProperties * @param array $returnedProperties * @return void */ public function beforeGetProperties($path, DAV\INode $node, array &$requestedProperties, array &$returnedProperties) { if ($node instanceof DAVACL\IPrincipal) { // calendar-home-set property $addHome = '{' . self::NS_CARDDAV . '}addressbook-home-set'; if (in_array($addHome, $requestedProperties)) { $principalId = $node->getName(); $addressbookHomePath = self::ADDRESSBOOK_ROOT . '/' . $principalId . '/'; unset($requestedProperties[array_search($addHome, $requestedProperties)]); $returnedProperties[200][$addHome] = new DAV\Property\Href($addressbookHomePath); } $directories = '{' . self::NS_CARDDAV . '}directory-gateway'; if ($this->directories && in_array($directories, $requestedProperties)) { unset($requestedProperties[array_search($directories, $requestedProperties)]); $returnedProperties[200][$directories] = new DAV\Property\HrefList($this->directories); } } if ($node instanceof ICard) { // The address-data property is not supposed to be a 'real' // property, but in large chunks of the spec it does act as such. // Therefore we simply expose it as a property. $addressDataProp = '{' . self::NS_CARDDAV . '}address-data'; if (in_array($addressDataProp, $requestedProperties)) { unset($requestedProperties[$addressDataProp]); $val = $node->get(); if (is_resource($val)) { $val = stream_get_contents($val); } $returnedProperties[200][$addressDataProp] = $val; } } if ($node instanceof UserAddressBooks) { $meCardProp = '{http://calendarserver.org/ns/}me-card'; if (in_array($meCardProp, $requestedProperties)) { $props = $this->server->getProperties($node->getOwner(), array('{http://sabredav.org/ns}vcard-url')); if (isset($props['{http://sabredav.org/ns}vcard-url'])) { $returnedProperties[200][$meCardProp] = new DAV\Property\Href($props['{http://sabredav.org/ns}vcard-url']); $pos = array_search($meCardProp, $requestedProperties); unset($requestedProperties[$pos]); } } } }