[CalendarServer-changes] [2813] CalendarServer/branches/users/sagen/mailgateway-implicit-2745/ twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Tue Aug 12 17:58:02 PDT 2008


Revision: 2813
          http://trac.macosforge.org/projects/calendarserver/changeset/2813
Author:   sagen at apple.com
Date:     2008-08-12 17:58:01 -0700 (Tue, 12 Aug 2008)
Log Message:
-----------
Now inbound DSN messages are parsed and the failure is injected by setting "REQUEST-STATUS:5.1;Service unavailable" property

Modified Paths:
--------------
    CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/mail.py
    CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/test/test_mail.py

Modified: CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/mail.py
===================================================================
--- CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/mail.py	2008-08-12 23:08:08 UTC (rev 2812)
+++ CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/mail.py	2008-08-13 00:58:01 UTC (rev 2813)
@@ -35,6 +35,7 @@
 from twistedcaldav.scheduling.scheduler import IMIPScheduler
 from twistedcaldav.config import config, parseConfig, defaultConfig
 from twistedcaldav.sql import AbstractSQLDatabase
+from twistedcaldav.ical import Property
 from zope.interface import Interface, implements
 import email, email.utils
 import uuid
@@ -478,9 +479,9 @@
         self.db = MailGatewayTokensDatabase(dataRoot)
 
     def checkDSN(self, message):
-        # returns (isDSN, Action, Original Message-ID)
+        # returns (isDSN, Action, icalendar attachment)
 
-        report = deliveryStatus = original = None
+        report = deliveryStatus = original = calBody = None
 
         for part in message.walk():
             content_type = part.get_content_type()
@@ -493,6 +494,9 @@
             elif content_type == "message/rfc822":
                 original = part
                 continue
+            elif content_type == "text/calendar":
+                calBody = part.get_payload(decode=True)
+                continue
 
         if report is not None and deliveryStatus is not None:
             # we have what appears to be a DSN
@@ -507,41 +511,59 @@
             else:
                 action = None
 
-            if action is None or original is None:
-                # This is a DSN we can't do anything with
-                return True, None, None
+            return True, action, calBody
 
-            lines = str(original).split("\n")
-            for line in lines:
-                lower = line.lower()
-                if lower.startswith("message-id:"):
-                    # found Message-ID:
-                    messageID = lower.split(' ')[1]
-                    break
-            else:
-                messageID = None
 
-            return True, action, messageID
-
         else:
             # Not a DSN
             return False, None, None
 
 
 
+    def _extractToken(self, text):
+        try:
+            pre, post = text.split('@')
+            pre, token = pre.split('+')
+            return token
+        except ValueError:
+            return None
 
 
     def inbound(self, message):
         msg = email.message_from_string(message)
 
-        isDSN, action, original = self.checkDSN(msg)
+        isDSN, action, calBody = self.checkDSN(msg)
         if isDSN:
-            if action == 'failed' and original:
+            if action == 'failed' and calBody:
                 # This is a DSN we can handle
-                pass
+                calendar = ical.Component.fromString(calBody)
+                # Extract the token (from organizer property)
+                organizer = calendar.getOrganizer()
+                token = self._extractToken(organizer)
+                if not token:
+                    self.log_error("Mail gateway can't find token in DSN %s" % (msg['Message-ID'],))
+                    return
+
+                result = self.db.lookupByToken(token)
+                if result is None:
+                    # This isn't a token we recognize
+                    self.log_error("Mail gateway found a token (%s) but didn't recognize it in DSN %s" % (token, msg['Message-ID']))
+                    return
+
+                organizer, attendee = result
+                organizer = str(organizer)
+                attendee = str(attendee)
+                calendar.getOrganizerProperty().setValue(organizer)
+                calendar.addProperty(Property("REQUEST-STATUS",
+                    "5.1;Service unavailable"))
+
+                self.log_error("Mail gateway processing DSN %s" % (msg['Message-ID'],))
+                return injectMessage(organizer, attendee, calendar,
+                    msg['Message-ID'])
+
             else:
                 # It's a DSN without enough to go on
-                self.log_error("Can't process DSN %s" % (msg['Message-ID'],))
+                self.log_error("Mail gateway can't process DSN %s" % (msg['Message-ID'],))
                 return
 
         self.log_info("Mail gateway received message %s from %s to %s" %
@@ -553,10 +575,8 @@
         name, addr = email.utils.parseaddr(msg['To'])
         if addr:
             # addr looks like: server_address+token at example.com
-            try:
-                pre, post = addr.split('@')
-                pre, token = pre.split('+')
-            except ValueError:
+            token = self._extractToken(addr)
+            if not token:
                 self.log_error("Mail gateway didn't find a token in message %s (%s)" % (msg['Message-ID'], msg['To']))
                 return
         else:

Modified: CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/test/test_mail.py
===================================================================
--- CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/test/test_mail.py	2008-08-12 23:08:08 UTC (rev 2812)
+++ CalendarServer/branches/users/sagen/mailgateway-implicit-2745/twistedcaldav/test/test_mail.py	2008-08-13 00:58:01 UTC (rev 2813)
@@ -34,9 +34,9 @@
 
         data = {
             'good_reply' : (False, None, None),
-            'dsn_failure_no_ics' : (True, "failed", "<40900559-dab1-4956-ba87-f88e00cf5104 at example.com>"),
-            'dsn_failure_with_ics' : (True, "failed", "<20080812191939.51369.1538816694.0 at plugh.example.com>"),
-            'dsn_failure_no_original' : (True, None, None),
+            'dsn_failure_no_original' : (True, 'failed', None),
+            'dsn_failure_no_ics' : (True, 'failed', None),
+            'dsn_failure_with_ics' : (True, 'failed', 'BEGIN:VCALENDAR\nVERSION:2.0\nCALSCALE:GREGORIAN\nMETHOD:REQUEST\nPRODID:-//example Inc.//iCal 3.0//EN\nBEGIN:VTIMEZONE\nTZID:US/Pacific\nBEGIN:STANDARD\nDTSTART:20071104T020000\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\nTZNAME:PST\nTZOFFSETFROM:-0700\nTZOFFSETTO:-0800\nEND:STANDARD\nBEGIN:DAYLIGHT\nDTSTART:20070311T020000\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\nTZNAME:PDT\nTZOFFSETFROM:-0800\nTZOFFSETTO:-0700\nEND:DAYLIGHT\nEND:VTIMEZONE\nBEGIN:VEVENT\nUID:1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C\nDTSTART;TZID=US/Pacific:20080812T094500\nDTEND;TZID=US/Pacific:20080812T104500\nATTENDEE;CUTYPE=INDIVIDUAL;CN=User 01;PARTSTAT=ACCEPTED:mailto:user01 at exam\n ple.com\nATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-A\n CTION;CN=nonexistant at example.com:mailto:nonexistant at example.com\nCREATED:20080812T191857Z\nDTSTAMP:20080812T191932Z\nORGANIZER;CN=User 01:mailto:xyzzy+8e16b897-d544-4217-88e9-a363d08\n 46f6c at ex
 ample.com\nSEQUENCE:2\nSUMMARY:New Event\nTRANSP:OPAQUE\nEND:VEVENT\nEND:VCALENDAR\n'),
         }
 
         for filename, expected in data.iteritems():
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080812/440fbdd0/attachment-0001.html 


More information about the calendarserver-changes mailing list