/**
  * Implementing Principal Match
  * 
  * @param DOMDocument $dom
  */
 public function principalMatch(DOMDocument $dom)
 {
     $xml = array(array('href' => 'principals/users/' . Tinebase_Core::getUser()->contact_id));
     $this->server->httpResponse->sendStatus(207);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->httpResponse->sendBody($this->server->generateMultiStatus($xml));
 }
Example #2
0
 /**
  * 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));
 }
Example #3
0
 /**
  * This function handles the addressbook-query REPORT
  *
  * This report is used by the client to filter an addressbook based on a
  * complex query.
  *
  * @param \DOMNode $dom
  * @return void
  */
 protected function addressbookQueryReport($dom)
 {
     $query = new AddressBookQueryParser($dom);
     $query->parse();
     $depth = $this->server->getHTTPDepth(0);
     if ($depth == 0) {
         $candidateNodes = [$this->server->tree->getNodeForPath($this->server->getRequestUri())];
         if (!$candidateNodes[0] instanceof ICard) {
             throw new ReportNotSupported('The addressbook-query report is not supported on this url with Depth: 0');
         }
     } else {
         $candidateNodes = $this->server->tree->getChildren($this->server->getRequestUri());
     }
     $xpath = new \DOMXPath($dom);
     $xpath->registerNameSpace('card', Plugin::NS_CARDDAV);
     $xpath->registerNameSpace('dav', 'urn:DAV');
     $contentType = $xpath->evaluate("string(/card:addressbook-query/dav:prop/card:address-data/@content-type)");
     $version = $xpath->evaluate("string(/card:addressbook-query/dav:prop/card:address-data/@version)");
     if ($version) {
         $contentType .= '; version=' . $version;
     }
     $vcardType = $this->negotiateVCard($contentType);
     $validNodes = [];
     foreach ($candidateNodes as $node) {
         if (!$node instanceof ICard) {
             continue;
         }
         $blob = $node->get();
         if (is_resource($blob)) {
             $blob = stream_get_contents($blob);
         }
         if (!$this->validateFilters($blob, $query->filters, $query->test)) {
             continue;
         }
         $validNodes[] = $node;
         if ($query->limit && $query->limit <= count($validNodes)) {
             // We hit the maximum number of items, we can stop now.
             break;
         }
     }
     $result = [];
     foreach ($validNodes as $validNode) {
         if ($depth == 0) {
             $href = $this->server->getRequestUri();
         } else {
             $href = $this->server->getRequestUri() . '/' . $validNode->getName();
         }
         list($props) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
         if (isset($props[200]['{' . self::NS_CARDDAV . '}address-data'])) {
             $props[200]['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard($props[200]['{' . self::NS_CARDDAV . '}address-data'], $vcardType);
         }
         $result[] = $props;
     }
     $prefer = $this->server->getHTTPPRefer();
     $this->server->httpResponse->setStatus(207);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
     $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 }
 /**
  * This method handles the PROPFIND method.
  *
  * It's a very lazy method, it won't bother checking the request body
  * for which properties were requested, and just sends back a default
  * set of properties.
  *
  * @param RequestInterface $request
  * @param ResponseInterface $hR
  * @param string $tempLocation
  * @return bool
  */
 function httpPropfind(RequestInterface $request, ResponseInterface $hR, $tempLocation)
 {
     if (!file_exists($tempLocation)) {
         return;
     }
     $hR->setHeader('X-Sabre-Temp', 'true');
     $hR->setStatus(207);
     $hR->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $properties = ['href' => $request->getPath(), 200 => ['{DAV:}getlastmodified' => new Xml\Property\GetLastModified(filemtime($tempLocation)), '{DAV:}getcontentlength' => filesize($tempLocation), '{DAV:}resourcetype' => new Xml\Property\ResourceType(null), '{' . Server::NS_SABREDAV . '}tempFile' => true]];
     $data = $this->server->generateMultiStatus([$properties]);
     $hR->setBody($data);
     return false;
 }
Example #5
0
 /**
  * principalPropertySearchReport
  *
  * This method is responsible for handing the
  * {DAV:}principal-property-search report. This report can be used for
  * clients to search for groups of principals, based on the value of one
  * or more properties.
  *
  * @param \DOMDocument $dom
  * @return void
  */
 protected function principalPropertySearchReport(\DOMDocument $dom)
 {
     list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet, $test) = $this->parsePrincipalPropertySearchReportRequest($dom);
     $uri = null;
     if (!$applyToPrincipalCollectionSet) {
         $uri = $this->server->getRequestUri();
     }
     $result = $this->principalSearch($searchProperties, $requestedProperties, $uri, $test);
     $prefer = $this->server->getHTTPPRefer();
     $this->server->httpResponse->setStatus(207);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
     $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 }
 /**
  * This method handles the PROPFIND method.
  *
  * It's a very lazy method, it won't bother checking the request body
  * for which properties were requested, and just sends back a default
  * set of properties.
  *
  * @param string $tempLocation
  * @param string $uri
  * @return bool
  */
 public function httpPropfind($tempLocation, $uri)
 {
     if (!file_exists($tempLocation)) {
         return true;
     }
     $hR = $this->server->httpResponse;
     $hR->setHeader('X-Sabre-Temp', 'true');
     $hR->sendStatus(207);
     $hR->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true));
     $properties = array('href' => $uri, 200 => array('{DAV:}getlastmodified' => new Property\GetLastModified(filemtime($tempLocation)), '{DAV:}getcontentlength' => filesize($tempLocation), '{DAV:}resourcetype' => new Property\ResourceType(null), '{' . Server::NS_SABREDAV . '}tempFile' => true));
     $data = $this->server->generateMultiStatus(array($properties));
     $hR->sendBody($data);
     return false;
 }
Example #7
0
 /**
  * principalPropertySearchReport
  *
  * This method is responsible for handing the
  * {DAV:}principal-property-search report. This report can be used for
  * clients to search for groups of principals, based on the value of one
  * or more properties.
  *
  * @param Xml\Request\PrincipalPropertySearchReport $report
  * @return void
  */
 protected function principalPropertySearchReport($report)
 {
     $uri = null;
     if (!$report->applyToPrincipalCollectionSet) {
         $uri = $this->server->httpRequest->getPath();
     }
     if ($this->server->getHttpDepth('0') !== 0) {
         throw new BadRequest('Depth must be 0');
     }
     $result = $this->principalSearch($report->searchProperties, $report->properties, $uri, $report->test);
     $prefer = $this->server->getHTTPPrefer();
     $this->server->httpResponse->setStatus(207);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
     $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return'] === 'minimal'));
 }
Example #8
0
 /**
  * This function handles the addressbook-query REPORT
  *
  * This report is used by the client to filter an addressbook based on a
  * complex query.
  *
  * @param \DOMNode $dom
  * @return void
  */
 protected function addressbookQueryReport($dom)
 {
     $query = new AddressBookQueryParser($dom);
     $query->parse();
     $depth = $this->server->getHTTPDepth(0);
     if ($depth == 0) {
         $candidateNodes = array($this->server->tree->getNodeForPath($this->server->getRequestUri()));
     } else {
         $candidateNodes = $this->server->tree->getChildren($this->server->getRequestUri());
     }
     $validNodes = array();
     foreach ($candidateNodes as $node) {
         if (!$node instanceof ICard) {
             continue;
         }
         $blob = $node->get();
         if (is_resource($blob)) {
             $blob = stream_get_contents($blob);
         }
         if (!$this->validateFilters($blob, $query->filters, $query->test)) {
             continue;
         }
         $validNodes[] = $node;
         if ($query->limit && $query->limit <= count($validNodes)) {
             // We hit the maximum number of items, we can stop now.
             break;
         }
     }
     $result = array();
     foreach ($validNodes as $validNode) {
         if ($depth == 0) {
             $href = $this->server->getRequestUri();
         } else {
             $href = $this->server->getRequestUri() . '/' . $validNode->getName();
         }
         list($result[]) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
     }
     $prefer = $this->server->getHTTPPRefer();
     $this->server->httpResponse->sendStatus(207);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
     $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
     $this->server->httpResponse->sendBody($this->server->generateMultiStatus($result, $prefer['return-minimal']));
 }