diff options
-rw-r--r-- | tests/functional/test_wallace/test_007_invitationpolicy.py | 51 | ||||
-rw-r--r-- | wallace/module_invitationpolicy.py | 36 |
2 files changed, 83 insertions, 4 deletions
diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py index 9bc808f..568a0e8 100644 --- a/tests/functional/test_wallace/test_007_invitationpolicy.py +++ b/tests/functional/test_wallace/test_007_invitationpolicy.py @@ -105,6 +105,27 @@ END:VEVENT END:VCALENDAR """ +itip_delegated = """ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//pykolab-0.6.9-1//kolab.org// +CALSCALE:GREGORIAN +METHOD:REPLY +BEGIN:VEVENT +SUMMARY:%(summary)s +UID:%(uid)s +DTSTART;TZID=Europe/Berlin;VALUE=DATE-TIME:%(start)s +DTEND;TZID=Europe/Berlin;VALUE=DATE-TIME:%(end)s +DTSTAMP;VALUE=DATE-TIME:20140706T171038Z +ORGANIZER;CN="Doe, John":MAILTO:%(organizer)s +ATTENDEE;PARTSTAT=DELEGATED;DELEGATED-TO=jack@ripper.com;ROLE=NON-PARTICIPANT:mailto:%(mailto)s +ATTENDEE;PARTSTAT=%(partstat)s;DELEGATED-FROM=%(mailto)s;ROLE=REQ-PARTICIPANT:mailto:jack@ripper.com +PRIORITY:0 +SEQUENCE:%(sequence)d +END:VEVENT +END:VCALENDAR +""" + mime_message = """MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_c8894dbdb8baeedacae836230e3436fd" @@ -584,6 +605,36 @@ class TestWallaceInvitationpolicy(unittest.TestCase): self.assertEqual(event.get_attachment_data(0), 'This is a text attachment') + def test_006_invitation_reply_delegated(self): + self.purge_mailbox(self.john['mailbox']) + + start = datetime.datetime(2014,8,28, 14,30,0, tzinfo=pytz.timezone("Europe/Berlin")) + uid = self.create_calendar_event(start, user=self.john) + + event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + self.assertIsInstance(event, pykolab.xml.Event) + + # send a reply from jane to john + self.send_itip_reply(uid, self.jane['mail'], self.john['mail'], start=start, template=itip_delegated, partstat='NEEDS-ACTION') + + # check for the updated event in john's calendar + time.sleep(10) + event = self.check_user_calendar_event(self.john['kolabtargetfolder'], uid) + self.assertIsInstance(event, pykolab.xml.Event) + + attendee = event.get_attendee(self.jane['mail']) + self.assertIsInstance(attendee, pykolab.xml.Attendee) + self.assertEqual(attendee.get_participant_status(), kolabformat.PartDelegated) + # FIXME: self.assertEqual(len(attendee.get_delegated_to()), 1) + # FIXME: self.assertEqual(attendee.get_delegated_to(True)[0], 'jack@ripper.com') + + delegatee = event.get_attendee('jack@ripper.com') + self.assertIsInstance(delegatee, pykolab.xml.Attendee) + self.assertEqual(delegatee.get_participant_status(), kolabformat.PartNeedsAction) + # FIXME: self.assertEqual(len(delegatee.get_delegated_from()), 1) + # FIXME: self.assertEqual(delegatee.get_delegated_from(True)[0], self.jane['mail']) + + def test_007_invitation_cancel(self): self.purge_mailbox(self.john['mailbox']) diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py index 92e1fea..6dfc111 100644 --- a/wallace/module_invitationpolicy.py +++ b/wallace/module_invitationpolicy.py @@ -424,7 +424,7 @@ def process_itip_reply(itip_event, policy, recipient_email, sender_email, receiv return MESSAGE_FORWARD # find existing event in user's calendar - # TODO: set/check lock to avoid concurrent wallace processes trying to update the same event simultaneously + # sets/checks lock to avoid concurrent wallace processes trying to update the same event simultaneously existing = find_existing_event(itip_event['uid'], receiving_user, True) if existing: @@ -438,13 +438,41 @@ def process_itip_reply(itip_event, policy, recipient_email, sender_email, receiv log.debug(_("Auto-updating event %r on iTip REPLY") % (existing.uid), level=8) try: + existing_attendee = existing.get_attendee(sender_email) existing.set_attendee_participant_status(sender_email, sender_attendee.get_participant_status(), rsvp=False) except Exception, e: log.error("Could not find corresponding attende in organizer's event: %r" % (e)) - # TODO: accept new participant if ACT_ACCEPT ? - remove_write_lock(existing._lock_key) - return MESSAGE_FORWARD + # append delegated-from attendee ? + if len(sender_attendee.get_delegated_from()) > 0: + existing._attendees.append(sender_attendee) + existing.event.setAttendees(existing._attendees) + else: + # TODO: accept new participant if ACT_ACCEPT ? + remove_write_lock(existing._lock_key) + return MESSAGE_FORWARD + + # append delegated-to attendee + if len(sender_attendee.get_delegated_to()) > 0: + try: + delegatee_email = sender_attendee.get_delegated_to(True)[0] + sender_delegatee = itip_event['xml'].get_attendee_by_email(delegatee_email) + existing_delegatee = existing.find_attendee(delegatee_email) + + if not existing_delegatee: + existing._attendees.append(sender_delegatee) + log.debug(_("Add delegatee: %r") % (sender_delegatee.to_dict()), level=9) + else: + existing_delegatee.copy_from(sender_delegatee) + log.debug(_("Update existing delegatee: %r") % (existing_delegatee.to_dict()), level=9) + + # copy all parameters from replying attendee (e.g. delegated-to, role, etc.) + existing_attendee.copy_from(sender_attendee) + existing.event.setAttendees(existing._attendees) + log.debug(_("Update delegator: %r") % (existing_attendee.to_dict()), level=9) + + except Exception, e: + log.error("Could not find delegated-to attendee: %r" % (e)) # update the organizer's copy of the event if update_event(existing, receiving_user): |