<?php

/**
 * Handle the FREE-BUSY-QUERY variant of REPORT
 */
include_once "freebusy-functions.php";
$fbq_content = $xmltree->GetContent('urn:ietf:params:xml:ns:caldav:free-busy-query');
$fbq_start = $fbq_content[0]->GetAttribute('start');
$fbq_end = $fbq_content[0]->GetAttribute('end');
if (!(isset($fbq_start) || isset($fbq_end))) {
    $request->DoResponse(400, 'All valid freebusy requests MUST contain a time-range filter');
}
$range_start = new RepeatRuleDateTime($fbq_start);
$range_end = new RepeatRuleDateTime($fbq_end);
/** We use the same code for the REPORT, the POST and the freebusy GET... */
$freebusy = get_freebusy('^' . $request->path . $request->DepthRegexTail(), $range_start, $range_end);
$result = new iCalComponent();
$result->VCalendar();
$result->AddComponent($freebusy);
$request->DoResponse(200, $result->Render(), 'text/calendar');
// Won't return from that
示例#2
0
function ischedule_freebusy_request($ic, $attendees, $attendees_fail)
{
    global $c, $session, $request;
    $reply = new XMLDocument(array("urn:ietf:params:xml:ns:ischedule" => "I"));
    $icalAttendees = $ic->GetAttendees();
    $responses = array();
    $ical = $ic->GetComponents('VFREEBUSY');
    $ical = $ical[0];
    $fbq_start = $ical->GetPValue('DTSTART');
    $fbq_end = $ical->GetPValue('DTEND');
    if (!(isset($fbq_start) || isset($fbq_end))) {
        $request->DoResponse(400, 'All valid freebusy requests MUST contain a DTSTART and a DTEND');
    }
    $range_start = new RepeatRuleDateTime($fbq_start);
    $range_end = new RepeatRuleDateTime($fbq_end);
    foreach ($attendees as $k => $attendee) {
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:ischedule');
        $fb = get_freebusy('^' . $attendee->dav_name, $range_start, $range_end);
        $fb->AddProperty('UID', $ical->GetPValue('UID'));
        $fb->SetProperties($ical->GetProperties('ORGANIZER'), 'ORGANIZER');
        foreach ($ical->GetProperties('ATTENDEE') as $at) {
            if ($at->Value() == 'mailto:' . $attendee->email) {
                $fb->AddProperty($at);
            }
        }
        $vcal = new vCalendar(array('METHOD' => 'REPLY'));
        $vcal->AddComponent($fb);
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:ischedule');
        $response->NewElement("recipient", 'mailto:' . $attendee->email, false, 'urn:ietf:params:xml:ns:ischedule');
        $response->NewElement("request-status", "2.0;Success", false, 'urn:ietf:params:xml:ns:ischedule');
        $response->NewElement("calendar-data", $vcal->Render(), false, 'urn:ietf:params:xml:ns:ischedule');
        $responses[] = $response;
    }
    foreach ($attendees_fail as $k => $attendee) {
        $XMLresponse = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:ischedule');
        $XMLresponse->NewElement("recipient", $reply->href('mailto:' . $attendee));
        $XMLresponse->NewElement("request-status", '5.3;cannot schedule this user, unknown or access denied');
        $responses[] = $XMLresponse;
    }
    $response = $reply->NewXMLElement("schedule-response", $responses, $reply->GetXmlNsArray(), 'urn:ietf:params:xml:ns:ischedule');
    $request->XMLResponse(200, $response);
}
示例#3
0
function handle_freebusy_request($ic)
{
    global $c, $session, $request, $ical;
    $request->NeedPrivilege('CALDAV:schedule-send-freebusy');
    $reply = new XMLDocument(array("DAV:" => "", "urn:ietf:params:xml:ns:caldav" => "C"));
    $responses = array();
    $fbq_start = $ic->GetPValue('DTSTART');
    $fbq_end = $ic->GetPValue('DTEND');
    if (!(isset($fbq_start) || isset($fbq_end))) {
        $request->DoResponse(400, 'All valid freebusy requests MUST contain a DTSTART and a DTEND');
    }
    $range_start = new RepeatRuleDateTime($fbq_start);
    $range_end = new RepeatRuleDateTime($fbq_end);
    $attendees = $ic->GetProperties('ATTENDEE');
    if (preg_match('# iCal/\\d#', $_SERVER['HTTP_USER_AGENT'])) {
        dbg_error_log("POST", "Non-compliant iCal request.  Using X-WR-ATTENDEE property");
        $wr_attendees = $ic->GetProperties('X-WR-ATTENDEE');
        foreach ($wr_attendees as $k => $v) {
            $attendees[] = $v;
        }
    }
    dbg_error_log("POST", "Responding with free/busy for %d attendees", count($attendees));
    foreach ($attendees as $k => $attendee) {
        $attendee_email = preg_replace('/^mailto:/', '', $attendee->Value());
        dbg_error_log("POST", "Calculating free/busy for %s", $attendee_email);
        /** @todo Refactor this so we only do one query here and loop through the results */
        $params = array(':session_principal' => $session->principal_id, ':scan_depth' => $c->permission_scan_depth, ':email' => $attendee_email);
        $qry = new AwlQuery('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE lower(usr.email) = lower(:email)', $params);
        if (!$qry->Exec('POST', __LINE__, __FILE__)) {
            $request->DoResponse(501, 'Database error');
        }
        if ($qry->rows() > 1) {
            // Unlikely, but if we get more than one result we'll do an exact match instead.
            if (!$qry->QDo('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE usr.email = :email', $params)) {
                $request->DoResponse(501, 'Database error');
            }
            if ($qry->rows() == 0) {
                /** Sigh... Go back to the original case-insensitive match */
                $qry->QDo('SELECT pprivs(:session_principal::int8,principal_id,:scan_depth::int) AS p, username FROM usr JOIN principal USING(user_no) WHERE lower(usr.email) = lower(:email)', $params);
            }
        }
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:caldav');
        $reply->CalDAVElement($response, "recipient", $reply->href($attendee->Value()));
        if ($qry->rows() == 0) {
            $remote = new iSchedule();
            $answer = $remote->sendRequest($attendee->Value(), 'VFREEBUSY/REQUEST', $ical->Render());
            if ($answer === false) {
                $reply->CalDAVElement($response, "request-status", "3.7;Invalid Calendar User");
                $reply->CalDAVElement($response, "calendar-data");
                $responses[] = $response;
                continue;
            }
            foreach ($answer as $a) {
                if ($a === false) {
                    $reply->CalDAVElement($response, "request-status", "3.7;Invalid Calendar User");
                    $reply->CalDAVElement($response, "calendar-data");
                } elseif (substr($a, 0, 1) >= 1) {
                    $reply->CalDAVElement($response, "request-status", $a);
                    $reply->CalDAVElement($response, "calendar-data");
                } else {
                    $reply->CalDAVElement($response, "request-status", "2.0;Success");
                    $reply->CalDAVElement($response, "calendar-data", $a);
                }
                $responses[] = $response;
            }
            continue;
        }
        if (!($attendee_usr = $qry->Fetch())) {
            $request->DoResponse(501, 'Database error');
        }
        if ((privilege_to_bits('schedule-query-freebusy') & bindec($attendee_usr->p)) == 0) {
            $reply->CalDAVElement($response, "request-status", "3.8;No authority");
            $reply->CalDAVElement($response, "calendar-data");
            $responses[] = $response;
            continue;
        }
        $attendee_path_match = '^/' . $attendee_usr->username . '/';
        $fb = get_freebusy($attendee_path_match, $range_start, $range_end, bindec($attendee_usr->p));
        $fb->AddProperty('UID', $ic->GetPValue('UID'));
        $fb->SetProperties($ic->GetProperties('ORGANIZER'), 'ORGANIZER');
        $fb->AddProperty($attendee);
        $vcal = new vCalendar(array('METHOD' => 'REPLY'));
        $vcal->AddComponent($fb);
        $response = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:caldav');
        $reply->CalDAVElement($response, "recipient", $reply->href($attendee->Value()));
        $reply->CalDAVElement($response, "request-status", "2.0;Success");
        // Cargo-cult setting
        $reply->CalDAVElement($response, "calendar-data", $vcal->Render());
        $responses[] = $response;
    }
    $response = $reply->NewXMLElement("schedule-response", $responses, $reply->GetXmlNsArray(), 'urn:ietf:params:xml:ns:caldav');
    $request->XMLResponse(200, $response);
}
示例#4
0
if (preg_match('{^/(\\S+@[a-z0-9][a-z0-9-]*[.][a-z0-9.-]+)/?$}i', $request->path, $matches)) {
    $principal = new Principal('email', $matches[1]);
    $path_match = '^' . $principal->dav_name();
}
if (isset($fb_format) && $fb_format != 'text/calendar') {
    $request->DoResponse(406, translate('This server only supports the text/calendar format for freebusy URLs'));
}
if (!$request->HavePrivilegeTo('read-free-busy')) {
    $request->DoResponse(404);
}
require_once "freebusy-functions.php";
switch ($_SERVER['REQUEST_METHOD']) {
    case 'GET':
        $range_start = new RepeatRuleDateTime($fb_start);
        if (!isset($fb_end)) {
            $range_end = clone $range_start;
            $range_end->modify($fb_period);
        } else {
            $range_end = new RepeatRuleDateTime($fb_end);
        }
        $freebusy = get_freebusy($path_match, $range_start, $range_end);
        $result = new vCalendar();
        $result->AddComponent($freebusy);
        $request->DoResponse(200, $result->Render(), 'text/calendar');
        break;
    default:
        dbg_error_log("freebusy", "Unhandled request method >>%s<<", $_SERVER['REQUEST_METHOD']);
        dbg_log_array("freebusy", 'HEADERS', $raw_headers);
        dbg_log_array("freebusy", '_SERVER', $_SERVER, true);
        @dbg_error_log("freebusy", "RAW: %s", str_replace("\n", "", str_replace("\r", "", $request->raw_post)));
}