Files
jcoffey-dev 6efa90cfc1 Calendar: answer iTIP REFRESH and REPLY only from the event's attendees
An organizer's server sent the whole event, with every attendee, the
description and the location, to anyone who sent a REFRESH with the
event's UID, including attendees who had been removed and people who
were never invited. A REPLY for an instance the organizer hadn't
changed was stored as a new instance as long as the sender listed
itself as an attendee of the reply, so a removed attendee or a
stranger could add instances on any date, with any ORGANIZER parameters
and any other ATTENDEE lines; those attendees would then get the
organizer's next update.

A REFRESH is now answered only when the sender is an attendee of the
stored event. A REPLY for an unchanged instance needs the sender to be
an attendee of the series and the date to be one of the series' own
dates. The new instance takes its ORGANIZER, UID and SEQUENCE from the
organizer's copy and the sender's own ATTENDEE line with the answer
applied; only the people the sender delegated to are added from the
reply.

The recurring to-do test used a RECURRENCE-ID that is not a date of
its series; it now uses the series' second date.

Test: a REFRESH from someone never invited returned the full event on
main, and a removed attendee's REPLY created an instance; a REPLY that
added another attendee stored that attendee, and one for a date outside
the series stored it. Now each is refused or ignored and the
organizer's copy holds only the attendee's own answer.
2026-10-28 21:54:34 -07:00

502 lines
16 KiB
Plaintext

# RFC5546 - Todo Request
# A sample todo is sent from "A" to "B", "C", and "D".
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
METHOD:REQUEST
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
DTSTART:19970701T170000Z
DUE:19970722T170000Z
PRIORITY:1
SUMMARY:Create the requirements document
UID:[email protected]
SEQUENCE:0
DTSTAMP:19970717T200000Z
STATUS:NEEDS-ACTION
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected], [email protected], [email protected]
summary: invite
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:0
END:VTODO
END:VCALENDAR
# Send iTIP request to the attendees
> send
# Make sure B received the todo
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:0
END:VTODO
END:VCALENDAR
# "B" accepts the to-do.
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
ATTENDEE;PARTSTAT=ACCEPTED:mailto:[email protected]
UID:[email protected]
COMMENT:I'll send you my input by email
SEQUENCE:1
PRIORITY:1
STATUS:IN-PROCESS
DTSTART:19970701T170000Z
DUE:19970722T170000Z
DTSTAMP:19970717T203000Z
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected]
summary: rsvp ACCEPTED
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
STATUS:IN-PROCESS
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=ACCEPTED:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
REQUEST-STATUS:2.0;Success
END:VTODO
END:VCALENDAR
# Send iTIP reply to the organizer
> send
# Make sure "A" received the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:IN-PROCESS
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:[email protected]
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:1
SEQUENCE:0
END:VTODO
END:VCALENDAR
# "B" updates percent completion of the to-do.
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
PERCENT-COMPLETE:75
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:[email protected]
UID:[email protected]
COMMENT:I'll send you my input by email
SEQUENCE:1
PRIORITY:1
STATUS:IN-PROCESS
DTSTART:19970701T170000Z
DUE:19970722T170000Z
DTSTAMP:19970717T203000Z
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected]
summary: rsvp IN-PROCESS
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
STATUS:IN-PROCESS
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
REQUEST-STATUS:2.0;Success
END:VTODO
END:VCALENDAR
# Send iTIP reply to the organizer
> send
# Make sure "A" received the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
PRIORITY:1
STATUS:IN-PROCESS
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=IN-PROCESS;SCHEDULE-STATUS=2.0:mailto:[email protected]
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:1
SEQUENCE:0
END:VTODO
END:VCALENDAR
# "D" completed the to-do.
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
ATTENDEE;PARTSTAT=COMPLETED:mailto:[email protected]
UID:[email protected]
COMMENT:I'll send you my input by email
SEQUENCE:1
PRIORITY:1
DTSTART:19970701T170000Z
DUE:19970722T170000Z
DTSTAMP:19970717T203000Z
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected]
summary: rsvp COMPLETED
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=COMPLETED:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
REQUEST-STATUS:2.0;Success
END:VTODO
END:VCALENDAR
# Send iTIP reply to the organizer
> send
# Make sure "A" received the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
PRIORITY:1
STATUS:IN-PROCESS
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;PARTSTAT=COMPLETED;SCHEDULE-STATUS=2.0:mailto:[email protected]
ATTENDEE;PARTSTAT=IN-PROCESS;SCHEDULE-STATUS=2.0:mailto:[email protected]
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:1
SEQUENCE:0
END:VTODO
END:VCALENDAR
# Recurring to-do request
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:[email protected]
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTART:19980101T100000Z
DUE:19980103T100000Z
SUMMARY:Send Status Reports to Area Managers
UID:[email protected]
SEQUENCE:0
DTSTAMP:19970717T200000Z
STATUS:NEEDS-ACTION
PRIORITY:1
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected], [email protected]
summary: update REQUEST
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 883648800, tz_id: 32768 })
summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: None, count: Some(10), interval: None, bysecond: [], byminute: [], byhour: [], byday: [ICalendarDay { ordwk: Some(1), weekday: Friday }], bymonthday: [], byyearday: [], byweekno: [], bymonth: [], bysetpos: [], wkst: None, rscale: None, skip: None })
summary.summary: Text("Send Status Reports to Area Managers")
~summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
~summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
~summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Send Status Reports to Area Managers
DUE:19980103T100000Z
DTSTART:19980101T100000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:b@example
.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:d@example
.com
ORGANIZER:mailto:[email protected]
UID:[email protected]
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTAMP:0
SEQUENCE:1
END:VTODO
END:VCALENDAR
================================
from: [email protected]
to: [email protected]
summary: cancel
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: None, count: Some(10), interval: None, bysecond: [], byminute: [], byhour: [], byday: [ICalendarDay { ordwk: Some(1), weekday: Friday }], bymonthday: [], byyearday: [], byweekno: [], bymonth: [], bysetpos: [], wkst: None, rscale: None, skip: None })
summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
STATUS:CANCELLED
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
END:VTODO
END:VCALENDAR
> send
# Make sure "C" received the cancel request
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:CANCELLED
SUMMARY:Create the requirements document
DUE:19970722T170000Z
DTSTART:19970701T170000Z
ATTENDEE;RSVP=TRUE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
DTSTAMP:0
END:VTODO
END:VCALENDAR
# Make sure "B" received the updated to-do
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
COMMENT:I'll send you my input by email
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Send Status Reports to Area Managers
DUE:19980103T100000Z
DTSTART:19980101T100000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:b@example
.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:d@example
.com
ORGANIZER:mailto:[email protected]
UID:[email protected]
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTAMP:0
SEQUENCE:1
END:VTODO
END:VCALENDAR
# Reply to an instance of a recurring to-do
> put [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
COMMENT:I'll send you my input by email
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Send Status Reports to Area Managers
DUE:19980103T100000Z
DTSTART:19980101T100000Z
ATTENDEE;ROLE=CHAIR;PARTSTAT=NEEDS-ACTION:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:b@example
.com
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION:mailto:d@example
.com
ORGANIZER:mailto:[email protected]
UID:[email protected]
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTAMP:19970717T233000Z
SEQUENCE:1
END:VTODO
BEGIN:VTODO
ORGANIZER:mailto:[email protected]
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:[email protected]
PERCENT-COMPLETE:75
UID:[email protected]
DTSTAMP:19970717T233000Z
RECURRENCE-ID:19980102T100000Z
SEQUENCE:1
END:VTODO
END:VCALENDAR
> expect
from: [email protected]
to: [email protected]
summary: rsvp NEEDS-ACTION
summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
summary.dtstart: Time(ItipTime { start: 883648800, tz_id: 32768 })
summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: None, count: Some(10), interval: None, bysecond: [], byminute: [], byhour: [], byday: [ICalendarDay { ordwk: Some(1), weekday: Friday }], bymonthday: [], byyearday: [], byweekno: [], bymonth: [], bysetpos: [], wkst: None, rscale: None, skip: None })
summary.summary: Text("Send Status Reports to Area Managers")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//inbuxa//inbuxa Server//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:[email protected]
ORGANIZER:mailto:[email protected]
RECURRENCE-ID:19980102T100000Z
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
REQUEST-STATUS:2.0;Success
END:VTODO
END:VCALENDAR
> send
# Make sure "A" received the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Example/ExampleCalendarClient//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Send Status Reports to Area Managers
DUE:19980103T100000Z
DTSTART:19980101T100000Z
ATTENDEE;ROLE=CHAIR:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:mailto:[email protected]
ORGANIZER:mailto:[email protected]
UID:[email protected]
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
DTSTAMP:1
SEQUENCE:1
END:VTODO
BEGIN:VTODO
PERCENT-COMPLETE:75
ATTENDEE;CUTYPE=INDIVIDUAL;PARTSTAT=IN-PROCESS;SCHEDULE-STATUS=2.0:mailto:[email protected]
ORGANIZER:mailto:[email protected]
RECURRENCE-ID:19980102T100000Z
UID:[email protected]
DTSTAMP:0
SEQUENCE:1
END:VTODO
END:VCALENDAR