From 8ba55217dfa77308e274fd03d3a95808dddb43b7 Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Mon, 24 Oct 2011 18:38:48 +1300 Subject: [PATCH] More fixes to CalDAV Scheduling - Handle REPLY from ATTENDEE accepting/declining meeting. - Handle processing on ORGANIZER further changing meeting. --- inc/caldav-PUT-functions.php | 167 ++++++++++++++-- .../tests/binding/1029-PUT-subcalendar.result | 2 +- .../tests/binding/1029-PUT-subcalendar.test | 4 +- testing/tests/binding/1035-GET-mashup.result | 21 +- .../1036-REPORT-sync-initial-bound.result | 4 +- .../scheduling/3010-PUT-with-attendees.result | 12 +- .../3023-PUT-iCal-with-attendees.result | 5 +- .../3024-PUT-iCal-with-attendees.result | 5 +- .../scheduling/3025-DELETE-invite.result | 12 ++ .../tests/scheduling/3025-DELETE-invite.test | 18 ++ .../tests/scheduling/3026-PUT-Accept.result | 134 +++++++++++++ testing/tests/scheduling/3026-PUT-Accept.test | 66 ++++++ .../3027-PUT-iCal-with-attendees.result | 189 ++++++++++++++++++ .../3027-PUT-iCal-with-attendees.test | 63 ++++++ .../tests/timezone/Restore-Database.result | 2 +- 15 files changed, 661 insertions(+), 43 deletions(-) create mode 100644 testing/tests/scheduling/3025-DELETE-invite.result create mode 100644 testing/tests/scheduling/3025-DELETE-invite.test create mode 100644 testing/tests/scheduling/3026-PUT-Accept.result create mode 100644 testing/tests/scheduling/3026-PUT-Accept.test create mode 100644 testing/tests/scheduling/3027-PUT-iCal-with-attendees.result create mode 100644 testing/tests/scheduling/3027-PUT-iCal-with-attendees.test diff --git a/inc/caldav-PUT-functions.php b/inc/caldav-PUT-functions.php index ca2f3aa1..f1fb9374 100644 --- a/inc/caldav-PUT-functions.php +++ b/inc/caldav-PUT-functions.php @@ -311,6 +311,132 @@ function handle_schedule_reply ( vCalendar $ical ) { } +/** + * Do the scheduling adjustments for a REPLY when an ATTENDEE updates their status. + * @param vCalendar $resource The resource that the ATTENDEE is writing to their calendar + * @param string $organizer The property which is the event ORGANIZER. + */ +function do_scheduling_reply( vCalendar $resource, vProperty $organizer ) { + global $request; + $organizer_email = preg_replace( '/^mailto:/i', '', $organizer->Value() ); + $organizer_principal = new Principal('email',$organizer_email ); + if ( !$organizer_principal->Exists() ) { + dbg_error_log( 'PUT', 'Organizer "%s" not found - cannot perform scheduling reply.', $organizer ); + return false; + } + $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( 'PUT', 'No UID in VCALENDAR - giving up on REPLY.' ); + return false; + } + $uid = $uids[0]->Value(); + $qry = new AwlQuery($sql,$organizer_principal->user_no(), $uid); + if ( !$qry->Exec('PUT',__LINE__,__FILE__) || $qry->rows() < 1 ) { + dbg_error_log( 'PUT', 'Could not find original event from organizer - giving up on REPLY.' ); + return false; + } + $row = $qry->Fetch(); + $attendees = $resource->GetAttendees(); + foreach( $attendees AS $v ) { + $email = preg_replace( '/^mailto:/i', '', $v->Value() ); + if ( $email == $request->principal->email() ) { + $attendee = $v; + } + } + if ( empty($attendee) ) { + dbg_error_log( 'PUT', 'Could not find ATTENDEE in VEVENT - giving up on REPLY.' ); + return false; + } + $schedule_original = new vCalendar($row->caldav_data); + $schedule_original->UpdateAttendeeStatus($request->principal->email(), clone($attendee) ); + + $collection_path = preg_replace('{/[^/]+$}', '/', $row->dav_name ); + $segment_name = str_replace($collection_path, '', $row->dav_name ); + $organizer_calendar = new WritableCollection(array('path' => $collection_path)); + $organizer_inbox = new WritableCollection(array('path' => $organizer_principal->internal_url('schedule-inbox'))); + + $schedule_reply = clone($schedule_original); + $schedule_reply->AddProperty('METHOD', 'REPLY'); + + dbg_error_log( 'PUT', 'Writing 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() ) { + 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. + } + else if ( $organizer_inbox->WriteCalendarMember($schedule_reply, false, false, $request->principal->username().$segment_name) !== false ) { + $response = '1.2'; // Scheduling reply delivered successfully + if ( $organizer_calendar->WriteCalendarMember($schedule_original, false, false, $segment_name) === false ) { + dbg_error_log('ERROR','Could not write updated calendar member to %s', + $attendee_calendar->dav_name(), $attendee_calendar->dav_name(), $schedule_target->username()); + trace_bug('Failed to write scheduling resource.'); + } + } + } + + $schedule_request = clone($schedule_original); + $schedule_request->AddProperty('METHOD', 'REQUEST'); + + dbg_error_log( 'PUT', 'Status for organizer <%s> set to "%s"', $organizer->Value(), $response ); + $organizer->SetParameterValue( 'SCHEDULE-STATUS', $response ); + $resource->UpdateOrganizerStatus($organizer); + $scheduling_actions = true; + + $attendees = $schedule_original->GetAttendees(); + 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 ( $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. + 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.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, false) !== false ) { + $response = '1.2'; // Scheduling invitation delivered successfully + if ( $attendee_calendar->WriteCalendarMember($schedule_original, false) === false ) { + dbg_error_log('ERROR','Could not write updated calendar member to %s', + $attendee_calendar->dav_name(), $attendee_calendar->dav_name(), $schedule_target->username()); + trace_bug('Failed to write scheduling resource.'); + } + } + } + } + dbg_error_log( 'PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $response ); + $attendee->SetParameterValue( 'SCHEDULE-STATUS', $response ); + $scheduling_actions = true; + + $resource->UpdateAttendeeStatus($email, clone($attendee)); + + } + + return $scheduling_actions; +} + + /** * Create/Update the scheduling requests for this resource. This includes updating * the scheduled user's default calendar. @@ -327,6 +453,20 @@ function do_scheduling_requests( vCalendar $resource, $create, $old_data = null 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); @@ -344,14 +484,12 @@ function do_scheduling_requests( vCalendar $resource, $create, $old_data = null $removed_attendees[$email] = $attendee; } - dbg_error_log( 'PUT', 'Adding to scheduling inbox %d attendees', count($attendees) ); - $schedule_request = clone($resource); - $schedule_request->AddProperty('METHOD','REQUEST'); + 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" ); + dbg_error_log( "PUT", "not delivering to owner '%s'", $request->principal->email() ); continue; } @@ -369,30 +507,33 @@ function do_scheduling_requests( vCalendar $resource, $create, $old_data = null continue; } $schedule_target = new Principal('email',$email); - $response = '5.3;'.translate('No scheduling support for user'); + $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() ) { $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;'.translate('No authority to deliver invitations to user.'); + $response = '3.8'; // No authority to deliver invitations to user. } else if ( $attendee_inbox->WriteCalendarMember($schedule_request, $attendee_is_new) !== false ) { - $response = '2.0;'.translate('Scheduling invitation delivered successfully'); + $response = '1.2'; // Scheduling invitation delivered successfully if ( $attendee_calendar->WriteCalendarMember($resource, $attendee_is_new) === false ) { - dbg_error_log('ERROR','Could not write new calendar member to %s', $attendee_calendar->dav_name(), - $attendee_calendar->dav_name(), $schedule_target->username()); + 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.'); } } } } - $schedule_status = '"'.$response.'"'; - dbg_error_log( 'PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $schedule_status ); - $attendee->SetParameterValue( 'SCHEDULE-STATUS', $schedule_status ); + dbg_error_log( 'PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $response ); + $attendee->SetParameterValue( 'SCHEDULE-STATUS', $response ); $scheduling_actions = true; } @@ -946,7 +1087,7 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle $calitem_params[':status'] = $first->GetPValue('STATUS'); if ( !$collection->IsSchedulingCollection() ) { - if ( do_scheduling_requests($vcal, ($put_action_type == 'INSERT') ) ) { + if ( do_scheduling_requests($vcal, ($put_action_type == 'INSERT'), $old_dav_data ) ) { $dav_params[':dav_data'] = $vcal->Render(null, true); $etag = null; } diff --git a/testing/tests/binding/1029-PUT-subcalendar.result b/testing/tests/binding/1029-PUT-subcalendar.result index 73263ac3..ea6361aa 100644 --- a/testing/tests/binding/1029-PUT-subcalendar.result +++ b/testing/tests/binding/1029-PUT-subcalendar.result @@ -6,7 +6,7 @@ Content-Length: 0 Content-Type: text/plain; charset="utf-8" - dav_etag: >baad41c9f24bd1ecbdde6e58882df9b7< + dav_etag: >ea6b316ca24db20f5eb37d1abd60f8c1< dav_name: >/user4/base/calendar/anothergoodleopard.ics< dtstart: >2010-03-22 16:00:00+13< summary: >An invited event. Black tie with pink polka dots is essential. Do not bring a leopard. Any leopards which do attend will be forcibly chained to a nearby fence.< diff --git a/testing/tests/binding/1029-PUT-subcalendar.test b/testing/tests/binding/1029-PUT-subcalendar.test index 2ba8e9aa..88d7d94e 100644 --- a/testing/tests/binding/1029-PUT-subcalendar.test +++ b/testing/tests/binding/1029-PUT-subcalendar.test @@ -21,13 +21,13 @@ UID:70399cd7-50a4-4be4-a665-af593e19a7fd SUMMARY:An invited event. Black tie with pink polka dots is essential. D o not bring a leopard. Any leopards which do attend will be forcibly chai ned to a nearby fence. -ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user1@example.net +ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user4@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:user2 @example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:user3 @example.net -ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:user4 +ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:user1 @example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:user5 @example.net diff --git a/testing/tests/binding/1035-GET-mashup.result b/testing/tests/binding/1035-GET-mashup.result index 1c7f790b..b7f0f707 100644 --- a/testing/tests/binding/1035-GET-mashup.result +++ b/testing/tests/binding/1035-GET-mashup.result @@ -2,7 +2,7 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule -Content-Length: 22543 +Content-Length: 22410 Etag: "ae93907cb03bc025b8e733eb61f3a09e" Content-Type: text/calendar; charset="utf-8" @@ -388,19 +388,16 @@ UID:70399cd7-50a4-4be4-a665-af593e19a7fd SUMMARY:An invited event. Black tie with pink polka dots is essential. Do not bring a leopard. Any leopards which do attend will be forcibly chained to a nearby fence. -ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user1@example.ne +ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user4@example.ne t ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;SCHEDULE-S - TATUS="2.0\;Scheduling invitation delivered successfully":mailto:user2@e - xample.net + TATUS=1.2:mailto:user2@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;SCHEDULE-S - TATUS="2.0\;Scheduling invitation delivered successfully":mailto:user3@e - xample.net -ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use - r4@example.net + TATUS=1.2:mailto:user3@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;SCHEDULE-S - TATUS="2.0\;Scheduling invitation delivered successfully":mailto:user5@e - xample.net + TATUS=3.8:mailto:user1@example.net +ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;SCHEDULE-S + TATUS=1.2:mailto:user5@example.net DTSTART:20100322T160000 DTEND:20100322T170000 X-MOZ-GENERATION:3 @@ -416,14 +413,14 @@ UID:70399cd7-50a4-4be4-a665-af593e19a7fd SUMMARY:An invited event. Black tie with pink polka dots is essential. Do not bring a leopard. Any leopards which do attend will be forcibly chained to a nearby fence. -ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user1@example.ne +ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user4@example.ne t ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use r2@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use r3@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use - r4@example.net + r1@example.net ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use r5@example.net DTSTART:20100322T160000 diff --git a/testing/tests/binding/1036-REPORT-sync-initial-bound.result b/testing/tests/binding/1036-REPORT-sync-initial-bound.result index 84fa0969..36699bdb 100644 --- a/testing/tests/binding/1036-REPORT-sync-initial-bound.result +++ b/testing/tests/binding/1036-REPORT-sync-initial-bound.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule -ETag: "f7758fc9ba3182e47aba690683524e55" +ETag: "e9729234a084898506d4821483a404c9" Content-Length: 2292 Content-Type: text/xml; charset="utf-8" @@ -84,7 +84,7 @@ Content-Type: text/xml; charset="utf-8" /caldav.php/user2/home/70399cd7-50a4-4be4-a665-af593e19a7fd.ics - "baad41c9f24bd1ecbdde6e58882df9b7" + "ea6b316ca24db20f5eb37d1abd60f8c1" HTTP/1.1 200 OK diff --git a/testing/tests/scheduling/3010-PUT-with-attendees.result b/testing/tests/scheduling/3010-PUT-with-attendees.result index 7912e76e..3fb03d13 100644 --- a/testing/tests/scheduling/3010-PUT-with-attendees.result +++ b/testing/tests/scheduling/3010-PUT-with-attendees.result @@ -56,14 +56,14 @@ ORGANIZER;CN=User 1:MAILTO:user1@example.net ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RS VP=TRUE;CN=User 1;LANGUAGE=en:MAILTO:user1@example.net ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RS - VP=TRUE;CN=User 2;LANGUAGE=en;SCHEDULE-STATUS="2.0\;Scheduling invitatio - n delivered successfully":MAILTO:user2@example.net + VP=TRUE;CN=User 2;LANGUAGE=en;SCHEDULE-STATUS=1.2:MAILTO:user2@example.n + et ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RS - VP=TRUE;CN=User 3;LANGUAGE=en;SCHEDULE-STATUS="2.0\;Scheduling invitatio - n delivered successfully":MAILTO:user3@example.net + VP=TRUE;CN=User 3;LANGUAGE=en;SCHEDULE-STATUS=1.2:MAILTO:user3@example.n + et ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RS - VP=TRUE;CN=User 4;LANGUAGE=en;SCHEDULE-STATUS="2.0\;Scheduling invitatio - n delivered successfully":MAILTO:user4@example.net + VP=TRUE;CN=User 4;LANGUAGE=en;SCHEDULE-STATUS=1.2:MAILTO:user4@example.n + et END:VEVENT END:VCALENDAR < diff --git a/testing/tests/scheduling/3023-PUT-iCal-with-attendees.result b/testing/tests/scheduling/3023-PUT-iCal-with-attendees.result index 6945797a..e70291b6 100644 --- a/testing/tests/scheduling/3023-PUT-iCal-with-attendees.result +++ b/testing/tests/scheduling/3023-PUT-iCal-with-attendees.result @@ -39,9 +39,8 @@ DTEND;TZID=Pacific/Auckland:20111019T110000 ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: mailto:manager1@example.net ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; - PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS="3. - 8\;No authority to deliver invitations to user.":mailto:user1@example.ne - t + PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=3.8 + :mailto:user1@example.net TRANSP:OPAQUE SUMMARY:Meeting with User1 DTSTART;TZID=Pacific/Auckland:20111019T100000 diff --git a/testing/tests/scheduling/3024-PUT-iCal-with-attendees.result b/testing/tests/scheduling/3024-PUT-iCal-with-attendees.result index 36860e6c..76d93c82 100644 --- a/testing/tests/scheduling/3024-PUT-iCal-with-attendees.result +++ b/testing/tests/scheduling/3024-PUT-iCal-with-attendees.result @@ -44,9 +44,8 @@ DTEND;TZID=Pacific/Auckland:20111019T110000 ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: mailto:manager1@example.net ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; - PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS="2. - 0\;Scheduling invitation delivered successfully":mailto:user1@example.ne - t + PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2 + :mailto:user1@example.net TRANSP:OPAQUE SUMMARY:Meeting with User1 DTSTART;TZID=Pacific/Auckland:20111019T100000 diff --git a/testing/tests/scheduling/3025-DELETE-invite.result b/testing/tests/scheduling/3025-DELETE-invite.result new file mode 100644 index 00000000..798ba092 --- /dev/null +++ b/testing/tests/scheduling/3025-DELETE-invite.result @@ -0,0 +1,12 @@ +HTTP/1.1 204 No Content +Date: Dow, 01 Jan 2000 00:00:00 GMT +DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule +DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule +Content-Length: 0 +Content-Type: text/plain; charset="utf-8" + + + dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics< + + dav_name: >/user1/home/E1A13F04-iCal-schedule.ics< + diff --git a/testing/tests/scheduling/3025-DELETE-invite.test b/testing/tests/scheduling/3025-DELETE-invite.test new file mode 100644 index 00000000..6dcf874d --- /dev/null +++ b/testing/tests/scheduling/3025-DELETE-invite.test @@ -0,0 +1,18 @@ +# +# iCal DELETE's the invitation in the .in +# +TYPE=DELETE +URL=http://regression.host/user1/.in/E1A13F04-iCal-schedule.ics + +HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549) +HEAD + +# +# Query to confirm we got rid of it. There should be two now. +QUERY +SELECT dav_name + FROM calendar_item + WHERE uid = 'E1A13F04-iCal-schedule' + ORDER BY dav_id +ENDQUERY + diff --git a/testing/tests/scheduling/3026-PUT-Accept.result b/testing/tests/scheduling/3026-PUT-Accept.result new file mode 100644 index 00000000..9985afc7 --- /dev/null +++ b/testing/tests/scheduling/3026-PUT-Accept.result @@ -0,0 +1,134 @@ + + caldav_type: >VEVENT< + dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics< + logged_user: >10< + summary: >Meeting with User1< + user_no: >20< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T110000 +ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: + mailto:manager1@example.net +ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; + PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T100000 +DTSTAMP:20111018T200107Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:5 +END:VEVENT +END:VCALENDAR +< + + caldav_type: >VEVENT< + dav_name: >/user1/home/E1A13F04-iCal-schedule.ics< + logged_user: >10< + summary: >Meeting with User1< + user_no: >10< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T110000 +ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: + mailto:manager1@example.net +ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; + PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T100000 +DTSTAMP:20111018T200107Z +ORGANIZER;CN=Manager 1;SCHEDULE-STATUS=1.2:mailto:manager1@example.net +SEQUENCE:5 +END:VEVENT +END:VCALENDAR +< + + caldav_type: >VEVENT< + dav_name: >/manager1/.in/user1E1A13F04-iCal-schedule.ics< + logged_user: >10< + summary: >Meeting with User1< + user_no: >20< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +METHOD:REPLY +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T110000 +ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: + mailto:manager1@example.net +ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; + PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T100000 +DTSTAMP:20111018T200107Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:5 +END:VEVENT +END:VCALENDAR +< + diff --git a/testing/tests/scheduling/3026-PUT-Accept.test b/testing/tests/scheduling/3026-PUT-Accept.test new file mode 100644 index 00000000..aab1ac2e --- /dev/null +++ b/testing/tests/scheduling/3026-PUT-Accept.test @@ -0,0 +1,66 @@ +# +# Testing for iCal accepting an invitation +# +TYPE=PUT +URL=http://regression.host/user1/home/E1A13F04-iCal-schedule.ics + +HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549) +HEADER=If-Match: "905cdcc0d1a76ef63ef8d238575c3856" +HEADER=Content-Type: text/calendar + +# REPLACE=#\d{8}T\d{6}#YYYYMMDDThhmmss# +# REPLACE=/^DTSTAMP:\d{4}[01]\d[0123]\dT[012]\d[0-5]\d[0-6]\dZ\r?$/DTSTAMP:yyyymmddThhmmssZ/ + +# QUERY +# ENDQUERY + +BEGINDATA +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T110000 +ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag + er1@example.net +ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n + et";PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T100000 +DTSTAMP:20111018T200107Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:5 +END:VEVENT +END:VCALENDAR +ENDDATA + + +QUERY +SELECT caldav_data.user_no, caldav_data.dav_name, + caldav_type, logged_user, caldav_data.caldav_data AS "vcalendar", + summary +FROM caldav_data JOIN calendar_item USING(dav_name) LEFT JOIN timezones ON (tz_id=tzid) +WHERE calendar_item.uid = 'E1A13F04-iCal-schedule' +ORDER BY caldav_data.dav_id +ENDQUERY + diff --git a/testing/tests/scheduling/3027-PUT-iCal-with-attendees.result b/testing/tests/scheduling/3027-PUT-iCal-with-attendees.result new file mode 100644 index 00000000..5c2adf11 --- /dev/null +++ b/testing/tests/scheduling/3027-PUT-iCal-with-attendees.result @@ -0,0 +1,189 @@ +HTTP/1.1 204 No Content +Date: Dow, 01 Jan 2000 00:00:00 GMT +DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule +DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule +Content-Length: 0 +Content-Type: text/plain; charset="utf-8" + + + caldav_type: >VEVENT< + dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics< + logged_user: >20< + summary: >Meeting with User1< + user_no: >20< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T140000 +ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: + mailto:manager1@example.net +ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; + PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2 + :mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T130000 +DTSTAMP:20111024T035702Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:6 +END:VEVENT +END:VCALENDAR +< + + caldav_type: >VEVENT< + dav_name: >/user1/home/E1A13F04-iCal-schedule.ics< + logged_user: >20< + summary: >Meeting with User1< + user_no: >10< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T140000 +ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag + er1@example.net +ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n + et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex + ample.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T130000 +DTSTAMP:20111024T035702Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:6 +END:VEVENT +END:VCALENDAR +< + + caldav_type: >VEVENT< + dav_name: >/manager1/.in/user1E1A13F04-iCal-schedule.ics< + logged_user: >10< + summary: >Meeting with User1< + user_no: >20< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +METHOD:REPLY +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T110000 +ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED: + mailto:manager1@example.net +ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net; + PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T100000 +DTSTAMP:20111018T200107Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:5 +END:VEVENT +END:VCALENDAR +< + + caldav_type: >VEVENT< + dav_name: >/user1/.in/E1A13F04-iCal-schedule.ics< + logged_user: >20< + summary: >Meeting with User1< + user_no: >10< + vcalendar: >BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +METHOD:REQUEST +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T140000 +ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag + er1@example.net +ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n + et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex + ample.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T130000 +DTSTAMP:20111024T035702Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:6 +END:VEVENT +END:VCALENDAR +< + diff --git a/testing/tests/scheduling/3027-PUT-iCal-with-attendees.test b/testing/tests/scheduling/3027-PUT-iCal-with-attendees.test new file mode 100644 index 00000000..c9fce207 --- /dev/null +++ b/testing/tests/scheduling/3027-PUT-iCal-with-attendees.test @@ -0,0 +1,63 @@ +# +# PUT an event with attendees +# +TYPE=PUT +URL=http://regression.host/caldav.php/manager1/home/E1A13F04-iCal-schedule.ics +HEADER=Content-Type: text/calendar +HEADER=DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549) +HEADER=If-Match: "87421a4ff0b84a95a31db428ee6d11d9" +HEAD + +AUTH=manager1:manager1 + +BEGINDATA +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Apple Inc.//iCal 4.0.4//EN +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Pacific/Auckland +BEGIN:DAYLIGHT +TZOFFSETFROM:+1200 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:20070930T020000 +TZNAME:GMT+13:00 +TZOFFSETTO:+1300 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1300 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +DTSTART:20080406T030000 +TZNAME:GMT+12:00 +TZOFFSETTO:+1200 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20111018T195845Z +UID:E1A13F04-iCal-schedule +DTEND;TZID=Pacific/Auckland:20111019T140000 +ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag + er1@example.net +ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n + et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex + ample.net +TRANSP:OPAQUE +SUMMARY:Meeting with User1 +DTSTART;TZID=Pacific/Auckland:20111019T130000 +DTSTAMP:20111024T035702Z +ORGANIZER;CN="Manager 1":mailto:manager1@example.net +SEQUENCE:6 +END:VEVENT +END:VCALENDAR +ENDDATA + + +QUERY +SELECT caldav_data.user_no, caldav_data.dav_name, + caldav_type, logged_user, caldav_data.caldav_data AS "vcalendar", + summary +FROM caldav_data JOIN calendar_item USING(dav_name) LEFT JOIN timezones ON (tz_id=tzid) +WHERE calendar_item.uid = 'E1A13F04-iCal-schedule' +ORDER BY caldav_data.dav_id +ENDQUERY + diff --git a/testing/tests/timezone/Restore-Database.result b/testing/tests/timezone/Restore-Database.result index 0be04532..ba0eace9 100644 --- a/testing/tests/timezone/Restore-Database.result +++ b/testing/tests/timezone/Restore-Database.result @@ -1,6 +1,6 @@ setval -------- - 1654 + 1657 (1 row) setval