/**
  * 'beforeMethod' event handles. This event handles intercepts GET requests ending
  * with ?export
  *
  * @param string $method
  * @param string $uri
  * @return bool
  */
 public function beforeMethod($method, $uri)
 {
     if ($method != 'GET') {
         return;
     }
     if ($this->server->httpRequest->getQueryString() != 'export') {
         return;
     }
     // splitting uri
     list($uri) = explode('?', $uri, 2);
     $node = $this->server->tree->getNodeForPath($uri);
     if (!$node instanceof IAddressBook) {
         return;
     }
     // Checking ACL, if available.
     if ($aclPlugin = $this->server->getPlugin('acl')) {
         $aclPlugin->checkPrivileges($uri, '{DAV:}read');
     }
     $this->server->httpResponse->setHeader('Content-Type', 'text/directory');
     $this->server->httpResponse->sendStatus(200);
     $nodes = $this->server->getPropertiesForPath($uri, array('{' . Plugin::NS_CARDDAV . '}address-data'), 1);
     $this->server->httpResponse->sendBody($this->generateVCF($nodes));
     // Returning false to break the event chain
     return false;
 }
Exemple #2
0
 /**
  * Returns the standard users' principal.
  *
  * This is one authorative principal url for the current user.
  * This method will return null if the user wasn't logged in.
  *
  * @return string|null
  */
 public function getCurrentUserPrincipal()
 {
     $authPlugin = $this->server->getPlugin('auth');
     if (is_null($authPlugin)) {
         return null;
     }
     /** @var $authPlugin SabreForRainLoop\DAV\Auth\Plugin */
     $userName = $authPlugin->getCurrentUser();
     if (!$userName) {
         return null;
     }
     return $this->defaultUsernamePath . '/' . $userName;
 }
 /**
  * This event is triggered when the server didn't know how to handle a
  * certain request.
  *
  * We intercept this to handle POST requests on calendars.
  *
  * @param string $method
  * @param string $uri
  * @return null|bool
  */
 public function unknownMethod($method, $uri)
 {
     if ($method !== 'POST') {
         return;
     }
     // Only handling xml
     $contentType = $this->server->httpRequest->getHeader('Content-Type');
     if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) {
         return;
     }
     // Making sure the node exists
     try {
         $node = $this->server->tree->getNodeForPath($uri);
     } catch (DAV\Exception\NotFound $e) {
         return;
     }
     $requestBody = $this->server->httpRequest->getBody(true);
     // If this request handler could not deal with this POST request, it
     // will return 'null' and other plugins get a chance to handle the
     // request.
     //
     // However, we already requested the full body. This is a problem,
     // because a body can only be read once. This is why we preemptively
     // re-populated the request body with the existing data.
     $this->server->httpRequest->setBody($requestBody);
     $dom = DAV\XMLUtil::loadDOMDocument($requestBody);
     $documentType = DAV\XMLUtil::toClarkNotation($dom->firstChild);
     switch ($documentType) {
         // Dealing with the 'share' document, which modified invitees on a
         // calendar.
         case '{' . Plugin::NS_CALENDARSERVER . '}share':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof IShareableCalendar) {
                 return;
             }
             // Getting ACL info
             $acl = $this->server->getPlugin('acl');
             // If there's no ACL support, we allow everything
             if ($acl) {
                 $acl->checkPrivileges($uri, '{DAV:}write');
             }
             $mutations = $this->parseShareRequest($dom);
             $node->updateShares($mutations[0], $mutations[1]);
             $this->server->httpResponse->sendStatus(200);
             // Adding this because sending a response body may cause issues,
             // and I wanted some type of indicator the response was handled.
             $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
             // Breaking the event chain
             return false;
             // The invite-reply document is sent when the user replies to an
             // invitation of a calendar share.
         // The invite-reply document is sent when the user replies to an
         // invitation of a calendar share.
         case '{' . Plugin::NS_CALENDARSERVER . '}invite-reply':
             // This only works on the calendar-home-root node.
             if (!$node instanceof UserCalendars) {
                 return;
             }
             // Getting ACL info
             $acl = $this->server->getPlugin('acl');
             // If there's no ACL support, we allow everything
             if ($acl) {
                 $acl->checkPrivileges($uri, '{DAV:}write');
             }
             $message = $this->parseInviteReplyRequest($dom);
             $url = $node->shareReply($message['href'], $message['status'], $message['calendarUri'], $message['inReplyTo'], $message['summary']);
             $this->server->httpResponse->sendStatus(200);
             // Adding this because sending a response body may cause issues,
             // and I wanted some type of indicator the response was handled.
             $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
             if ($url) {
                 $dom = new \DOMDocument('1.0', 'UTF-8');
                 $dom->formatOutput = true;
                 $root = $dom->createElement('cs:shared-as');
                 foreach ($this->server->xmlNamespaces as $namespace => $prefix) {
                     $root->setAttribute('xmlns:' . $prefix, $namespace);
                 }
                 $dom->appendChild($root);
                 $href = new DAV\Property\Href($url);
                 $href->serialize($this->server, $root);
                 $this->server->httpResponse->setHeader('Content-Type', 'application/xml');
                 $this->server->httpResponse->sendBody($dom->saveXML());
             }
             // Breaking the event chain
             return false;
         case '{' . Plugin::NS_CALENDARSERVER . '}publish-calendar':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof IShareableCalendar) {
                 return;
             }
             // Getting ACL info
             $acl = $this->server->getPlugin('acl');
             // If there's no ACL support, we allow everything
             if ($acl) {
                 $acl->checkPrivileges($uri, '{DAV:}write');
             }
             $node->setPublishStatus(true);
             // iCloud sends back the 202, so we will too.
             $this->server->httpResponse->sendStatus(202);
             // Adding this because sending a response body may cause issues,
             // and I wanted some type of indicator the response was handled.
             $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
             // Breaking the event chain
             return false;
         case '{' . Plugin::NS_CALENDARSERVER . '}unpublish-calendar':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof IShareableCalendar) {
                 return;
             }
             // Getting ACL info
             $acl = $this->server->getPlugin('acl');
             // If there's no ACL support, we allow everything
             if ($acl) {
                 $acl->checkPrivileges($uri, '{DAV:}write');
             }
             $node->setPublishStatus(false);
             $this->server->httpResponse->sendStatus(200);
             // Adding this because sending a response body may cause issues,
             // and I wanted some type of indicator the response was handled.
             $this->server->httpResponse->setHeader('X-Sabre-Status', 'everything-went-well');
             // Breaking the event chain
             return false;
     }
 }