function __construct($user_no = null) { if (empty($user_no)) { $this->user_no = -1; $this->principal_id = -1; $this->logged_in = false; return; } $this->user_no = $user_no; $principal = new Principal('user_no', $user_no); // Assign each field in the selected record to the object foreach ($principal as $k => $v) { $this->{$k} = $v; } $this->username = $principal->username(); $this->principal_id = $principal->principal_id(); $this->email = $principal->email(); $this->dav_name = $principal->dav_name(); $this->principal = $principal; $this->logged_in = true; }
/** * The constructor, which just calls the actual type configured */ function PublicSession() { global $c; $principal = new Principal('username', 'unauthenticated'); // Assign each field in the selected record to the object foreach ($principal as $k => $v) { $this->{$k} = $v; } $this->username = $principal->username(); $this->user_no = $principal->user_no(); $this->principal_id = $principal->principal_id(); $this->email = $principal->email(); $this->dav_name = $principal->dav_name(); $this->principal = $principal; if (function_exists("awl_set_locale") && isset($this->locale) && $this->locale != "") { awl_set_locale($this->locale); } $this->groups = isset($c->public_groups) ? $c->public_groups : array(); $this->roles = array('Public' => true); $this->logged_in = false; }
/** * Create/Update the scheduling requests for this resource. This includes updating * the scheduled user's default calendar. * @param vComponent $resource The VEVENT/VTODO/... resource we are scheduling * @param boolean $create true if the scheduling requests are being created. * @return true If there was any scheduling action */ function do_scheduling_requests(vCalendar $resource, $create, $old_data = null, $remoteAttendee = false) { global $request, $c; if (!isset($request) || isset($c->enable_auto_schedule) && !$c->enable_auto_schedule) { return false; } if (!is_object($resource)) { trace_bug('do_scheduling_requests called with non-object parameter (%s)', gettype($resource)); return false; } $organizer = $resource->GetOrganizer(); if ($organizer === false || empty($organizer)) { dbg_error_log('PUT', 'Event has no organizer - no scheduling required.'); return false; } $organizer_email = preg_replace('/^mailto:/i', '', $organizer->Value()); if ($request->principal->email() != $organizer_email) { return do_scheduling_reply($resource, $organizer); } $schedule_request = clone $resource; $schedule_request->AddProperty('METHOD', 'REQUEST'); $old_attendees = array(); if (!empty($old_data)) { $old_resource = new vCalendar($old_data); $old_attendees = $old_resource->GetAttendees(); } $attendees = $resource->GetAttendees(); if (count($attendees) == 0 && count($old_attendees) == 0) { dbg_error_log('PUT', 'Event has no attendees - no scheduling required.', count($attendees)); return false; } $removed_attendees = array(); foreach ($old_attendees as $attendee) { $email = preg_replace('/^mailto:/i', '', $attendee->Value()); if ($email == $request->principal->email()) { continue; } $removed_attendees[$email] = $attendee; } $uids = $resource->GetPropertiesByPath('/VCALENDAR/*/UID'); if (count($uids) == 0) { dbg_error_log('PUT', 'No UID in VCALENDAR - giving up on REPLY.'); return false; } $uid = $uids[0]->Value(); dbg_error_log('PUT', 'Writing scheduling resources for %d attendees', count($attendees)); $scheduling_actions = false; foreach ($attendees as $attendee) { $email = preg_replace('/^mailto:/i', '', $attendee->Value()); if ($email == $request->principal->email()) { dbg_error_log("PUT", "not delivering to owner '%s'", $request->principal->email()); continue; } if ($create) { $attendee_is_new = true; } else { $attendee_is_new = !isset($removed_attendees[$email]); if (!$attendee_is_new) { unset($removed_attendees[$email]); } } $agent = $attendee->GetParameterValue('SCHEDULE-AGENT'); if ($agent && $agent != 'SERVER') { dbg_error_log("PUT", "not delivering to %s, schedule agent set to value other than server", $email); continue; } $schedule_target = new Principal('email', $email); $response = '3.7'; // Attendee was not found on server. dbg_error_log('PUT', 'Handling scheduling resources for %s on %s which is %s', $email, $create ? 'create' : 'update', $attendee_is_new ? 'new' : 'an update'); if ($schedule_target->Exists()) { // Instead of always writing to schedule-default-calendar, we first try to // find a calendar with an existing instance of the event. $sql = 'SELECT caldav_data.dav_name, caldav_data.caldav_data, caldav_data.collection_id FROM caldav_data JOIN calendar_item USING(dav_id) '; $sql .= 'WHERE caldav_data.collection_id IN (SELECT collection_id FROM collection WHERE is_calendar AND user_no =?) '; $sql .= 'AND uid=? LIMIT 1'; $qry = new AwlQuery($sql, $schedule_target->user_no(), $uid); if (!$qry->Exec('PUT', __LINE__, __FILE__) || $qry->rows() < 1) { dbg_error_log('PUT', "Could not find event in attendee's calendars"); $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar'))); } else { $row = $qry->Fetch(); $r = new DAVResource($row); $attendee_calendar = new WritableCollection(array('path' => $r->parent_path())); if ($attendee_calendar->IsCalendar()) { dbg_error_log('XXX', "found the event in attendee's calendar %s", $attendee_calendar->dav_name()); } else { dbg_error_log('XXX', 'could not find the event in any calendar, using schedule-default-calendar'); $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar'))); } } if (!$attendee_calendar->Exists()) { dbg_error_log('ERROR', 'Default calendar at "%s" does not exist for user "%s"', $attendee_calendar->dav_name(), $schedule_target->username()); $response = '5.2'; // No scheduling support for user } else { $attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox'))); if (!$attendee_inbox->HavePrivilegeTo('schedule-deliver-invite')) { $response = '3.8'; // No authority to deliver invitations to user. } else { if ($attendee_inbox->WriteCalendarMember($schedule_request, $attendee_is_new) !== false) { $response = '1.2'; // Scheduling invitation delivered successfully if ($attendee_calendar->WriteCalendarMember($resource, $attendee_is_new) === false) { dbg_error_log('ERROR', 'Could not write %s calendar member to %s', $attendee_is_new ? 'new' : 'updated', $attendee_calendar->dav_name(), $attendee_calendar->dav_name(), $schedule_target->username()); trace_bug('Failed to write scheduling resource.'); } } } } } else { if ($remoteAttendee) { $attendee->is_remote = true; $remote = new iSchedule(); $answer = $remote->sendRequest($email, 'VEVENT/REQUEST', $schedule_request->Render()); } else { $remote = new iSchedule(); $answer = $remote->sendRequest($email, 'VEVENT/REQUEST', $schedule_request->Render()); if ($answer === false) { $response = "3.7;Invalid Calendar User"; } else { foreach ($answer as $a) { if ($a === false) { $response = "3.7;Invalid Calendar User"; } elseif (substr($a, 0, 1) >= 1) { $response = $a; } else { $response = "2.0;Success"; } } } } } dbg_error_log('PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $response); $attendee->SetParameterValue('SCHEDULE-STATUS', $response); $scheduling_actions = true; } if (!$create) { foreach ($removed_attendees as $attendee) { $schedule_target = new Principal('email', $email); if ($schedule_target->Exists()) { $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar'))); } } } return $scheduling_actions; }
/** * Synchronise a cached user with one from LDAP * @param object $principal A Principal object to be updated (or created) */ function sync_user_from_LDAP(Principal &$principal, $mapping, $ldap_values) { global $c; dbg_error_log("LDAP", "Going to sync the user from LDAP"); $fields_to_set = array(); $updateable_fields = Principal::updateableFields(); foreach ($updateable_fields as $field) { if (isset($mapping[$field])) { $tab_part_fields = explode(',', $mapping[$field]); foreach ($tab_part_fields as $part_field) { if (isset($ldap_values[$part_field])) { if (isset($fields_to_set[$field])) { $fields_to_set[$field] .= ' ' . $ldap_values[$part_field]; } else { $fields_to_set[$field] = $ldap_values[$part_field]; } } } dbg_error_log("LDAP", "Setting usr->%s to %s from LDAP field %s", $field, $fields_to_set[$field], $mapping[$field]); } else { if (isset($c->authenticate_hook['config']['default_value']) && is_array($c->authenticate_hook['config']['default_value']) && isset($c->authenticate_hook['config']['default_value'][$field])) { $fields_to_set[$field] = $c->authenticate_hook['config']['default_value'][$field]; dbg_error_log("LDAP", "Setting usr->%s to %s from configured defaults", $field, $c->authenticate_hook['config']['default_value'][$field]); } } } if ($principal->Exists()) { $principal->Update($fields_to_set); } else { $principal->Create($fields_to_set); CreateHomeCollections($principal->username()); CreateDefaultRelationships($principal->username()); } }
<Error Time="{$error_time}" Id="{$error_time_id}"> <ErrorCode>{$code}</ErrorCode> <Message>{$message}</Message> <DebugData>{$debugdata}</DebugData> </Error> </Response> </Autodiscover> ERROR; $request->DoResponse($code, $response, 'text/xml; charset="utf-8"'); exit(0); // unneccessary } if (!isset($request->xml_tags)) { errorResponse(406, translate("Body contains no XML data!")); } $position = 0; $xmltree = BuildXMLTree($request->xml_tags, $position); if (!is_object($xmltree)) { errorResponse(406, translate("REPORT body is not valid XML data!")); } $user_email = $xmltree->GetPath('/' . $ns_outlook_req_2006 . ':Autodiscover' . '/' . $ns_outlook_req_2006 . ':Request' . '/' . $ns_outlook_req_2006 . ':EMailAddress'); if (count($user_email) < 1) { errorResponse(500, "User not found."); } $user_email = $user_email[0]->GetContent(); $principal = new Principal(); $reply = new XMLDocument(array($ns_outlook_resp_2006a => "")); $response = array(new XMLElement('User', array(new XMLElement('DisplayName', $principal->{$fullname}), new XMLElement('AutoDiscoverSMTPAddress', $user_email)))); $response[] = new XMLElement('Account', array(new XMLElement('AccountType', 'email'), new XMLElement('Action', 'settings'), new XMLElement('Protocol', array(new XMLElement('Type', 'DAV'), new XMLElement('Server', $c->domain_name), new XMLElement('LoginName', $principal->username()))))); $autodiscover = new XMLElement("Autodiscover", $responses, $reply->GetXmlNsArray(), $ns_exchange_resp_2006); $request->XMLResponse(207, $autodiscover);
function ischedule_cancel($ic, $attendees, $attendees_fail) { global $c, $session, $request; $reply = new XMLDocument(array("DAV:" => "", "urn:ietf:params:xml:ns:caldav" => "C", "urn:ietf:params:xml:ns:ischedule" => "I")); $responses = array(); $ical = $ic->GetComponents('VEVENT'); $ical = $ical[0]; foreach ($attendees as $k => $attendee) { $XMLresponse = $reply->NewXMLElement("response", false, false, 'urn:ietf:params:xml:ns:ischedule'); dbg_error_log('ischedule', 'scheduling event for ' . $attendee->email); $schedule_target = new Principal('email', $attendee->email); $response = '3.7'; // Attendee was not found on server. if ($schedule_target->Exists()) { $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar'))); if (!$attendee_calendar->Exists()) { dbg_error_log('ERROR', 'Default calendar at "%s" does not exist for user "%s"', $attendee_calendar->dav_name(), $schedule_target->username()); $response = '5.3;cannot schedule this user, unknown or access denied'; // No scheduling support for user } else { $attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox'))); if (!$attendee_inbox->HavePrivilegeTo('schedule-deliver-invite')) { $response = '3.8;denied'; // No authority to deliver invitations to user. } else { if ($attendee_inbox->WriteCalendarMember($ic, false) !== false) { $response = '2.0;delivered'; // Scheduling invitation delivered successfully } } } } dbg_error_log('PUT', 'Status for attendee <%s> set to "%s"', $attendee->email, $response); $XMLresponse->NewElement("recipient", $reply->href('mailto:' . $attendee->email), false, 'urn:ietf:params:xml:ns:ischedule'); $XMLresponse->NewElement("request-status", $response, false, 'urn:ietf:params:xml:ns:ischedule'); $responses[] = $XMLresponse; } 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->email), false, 'urn:ietf:params:xml:ns:ischedule'); $XMLresponse->NewElement("request-status", '5.3;cannot schedule this user, unknown or access denied', false, 'urn:ietf:params:xml:ns:ischedule'); $responses[] = $XMLresponse; } $response = $reply->NewXMLElement("schedule-response", $responses, $reply->GetXmlNsArray(), 'urn:ietf:params:xml:ns:ischedule'); $request->XMLResponse(200, $response); }
function doItipAttendeeReply(vCalendar $resource, $partstat) { global $request; $organizer = $resource->GetOrganizer(); $organizer_email = preg_replace('/^mailto:/i', '', $organizer->Value()); $organizer_principal = new Principal('email', $organizer_email); if (!$organizer_principal->Exists()) { dbg_error_log('schedule', 'Unknown ORGANIZER "%s" - unable to notify.', $organizer->Value()); header("Debug: Could maybe do the iMIP message dance for organizer " . $organizer->Value()); return true; } $sql = 'SELECT caldav_data.dav_name, caldav_data.caldav_data FROM caldav_data JOIN calendar_item USING(dav_id) '; $sql .= 'WHERE caldav_data.collection_id IN (SELECT collection_id FROM collection WHERE is_calendar AND user_no =?) '; $sql .= 'AND uid=? LIMIT 1'; $uids = $resource->GetPropertiesByPath('/VCALENDAR/*/UID'); if (count($uids) == 0) { dbg_error_log('schedule', 'No UID in VCALENDAR - giving up on REPLY.'); return true; } $uid = $uids[0]->Value(); $qry = new AwlQuery($sql, $organizer_principal->user_no(), $uid); if (!$qry->Exec('schedule', __LINE__, __FILE__) || $qry->rows() < 1) { dbg_error_log('schedule', 'Could not find original event from organizer - giving up on REPLY.'); return true; } $row = $qry->Fetch(); $collection_path = preg_replace('{/[^/]+$}', '/', $row->dav_name); $segment_name = str_replace($collection_path, '', $row->dav_name); $vcal = new vCalendar($row->caldav_data); $attendees = $vcal->GetAttendees(); foreach ($attendees as $v) { $email = preg_replace('/^mailto:/i', '', $v->Value()); if ($email == $request->principal->email()) { $attendee = $v; break; } } if (empty($attendee)) { dbg_error_log('schedule', 'Could not find ATTENDEE in VEVENT - giving up on REPLY.'); return true; } $attendee->SetParameterValue('PARTSTAT', $partstat); $attendee->SetParameterValue('SCHEDULE-STATUS', '2.0'); $vcal->UpdateAttendeeStatus($request->principal->email(), clone $attendee); $organizer_calendar = new WritableCollection(array('path' => $collection_path)); $organizer_inbox = new WritableCollection(array('path' => $organizer_principal->internal_url('schedule-inbox'))); $schedule_reply = GetItip(new vCalendar($row->caldav_data), 'REPLY', $attendee->Value()); $schedule_request = GetItip(new vCalendar($row->caldav_data), 'REQUEST', null); dbg_error_log('schedule', 'Writing ATTENDEE scheduling REPLY from %s to %s', $request->principal->email(), $organizer_principal->email()); $response = '3.7'; // Organizer was not found on server. if (!$organizer_calendar->Exists()) { if (doImipMessage('REPLY', $organizer_principal->email(), $vcal)) { $response = '1.1'; // Scheduling whoosit 'Sent' } else { dbg_error_log('ERROR', 'Default calendar at "%s" does not exist for user "%s"', $organizer_calendar->dav_name(), $schedule_target->username()); $response = '5.2'; // No scheduling support for user } } else { if (!$organizer_inbox->HavePrivilegeTo('schedule-deliver-reply')) { $response = '3.8'; // No authority to deliver replies to organizer. } $response = '1.2'; // Scheduling reply delivered successfully if ($organizer_calendar->WriteCalendarMember($vcal, false, false, $segment_name) === false) { dbg_error_log('ERROR', 'Could not write updated calendar member to %s', $attendee_calendar->dav_name()); trace_bug('Failed to write scheduling resource.'); } $organizer_inbox->WriteCalendarMember($schedule_reply, false, false, $request->principal->username() . $segment_name); } dbg_error_log('schedule', 'Status for organizer <%s> set to "%s"', $organizer->Value(), $response); $organizer->SetParameterValue('SCHEDULE-STATUS', $response); $resource->UpdateOrganizerStatus($organizer); // Which was passed in by reference, and we're updating it here. // Now we loop through the *other* ATTENDEEs, updating them on the status of the ATTENDEE DECLINE/ACCEPT foreach ($attendees as $attendee) { $email = preg_replace('/^mailto:/i', '', $attendee->Value()); if ($email == $request->principal->email() || $email == $organizer_principal->email()) { continue; } $agent = $attendee->GetParameterValue('SCHEDULE-AGENT'); if (!empty($agent) && $agent != 'SERVER') { continue; } $schedule_target = new Principal('email', $email); if ($schedule_target->Exists()) { $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar'))); if (!$attendee_calendar->Exists()) { dbg_error_log('ERROR', 'Default calendar at "%s" does not exist for user "%s"', $attendee_calendar->dav_name(), $schedule_target->username()); continue; } else { $attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox'))); if (!$attendee_inbox->HavePrivilegeTo('schedule-deliver-invite')) { continue; } if ($attendee_calendar->WriteCalendarMember($vcal, false) === false) { dbg_error_log('ERROR', 'Could not write updated calendar member to %s', $attendee_calendar->dav_name()); trace_bug('Failed to write scheduling resource.'); } $attendee_inbox->WriteCalendarMember($schedule_request, false); } } else { header("Debug: Could maybe do the iMIP message dance for attendee " . $email); } } return true; }