summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2015-02-02 18:31:41 +0100
committerThomas Bruederli <bruederli@kolabsys.com>2015-02-02 18:31:41 +0100
commit8bd5f266bcb6a230274984e085260795c052919d (patch)
tree177975e4866979d695c91159111624bb66263cc2
parent6648f7334a89b18411b8db8f515dfe9e18146c62 (diff)
downloadpykolab-8bd5f266bcb6a230274984e085260795c052919d.tar.gz
Implement additional policy value *_SAVE_AND_FORWARD to still pass through the original iTip message after saving it to the invitation calendar (#4269)
-rw-r--r--tests/functional/test_wallace/test_007_invitationpolicy.py32
-rw-r--r--wallace/module_invitationpolicy.py12
2 files changed, 43 insertions, 1 deletions
diff --git a/tests/functional/test_wallace/test_007_invitationpolicy.py b/tests/functional/test_wallace/test_007_invitationpolicy.py
index d18e1f3..dee15bf 100644
--- a/tests/functional/test_wallace/test_007_invitationpolicy.py
+++ b/tests/functional/test_wallace/test_007_invitationpolicy.py
@@ -14,6 +14,7 @@ from pykolab.translate import _
from pykolab.xml import event_from_message
from pykolab.xml import todo_from_message
from pykolab.xml import participant_status_label
+from pykolab.itip import events_from_message
from email import message_from_string
from twisted.trial import unittest
@@ -287,6 +288,17 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
'kolabinvitationpolicy': ['ACT_ACCEPT','ACT_UPDATE_AND_NOTIFY']
}
+ self.lucy = {
+ 'displayname': 'Lucy Meyer',
+ 'mail': 'lucy.meyer@example.org',
+ 'dn': 'uid=meyer,ou=People,dc=example,dc=org',
+ 'preferredlanguage': 'en_US',
+ 'mailbox': 'user/lucy.meyer@example.org',
+ 'kolabcalendarfolder': 'user/lucy.meyer/Calendar@example.org',
+ 'kolabtasksfolder': 'user/lucy.meyer/Tasks@example.org',
+ 'kolabinvitationpolicy': ['ALL_SAVE_AND_FORWARD','ACT_UPDATE_AND_NOTIFY']
+ }
+
self.external = {
'displayname': 'Bob External',
'mail': 'bob.external@gmail.com'
@@ -297,6 +309,7 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
user_add("Jane", "Manager", kolabinvitationpolicy=self.jane['kolabinvitationpolicy'], preferredlanguage=self.jane['preferredlanguage'])
user_add("Jack", "Tentative", kolabinvitationpolicy=self.jack['kolabinvitationpolicy'], preferredlanguage=self.jack['preferredlanguage'])
user_add("Mark", "German", kolabinvitationpolicy=self.mark['kolabinvitationpolicy'], preferredlanguage=self.mark['preferredlanguage'])
+ user_add("Lucy", "Meyer", kolabinvitationpolicy=self.lucy['kolabinvitationpolicy'], preferredlanguage=self.lucy['preferredlanguage'])
time.sleep(1)
from tests.functional.synchronize import synchronize_once
@@ -655,6 +668,25 @@ class TestWallaceInvitationpolicy(unittest.TestCase):
self.assertEqual(event.get_summary(), "test2")
self.assertEqual(event.get_attendee(self.jack['mail']).get_participant_status(), kolabformat.PartNeedsAction)
+ def test_004_copy_to_calendar_and_forward(self):
+ uid = self.send_itip_invitation(self.lucy['mail'], datetime.datetime(2015,2,11, 14,0,0), summary="test forward")
+ response = self.check_message_received(self.itip_reply_subject % { 'summary':'test forward', 'status':participant_status_label('ACCEPTED') }, self.lucy['mail'], self.lucy['mailbox'])
+ self.assertEqual(response, None, "No reply expected")
+
+ event = self.check_user_calendar_event(self.lucy['kolabcalendarfolder'], uid)
+ self.assertIsInstance(event, pykolab.xml.Event)
+ self.assertEqual(event.get_summary(), "test forward")
+ self.assertEqual(event.get_attendee(self.lucy['mail']).get_participant_status(), kolabformat.PartNeedsAction)
+
+ # find original itip invitation in user's inbox
+ message = self.check_message_received('"test"', 'john.doe@example.org', self.lucy['mailbox'])
+ self.assertIsInstance(message, email.message.Message)
+
+ itips = events_from_message(message)
+ self.assertEqual(len(itips), 1);
+ self.assertEqual(itips[0]['method'], 'REQUEST');
+ self.assertEqual(itips[0]['uid'], uid);
+
def test_005_invite_rescheduling_accept(self):
self.purge_mailbox(self.john['mailbox'])
diff --git a/wallace/module_invitationpolicy.py b/wallace/module_invitationpolicy.py
index d473d52..0a38fcc 100644
--- a/wallace/module_invitationpolicy.py
+++ b/wallace/module_invitationpolicy.py
@@ -62,12 +62,14 @@ COND_IF_AVAILABLE = 64
COND_IF_CONFLICT = 128
COND_TENTATIVE = 256
COND_NOTIFY = 512
+COND_FORWARD = 4096
COND_TYPE_EVENT = 1024
COND_TYPE_TASK = 2048
COND_TYPE_ALL = COND_TYPE_EVENT + COND_TYPE_TASK
ACT_TENTATIVE = ACT_ACCEPT + COND_TENTATIVE
ACT_UPDATE_AND_NOTIFY = ACT_UPDATE + COND_NOTIFY
+ACT_SAVE_AND_FORWARD = ACT_SAVE_TO_FOLDER + COND_FORWARD
FOLDER_TYPE_ANNOTATION = '/vendor/kolab/folder-type'
@@ -83,6 +85,7 @@ policy_name_map = {
'ALL_UPDATE': ACT_UPDATE + COND_TYPE_ALL,
'ALL_UPDATE_AND_NOTIFY': ACT_UPDATE_AND_NOTIFY + COND_TYPE_ALL,
'ALL_SAVE_TO_FOLDER': ACT_SAVE_TO_FOLDER + COND_TYPE_ALL,
+ 'ALL_SAVE_AND_FORWARD': ACT_SAVE_AND_FORWARD + COND_TYPE_ALL,
# event related policy values
'EVENT_MANUAL': ACT_MANUAL + COND_TYPE_EVENT,
'EVENT_ACCEPT': ACT_ACCEPT + COND_TYPE_EVENT,
@@ -96,6 +99,7 @@ policy_name_map = {
'EVENT_DELEGATE_IF_CONFLICT': ACT_DELEGATE + COND_IF_CONFLICT + COND_TYPE_EVENT,
'EVENT_REJECT_IF_CONFLICT': ACT_REJECT + COND_IF_CONFLICT + COND_TYPE_EVENT,
'EVENT_SAVE_TO_FOLDER': ACT_SAVE_TO_FOLDER + COND_TYPE_EVENT,
+ 'EVENT_SAVE_AND_FORWARD': ACT_SAVE_AND_FORWARD + COND_TYPE_EVENT,
# task related policy values
'TASK_MANUAL': ACT_MANUAL + COND_TYPE_TASK,
'TASK_ACCEPT': ACT_ACCEPT + COND_TYPE_TASK,
@@ -104,6 +108,7 @@ policy_name_map = {
'TASK_UPDATE': ACT_UPDATE + COND_TYPE_TASK,
'TASK_UPDATE_AND_NOTIFY': ACT_UPDATE_AND_NOTIFY + COND_TYPE_TASK,
'TASK_SAVE_TO_FOLDER': ACT_SAVE_TO_FOLDER + COND_TYPE_TASK,
+ 'TASK_SAVE_AND_FORWARD': ACT_SAVE_AND_FORWARD + COND_TYPE_TASK,
# legacy values
'ACT_MANUAL': ACT_MANUAL + COND_TYPE_ALL,
'ACT_ACCEPT': ACT_ACCEPT + COND_TYPE_ALL,
@@ -117,6 +122,7 @@ policy_name_map = {
'ACT_UPDATE': ACT_UPDATE + COND_TYPE_ALL,
'ACT_UPDATE_AND_NOTIFY': ACT_UPDATE_AND_NOTIFY + COND_TYPE_ALL,
'ACT_SAVE_TO_CALENDAR': ACT_SAVE_TO_FOLDER + COND_TYPE_EVENT,
+ 'ACT_SAVE_AND_FORWARD': ACT_SAVE_AND_FORWARD + COND_TYPE_EVENT,
}
policy_value_map = dict([(v &~ COND_TYPE_ALL, k) for (k, v) in policy_name_map.iteritems()])
@@ -467,7 +473,11 @@ def process_itip_request(itip_event, policy, recipient_email, sender_email, rece
if not nonpart or existing:
# save new copy from iTip
if store_object(itip_event['xml'], receiving_user, targetfolder):
- return MESSAGE_PROCESSED
+ if policy & COND_FORWARD:
+ log.debug(_("Forward invitation for notification"), level=5)
+ return MESSAGE_FORWARD
+ else:
+ return MESSAGE_PROCESSED
return None