[CalendarServer-changes] [14963] CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav /datastore/scheduling/imip
source_changes at macosforge.org
source_changes at macosforge.org
Tue Jul 14 14:01:30 PDT 2015
Revision: 14963
http://trac.calendarserver.org//changeset/14963
Author: cdaboo at apple.com
Date: 2015-07-14 14:01:30 -0700 (Tue, 14 Jul 2015)
Log Message:
-----------
Fix iMIP send failures when organizer CN is missing or contains non-ascii characters. Make sure iMIP message-ids use the configured server host name as the domain portion of the id.
Modified Paths:
--------------
CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/inbound.py
CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/outbound.py
CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/smtpsender.py
CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py
Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/inbound.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/inbound.py 2015-07-14 20:58:41 UTC (rev 14962)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/inbound.py 2015-07-14 21:01:30 UTC (rev 14963)
@@ -28,7 +28,6 @@
from twisted.internet import protocol, defer, ssl
from twisted.internet.defer import inlineCallbacks, returnValue, succeed
from twisted.mail import pop3client, imap4
-from twisted.mail.smtp import messageid
from twistedcaldav.config import config
from twistedcaldav.ical import Property, Component
@@ -349,7 +348,7 @@
del msg["To"]
msg["To"] = toAddr
log.warn("Mail gateway forwarding reply back to organizer")
- yield smtpSender.sendMessage(fromAddr, toAddr, messageid(), msg.as_string())
+ yield smtpSender.sendMessage(fromAddr, toAddr, SMTPSender.betterMessageID(), msg.as_string())
returnValue(self.REPLY_FORWARDED_TO_ORGANIZER)
# Process the imip attachment; inject to calendar server
Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/outbound.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/outbound.py 2015-07-14 20:58:41 UTC (rev 14962)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/outbound.py 2015-07-14 21:01:30 UTC (rev 14963)
@@ -32,7 +32,7 @@
from twext.enterprise.queue import WorkItem
from twext.python.log import Logger
from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.mail.smtp import messageid, rfc822date
+from twisted.mail.smtp import rfc822date
from twisted.web.microdom import Text as DOMText, Element as DOMElement
from twisted.web.microdom import parseString
from twisted.web.template import XMLString, TEMPLATE_NAMESPACE, Element, renderer, flattenString, tags
@@ -449,6 +449,8 @@
orgEmail = organizerMailto[7:]
orgCN = calendar.getOrganizerProperty().parameterValue('CN', None)
+ if orgCN:
+ orgCN = orgCN.decode("utf-8")
addressWithToken = formattedFrom
# At the point we've created the token in the db, which we always
@@ -552,7 +554,7 @@
msg["Reply-To"] = replyToAddress
msg["To"] = toAddress
msg["Date"] = rfc822date()
- msgId = messageid()
+ msgId = SMTPSender.betterMessageID()
msg["Message-ID"] = msgId
msgAlt = MIMEMultipart("alternative")
@@ -654,8 +656,9 @@
# template stuff, and once again, it's just a 'mailto:'.
# tags.a(href="mailto:"+email)[cn]
if orgEmail:
- details['htmlOrganizer'] = tags.a(href="mailto:%s" % (orgEmail,))(
- orgCN)
+ if not orgCN:
+ orgCN = orgEmail
+ details['htmlOrganizer'] = tags.a(href="mailto:%s" % (orgEmail,))(orgCN)
else:
details['htmlOrganizer'] = orgCN
Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/smtpsender.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/smtpsender.py 2015-07-14 20:58:41 UTC (rev 14962)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/smtpsender.py 2015-07-14 21:01:30 UTC (rev 14963)
@@ -24,7 +24,8 @@
from twext.internet.gaiendpoint import GAIEndpoint
from twext.python.log import Logger
from twisted.internet import defer, ssl, reactor as _reactor
-from twisted.mail.smtp import ESMTPSenderFactory
+from twisted.mail.smtp import ESMTPSenderFactory, messageid
+from twistedcaldav.config import config
log = Logger()
@@ -74,3 +75,15 @@
deferred.addCallback(_success, msgId, fromAddr, toAddr)
deferred.addErrback(_failure, msgId, fromAddr, toAddr)
return deferred
+
+
+ @staticmethod
+ def betterMessageID():
+ """
+ Strip out the domain in the default Twisted Message-ID value and replace with our configured
+ server host name. That will avoid leaking internal app-server host names in a multi-host setup.
+
+ @return: our safe message-id value
+ @rtype: L{str}
+ """
+ return "{}@{}>".format(messageid().split("@")[0], config.ServerHostName)
Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py 2015-07-14 20:58:41 UTC (rev 14962)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py 2015-07-14 21:01:30 UTC (rev 14963)
@@ -57,7 +57,7 @@
DESCRIPTION:awesome description with "<" and "&"
END:VEVENT
END:VCALENDAR
-"""
+""".encode("utf-8")
inviteTextNoTimezone = u"""BEGIN:VCALENDAR
VERSION:2.0
@@ -80,7 +80,7 @@
DESCRIPTION:awesome description with "<" and "&"
END:VEVENT
END:VCALENDAR
-"""
+""".encode("utf-8")
inviteTextWithTimezone = u"""BEGIN:VCALENDAR
VERSION:2.0
@@ -246,7 +246,7 @@
DESCRIPTION:awesome description with "<" and "&"
END:VEVENT
END:VCALENDAR
-"""
+""".encode("utf-8")
ORGANIZER = "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A"
ATTENDEE = "mailto:attendee at example.com"
@@ -391,63 +391,63 @@
# Update
(
- """BEGIN:VCALENDAR
+ u"""BEGIN:VCALENDAR
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
UID:CFDD5E46-4F74-478A-9311-B3FF905449C3
DTSTART:20100325T154500Z
DTEND:20100325T164500Z
-ATTENDEE;CN=The Attendee;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:
+ATTENDEE;CN=Th\xe9 Attendee;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:
mailto:attendee at example.com
-ATTENDEE;CN=The Organizer;CUTYPE=INDIVIDUAL;EMAIL=organizer at example.com;PAR
+ATTENDEE;CN=Th\xe9 Organizer;CUTYPE=INDIVIDUAL;EMAIL=organizer at example.com;PAR
TSTAT=ACCEPTED:urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A
-ORGANIZER;CN=The Organizer;EMAIL=organizer at example.com:urn:uuid:C3B38B00-41
+ORGANIZER;CN=Th\xe9 Organizer;EMAIL=organizer at example.com:urn:uuid:C3B38B00-41
66-11DD-B22C-A07C87E02F6A
-SUMMARY:testing outbound( ) *update*
+SUMMARY:t\xe9sting outbound( ) *update*
END:VEVENT
END:VCALENDAR
-""",
+""".encode("utf-8"),
"CFDD5E46-4F74-478A-9311-B3FF905449C3",
"urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A",
"mailto:attendee at example.com",
"update",
"organizer at example.com",
- "The Organizer",
+ u"Th\xe9 Organizer",
[
- (u'The Attendee', u'attendee at example.com'),
- (u'The Organizer', u'organizer at example.com')
+ (u'Th\xe9 Attendee', u'attendee at example.com'),
+ (u'Th\xe9 Organizer', u'organizer at example.com')
],
- "The Organizer <organizer at example.com>",
- "The Organizer <organizer at example.com>",
+ u"Th\xe9 Organizer <organizer at example.com>",
+ "=?utf-8?q?Th=C3=A9_Organizer_=3Corganizer=40example=2Ecom=3E?=",
"attendee at example.com",
),
# Reply
(
- """BEGIN:VCALENDAR
+ u"""BEGIN:VCALENDAR
VERSION:2.0
METHOD:REPLY
BEGIN:VEVENT
UID:DFDD5E46-4F74-478A-9311-B3FF905449C4
DTSTART:20100325T154500Z
DTEND:20100325T164500Z
-ATTENDEE;CN=The Attendee;CUTYPE=INDIVIDUAL;EMAIL=attendee at example.com;PARTST
+ATTENDEE;CN=Th\xe9 Attendee;CUTYPE=INDIVIDUAL;EMAIL=attendee at example.com;PARTST
AT=ACCEPTED:urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A
-ORGANIZER;CN=The Organizer;EMAIL=organizer at example.com:mailto:organizer at exam
+ORGANIZER;CN=Th\xe9 Organizer;EMAIL=organizer at example.com:mailto:organizer at exam
ple.com
-SUMMARY:testing outbound( ) *reply*
+SUMMARY:t\xe9sting outbound( ) *reply*
END:VEVENT
END:VCALENDAR
-""",
+""".encode("utf-8"),
None,
"urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A",
"mailto:organizer at example.com",
"reply",
"organizer at example.com",
- "The Organizer",
+ u"Th\xe9 Organizer",
[
- (u'The Attendee', u'attendee at example.com'),
+ (u'Th\xe9 Attendee', u'attendee at example.com'),
],
"attendee at example.com",
"attendee at example.com",
@@ -621,6 +621,59 @@
self.assertEquals(actualTypes, expectedTypes)
+ def test_generateEmail_noOrganizerCN(self):
+ """
+ L{MailHandler.generateEmail} generates a MIME-formatted email when
+ the organizer property has no CN parameter.
+ """
+ calendar = Component.fromString(initialInviteText)
+ _ignore_msgID, msgTxt = self.sender.generateEmail(
+ inviteState='new',
+ calendar=calendar,
+ orgEmail=u"user01 at localhost",
+ orgCN=None,
+ attendees=[(u"Us\xe9r One", "user01 at localhost"),
+ (u"User 2", "user02 at localhost")],
+ fromAddress="user01 at localhost",
+ replyToAddress="imip-system at localhost",
+ toAddress="user03 at localhost",
+ )
+ message = email.message_from_string(msgTxt)
+ self.assertTrue(message is not None)
+
+
+ def test_generateEmail_noAttendeeCN(self):
+ """
+ L{MailHandler.generateEmail} generates a MIME-formatted email when
+ the attendee property has no CN parameter.
+ """
+ calendar = Component.fromString(initialInviteText)
+ _ignore_msgID, msgTxt = self.sender.generateEmail(
+ inviteState='new',
+ calendar=calendar,
+ orgEmail=u"user01 at localhost",
+ orgCN=u"User Z\xe9ro One",
+ attendees=[(None, "user01 at localhost"),
+ (None, "user02 at localhost")],
+ fromAddress="user01 at localhost",
+ replyToAddress="imip-system at localhost",
+ toAddress="user03 at localhost",
+ )
+ message = email.message_from_string(msgTxt)
+ self.assertTrue(message is not None)
+
+
+ def test_messageID(self):
+ """
+ L{SMTPSender.betterMessageID} generates a Message-ID domain matching
+ the L{config.ServerHostName} value.
+ """
+ self.patch(config, "ServerHostName", "calendar.example.com")
+ msgID, message = self.generateSampleEmail()
+ self.assertEquals(message['Message-ID'], msgID)
+ self.assertEqual(msgID[:-1].split("@")[1], config.ServerHostName)
+
+
def test_alwaysIncludeTimezones(self):
"""
L{MailHandler.generateEmail} generates a MIME-formatted email with a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150714/505fbef3/attachment-0001.html>
More information about the calendarserver-changes
mailing list