예제 #1
0
 /**
  * This method is responsible for parsing a free-busy query request and
  * returning it's result.
  *
  * @param Sabre_CalDAV_Schedule_IOutbox $outbox
  * @param string $request
  * @return string
  */
 protected function handleFreeBusyRequest(Sabre_CalDAV_Schedule_IOutbox $outbox, VObject\Component $vObject)
 {
     $vFreeBusy = $vObject->VFREEBUSY;
     $organizer = $vFreeBusy->organizer;
     $organizer = (string) $organizer;
     // Validating if the organizer matches the owner of the inbox.
     $owner = $outbox->getOwner();
     $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
     $uas = $caldavNS . 'calendar-user-address-set';
     $props = $this->server->getProperties($owner, array($uas));
     if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) {
         throw new Sabre_DAV_Exception_Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox');
     }
     if (!isset($vFreeBusy->ATTENDEE)) {
         throw new Sabre_DAV_Exception_BadRequest('You must at least specify 1 attendee');
     }
     $attendees = array();
     foreach ($vFreeBusy->ATTENDEE as $attendee) {
         $attendees[] = (string) $attendee;
     }
     if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) {
         throw new Sabre_DAV_Exception_BadRequest('DTSTART and DTEND must both be specified');
     }
     $startRange = $vFreeBusy->DTSTART->getDateTime();
     $endRange = $vFreeBusy->DTEND->getDateTime();
     $results = array();
     foreach ($attendees as $attendee) {
         $results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject);
     }
     $dom = new DOMDocument('1.0', 'utf-8');
     $dom->formatOutput = true;
     $scheduleResponse = $dom->createElement('cal:schedule-response');
     foreach ($this->server->xmlNamespaces as $namespace => $prefix) {
         $scheduleResponse->setAttribute('xmlns:' . $prefix, $namespace);
     }
     $dom->appendChild($scheduleResponse);
     foreach ($results as $result) {
         $response = $dom->createElement('cal:response');
         $recipient = $dom->createElement('cal:recipient');
         $recipientHref = $dom->createElement('d:href');
         $recipientHref->appendChild($dom->createTextNode($result['href']));
         $recipient->appendChild($recipientHref);
         $response->appendChild($recipient);
         $reqStatus = $dom->createElement('cal:request-status');
         $reqStatus->appendChild($dom->createTextNode($result['request-status']));
         $response->appendChild($reqStatus);
         if (isset($result['calendar-data'])) {
             $calendardata = $dom->createElement('cal:calendar-data');
             $calendardata->appendChild($dom->createTextNode(str_replace("\r\n", "\n", $result['calendar-data']->serialize())));
             $response->appendChild($calendardata);
         }
         $scheduleResponse->appendChild($response);
     }
     $this->server->httpResponse->sendStatus(200);
     $this->server->httpResponse->setHeader('Content-Type', 'application/xml');
     $this->server->httpResponse->sendBody($dom->saveXML());
 }
예제 #2
0
 /**
  * This method handles POST requests to the schedule-outbox
  *
  * @param Sabre_CalDAV_Schedule_IOutbox $outboxNode
  * @return void
  */
 public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode)
 {
     $originator = $this->server->httpRequest->getHeader('Originator');
     $recipients = $this->server->httpRequest->getHeader('Recipient');
     if (!$originator) {
         throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests');
     }
     if (!$recipients) {
         throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests');
     }
     if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) {
         throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address');
     }
     $originator = substr($originator, 7);
     $recipients = explode(',', $recipients);
     foreach ($recipients as $k => $recipient) {
         $recipient = trim($recipient);
         if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) {
             throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address');
         }
         $recipient = substr($recipient, 7);
         $recipients[$k] = $recipient;
     }
     // We need to make sure that 'originator' matches one of the email
     // addresses of the selected principal.
     $principal = $outboxNode->getOwner();
     $props = $this->server->getProperties($principal, array('{' . self::NS_CALDAV . '}calendar-user-address-set'));
     $addresses = array();
     if (isset($props['{' . self::NS_CALDAV . '}calendar-user-address-set'])) {
         $addresses = $props['{' . self::NS_CALDAV . '}calendar-user-address-set']->getHrefs();
     }
     if (!in_array('mailto:' . $originator, $addresses)) {
         throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header');
     }
     try {
         $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
     } catch (Sabre_VObject_ParseException $e) {
         throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
     }
     // Checking for the object type
     $componentType = null;
     foreach ($vObject->getComponents() as $component) {
         if ($component->name !== 'VTIMEZONE') {
             $componentType = $component->name;
             break;
         }
     }
     if (is_null($componentType)) {
         throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
     }
     // Validating the METHOD
     $method = strtoupper((string) $vObject->METHOD);
     if (!$method) {
         throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
     }
     if (in_array($method, array('REQUEST', 'REPLY', 'ADD', 'CANCEL')) && $componentType === 'VEVENT') {
         $this->iMIPMessage($originator, $recipients, $vObject, $principal);
         $this->server->httpResponse->sendStatus(200);
         $this->server->httpResponse->sendBody('Messages sent');
     } else {
         throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
     }
 }
예제 #3
0
 /**
  * This method is responsible for parsing a free-busy query request and
  * returning it's result.
  *
  * @param Sabre_DAV_INode $node
  * @param string $request
  * @return string
  */
 protected function handleFreeBusyRequest(Sabre_CalDAV_Schedule_IOutbox $outbox, $request)
 {
     $vObject = Sabre_VObject_Reader::read($request);
     $method = (string) $vObject->method;
     if ($method !== 'REQUEST') {
         throw new Sabre_DAV_Exception_BadRequest('The iTip object must have a METHOD:REQUEST property');
     }
     $vFreeBusy = $vObject->VFREEBUSY;
     if (!$vFreeBusy) {
         throw new Sabre_DAV_Exception_BadRequest('The iTip object must have a VFREEBUSY component');
     }
     $organizer = $vFreeBusy->organizer;
     $organizer = (string) $organizer;
     // Validating if the organizer matches the owner of the inbox.
     $owner = $outbox->getOwner();
     $caldavNS = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}';
     $uas = $caldavNS . 'calendar-user-address-set';
     $props = $this->server->getProperties($owner, array($uas));
     if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) {
         throw new Sabre_DAV_Exception_Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox');
     }
     if (!isset($vFreeBusy->ATTENDEE)) {
         throw new Sabre_DAV_Exception_BadRequest('You must at least specify 1 attendee');
     }
     $attendees = array();
     foreach ($vFreeBusy->ATTENDEE as $attendee) {
         $attendees[] = (string) $attendee;
     }
     if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) {
         throw new Sabre_DAV_Exception_BadRequest('DTSTART and DTEND must both be specified');
     }
     $startRange = $vFreeBusy->DTSTART->getDateTime();
     $endRange = $vFreeBusy->DTEND->getDateTime();
     $results = array();
     foreach ($attendees as $k => $attendee) {
         $results[] = $this->getFreeBusyForEmailTine20($attendee, $startRange, $endRange, $vObject);
     }
     $dom = new DOMDocument('1.0', 'utf-8');
     $dom->formatOutput = true;
     $scheduleResponse = $dom->createElementNS(Sabre_CalDAV_Plugin::NS_CALDAV, 'cal:schedule-response');
     $dom->appendChild($scheduleResponse);
     foreach ($results as $result) {
         $response = $dom->createElement('cal:response');
         $recipient = $dom->createElement('cal:recipient');
         $recipient->appendChild($dom->createTextNode($result['href']));
         $response->appendChild($recipient);
         $reqStatus = $dom->createElement('cal:request-status');
         $reqStatus->appendChild($dom->createTextNode($result['request-status']));
         $response->appendChild($reqStatus);
         if (isset($result['calendar-data'])) {
             $calendardata = $dom->createElement('cal:calendar-data');
             $calendardata->appendChild($dom->createTextNode(str_replace("\r\n", "\n", $result['calendar-data']->serialize())));
             $response->appendChild($calendardata);
         }
         $scheduleResponse->appendChild($response);
     }
     return $dom->saveXML();
 }