/**
  * '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 Sabre_CalDAV_Calendar) {
         return;
     }
     // Checking ACL, if available.
     if ($aclPlugin = $this->server->getPlugin('acl')) {
         $aclPlugin->checkPrivileges($uri, '{DAV:}read');
     }
     $this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
     $this->server->httpResponse->sendStatus(200);
     $nodes = $this->server->getPropertiesForPath($uri, array('{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'), 1);
     $this->server->httpResponse->sendBody($this->generateICS($nodes));
     // Returning false to break the event chain
     return false;
 }
示例#2
0
 function testInit()
 {
     $fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree(new Sabre_DAV_SimpleDirectory('bla')));
     $plugin = new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(), 'realm');
     $this->assertTrue($plugin instanceof Sabre_DAV_Auth_Plugin);
     $fakeServer->addPlugin($plugin);
     $this->assertEquals($plugin, $fakeServer->getPlugin('auth'));
 }
示例#3
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;
     }
     $userName = $authPlugin->getCurrentUser();
     if (!$userName) {
         return null;
     }
     return $this->defaultUsernamePath . '/' . $userName;
 }
示例#4
0
 function getServer()
 {
     $tree = array(new Sabre_DAVACL_MockPropertyNode('node1', array('{http://sabredav.org/ns}simple' => 'foo', '{http://sabredav.org/ns}href' => new Sabre_DAV_Property_Href('node2'), '{DAV:}displayname' => 'Node 1')), new Sabre_DAVACL_MockPropertyNode('node2', array('{http://sabredav.org/ns}simple' => 'simple', '{http://sabredav.org/ns}hreflist' => new Sabre_DAV_Property_HrefList(array('node1', 'node3')), '{DAV:}displayname' => 'Node 2')), new Sabre_DAVACL_MockPropertyNode('node3', array('{http://sabredav.org/ns}simple' => 'simple', '{DAV:}displayname' => 'Node 3')));
     $fakeServer = new Sabre_DAV_Server($tree);
     $fakeServer->debugExceptions = true;
     $fakeServer->httpResponse = new Sabre_HTTP_ResponseMock();
     $plugin = new Sabre_DAVACL_Plugin();
     $plugin->allowAccessToNodesWithoutACL = true;
     $this->assertTrue($plugin instanceof Sabre_DAVACL_Plugin);
     $fakeServer->addPlugin($plugin);
     $this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
     return $fakeServer;
 }
 function getServer()
 {
     $backend = new Sabre_DAV_Auth_MockBackend();
     $dir = new Sabre_DAV_SimpleDirectory('root');
     $principals = new Sabre_DAV_Auth_PrincipalCollection($backend);
     $dir->addChild($principals);
     $fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree($dir));
     $fakeServer->httpResponse = new Sabre_HTTP_ResponseMock();
     $plugin = new Sabre_DAV_Auth_Plugin($backend, 'realm');
     $this->assertTrue($plugin instanceof Sabre_DAV_Auth_Plugin);
     $fakeServer->addPlugin($plugin);
     $this->assertEquals($plugin, $fakeServer->getPlugin('Sabre_DAV_Auth_Plugin'));
     return $fakeServer;
 }
示例#6
0
 /**
  * This method is responsible for parsing the request and generating the
  * response for the CALDAV:free-busy-query REPORT.
  *
  * @param DOMNode $dom
  * @return void
  */
 protected function freeBusyQueryReport(DOMNode $dom)
 {
     $start = null;
     $end = null;
     foreach ($dom->firstChild->childNodes as $childNode) {
         $clark = Sabre_DAV_XMLUtil::toClarkNotation($childNode);
         if ($clark == '{' . self::NS_CALDAV . '}time-range') {
             $start = $childNode->getAttribute('start');
             $end = $childNode->getAttribute('end');
             break;
         }
     }
     if ($start) {
         $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
     }
     if ($end) {
         $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
     }
     if (!$start && !$end) {
         throw new Sabre_DAV_Exception_BadRequest('The freebusy report must have a time-range filter');
     }
     $acl = $this->server->getPlugin('acl');
     if (!$acl) {
         throw new Sabre_DAV_Exception('The ACL plugin must be loaded for free-busy queries to work');
     }
     $uri = $this->server->getRequestUri();
     $acl->checkPrivileges($uri, '{' . self::NS_CALDAV . '}read-free-busy');
     $calendar = $this->server->tree->getNodeForPath($uri);
     if (!$calendar instanceof Sabre_CalDAV_ICalendar) {
         throw new Sabre_DAV_Exception_NotImplemented('The free-busy-query REPORT is only implemented on calendars');
     }
     $objects = array_map(function ($child) {
         $obj = $child->get();
         if (is_resource($obj)) {
             $obj = stream_get_contents($obj);
         }
         return $obj;
     }, $calendar->getChildren());
     $generator = new Sabre_VObject_FreeBusyGenerator();
     $generator->setObjects($objects);
     $generator->setTimeRange($start, $end);
     $result = $generator->getResult();
     $result = $result->serialize();
     $this->server->httpResponse->sendStatus(200);
     $this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
     $this->server->httpResponse->setHeader('Content-Length', strlen($result));
     $this->server->httpResponse->sendBody($result);
 }
 function getServer()
 {
     $backend = new Sabre_DAVACL_MockPrincipalBackend();
     $dir = new Sabre_DAV_SimpleDirectory('root');
     $principals = new Sabre_DAVACL_PrincipalCollection($backend);
     $dir->addChild($principals);
     $fakeServer = new Sabre_DAV_Server(new Sabre_DAV_ObjectTree($dir));
     $fakeServer->httpResponse = new Sabre_HTTP_ResponseMock();
     $fakeServer->debugExceptions = true;
     $plugin = new Sabre_DAVACL_MockPlugin($backend, 'realm');
     $plugin->allowAccessToNodesWithoutACL = true;
     $this->assertTrue($plugin instanceof Sabre_DAVACL_Plugin);
     $fakeServer->addPlugin($plugin);
     $this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
     return $fakeServer;
 }
示例#8
0
 /**
  * Returns free-busy information for a specific address. The returned
  * data is an array containing the following properties:
  *
  * calendar-data : A VFREEBUSY VObject
  * request-status : an iTip status code.
  * href: The principal's email address, as requested
  *
  * The following request status codes may be returned:
  *   * 2.0;description
  *   * 3.7;description
  *
  * @param string $email address
  * @param DateTime $start
  * @param DateTime $end
  * @param Sabre_VObject_Component $request
  * @return Sabre_VObject_Component
  */
 protected function getFreeBusyForEmail($email, DateTime $start, DateTime $end, VObject\Component $request)
 {
     $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
     $aclPlugin = $this->server->getPlugin('acl');
     if (substr($email, 0, 7) === 'mailto:') {
         $email = substr($email, 7);
     }
     $result = $aclPlugin->principalSearch(array('{http://sabredav.org/ns}email-address' => $email), array('{DAV:}principal-URL', $caldavNS . 'calendar-home-set', '{http://sabredav.org/ns}email-address'));
     if (!count($result)) {
         return array('request-status' => '3.7;Could not find principal', 'href' => 'mailto:' . $email);
     }
     if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) {
         return array('request-status' => '3.7;No calendar-home-set property found', 'href' => 'mailto:' . $email);
     }
     $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
     // Grabbing the calendar list
     $objects = array();
     foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) {
         if (!$node instanceof Sabre_CalDAV_ICalendar) {
             continue;
         }
         $aclPlugin->checkPrivileges($homeSet . $node->getName(), $caldavNS . 'read-free-busy');
         // Getting the list of object uris within the time-range
         $urls = $node->calendarQuery(array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'comp-filters' => array(), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => array('start' => $start, 'end' => $end))), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => null));
         $calObjects = array_map(function ($url) use($node) {
             $obj = $node->getChild($url)->get();
             return $obj;
         }, $urls);
         $objects = array_merge($objects, $calObjects);
     }
     $vcalendar = VObject\Component::create('VCALENDAR');
     $vcalendar->VERSION = '2.0';
     $vcalendar->METHOD = 'REPLY';
     $vcalendar->CALSCALE = 'GREGORIAN';
     $vcalendar->PRODID = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
     $generator = new VObject\FreeBusyGenerator();
     $generator->setObjects($objects);
     $generator->setTimeRange($start, $end);
     $generator->setBaseObject($vcalendar);
     $result = $generator->getResult();
     $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email;
     $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID;
     $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER;
     return array('calendar-data' => $result, 'request-status' => '2.0;Success', 'href' => 'mailto:' . $email);
 }
示例#9
0
 /**
  * Returns free-busy information for a specific address. The returned 
  * data is an array containing the following properties:
  *
  * calendar-data : A VFREEBUSY VObject
  * request-status : an iTip status code.
  * href: The principal's email address, as requested
  *
  * The following request status codes may be returned:
  *   * 2.0;description
  *   * 3.7;description
  *
  * @param string $email address
  * @param DateTime $start
  * @param DateTime $end
  * @param Sabre_VObject_Component $request 
  * @return Sabre_VObject_Component 
  */
 protected function getFreeBusyForEmail($email, DateTime $start, DateTime $end, Sabre_VObject_Component $request)
 {
     $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
     $aclPlugin = $this->server->getPlugin('acl');
     if (substr($email, 0, 7) === 'mailto:') {
         $email = substr($email, 7);
     }
     $result = $aclPlugin->principalSearch(array('{http://sabredav.org/ns}email-address' => $email), array('{DAV:}principal-URL', $caldavNS . 'calendar-home-set', '{http://sabredav.org/ns}email-address'));
     if (!count($result)) {
         return array('request-status' => '3.7;Could not find principal', 'href' => 'mailto:' . $email);
     }
     if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) {
         return array('request-status' => '3.7;No calendar-home-set property found', 'href' => 'mailto:' . $email);
     }
     $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
     $calendars = array();
     // Grabbing the calendar list
     $props = array('{DAV:}resourcetype');
     $objects = array();
     foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) {
         if (!$node instanceof Sabre_CalDAV_ICalendar) {
             continue;
         }
         $aclPlugin->checkPrivileges($homeSet . $node->getName(), $caldavNS . 'read-free-busy');
         $calObjects = array_map(function ($child) {
             $obj = $child->get();
             return $obj;
         }, $node->getChildren());
         $objects = array_merge($objects, $calObjects);
     }
     $vcalendar = new Sabre_VObject_Component('VCALENDAR');
     $vcalendar->VERSION = '2.0';
     $vcalendar->METHOD = 'REPLY';
     $vcalendar->CALSCALE = 'GREGORIAN';
     $vcalendar->PRODID = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
     $generator = new Sabre_VObject_FreeBusyGenerator();
     $generator->setObjects($objects);
     $generator->setTimeRange($start, $end);
     $generator->setBaseObject($vcalendar);
     $result = $generator->getResult();
     $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email;
     $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID;
     return array('calendar-data' => $result, 'request-status' => '2.0;Success', 'href' => 'mailto:' . $email);
 }
 function testACLIntegrationNotBlocked()
 {
     if (!SABRE_HASSQLITE) {
         $this->markTestSkipped('SQLite driver is not available');
     }
     $cbackend = Sabre_CalDAV_TestUtil::getBackend();
     $pbackend = new Sabre_DAVACL_MockPrincipalBackend();
     $props = array('uri' => 'UUID-123467', 'principaluri' => 'admin', 'id' => 1);
     $tree = array(new Sabre_CalDAV_Calendar($pbackend, $cbackend, $props), new Sabre_DAVACL_PrincipalCollection($pbackend));
     $p = new Sabre_CalDAV_ICSExportPlugin();
     $s = new Sabre_DAV_Server($tree);
     $s->addPlugin($p);
     $s->addPlugin(new Sabre_CalDAV_Plugin());
     $s->addPlugin(new Sabre_DAVACL_Plugin());
     $s->addPlugin(new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(), 'SabreDAV'));
     // Forcing login
     $s->getPlugin('acl')->adminPrincipals = array('principals/admin');
     $h = new Sabre_HTTP_Request(array('QUERY_STRING' => 'export', 'REQUEST_URI' => '/UUID-123467', 'REQUEST_METHOD' => 'GET'));
     $s->httpRequest = $h;
     $s->httpResponse = new Sabre_HTTP_ResponseMock();
     $s->exec();
     $this->assertEquals('HTTP/1.1 200 OK', $s->httpResponse->status, 'Invalid status received. Response body: ' . $s->httpResponse->body);
     $this->assertEquals(array('Content-Type' => 'text/calendar'), $s->httpResponse->headers);
     $obj = Sabre_VObject_Reader::read($s->httpResponse->body);
     $this->assertEquals(5, count($obj->children()));
     $this->assertEquals(1, count($obj->VERSION));
     $this->assertEquals(1, count($obj->CALSCALE));
     $this->assertEquals(1, count($obj->PRODID));
     $this->assertEquals(1, count($obj->VTIMEZONE));
     $this->assertEquals(1, count($obj->VEVENT));
 }
 /**
  * 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 (Sabre_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 = Sabre_DAV_XMLUtil::loadDOMDocument($requestBody);
     $documentType = Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild);
     switch ($documentType) {
         // Dealing with the 'share' document, which modified invitees on a
         // calendar.
         case '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}share':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof Sabre_CalDAV_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 '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}invite-reply':
             // This only works on the calendar-home-root node.
             if (!$node instanceof Sabre_CalDAV_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 Sabre_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 '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}publish-calendar':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof Sabre_CalDAV_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 '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}unpublish-calendar':
             // We can only deal with IShareableCalendar objects
             if (!$node instanceof Sabre_CalDAV_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;
     }
 }
/**
 * @param Sabre_DAV_Server $server
 * @param Sabre_CalDAV_Calendar $calendar
 * @param string $calendarobject_uri
 * @param string $with_privilege
 * @return null|Sabre\VObject\Component\VCalendar
 */
function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
{
    $obj = $calendar->getChild($calendarobject_uri);
    if ($with_privilege == "") {
        $with_privilege = DAV_ACL_READ;
    }
    $a = get_app();
    $uri = "/calendars/" . strtolower($a->user["nickname"]) . "/" . $calendar->getName() . "/" . $calendarobject_uri;
    /** @var Sabre_DAVACL_Plugin $aclplugin  */
    $aclplugin = $server->getPlugin("acl");
    if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) {
        return null;
    }
    $data = $obj->get();
    $vObject = Sabre\VObject\Reader::read($data);
    return $vObject;
}