[CalendarServer-changes] [8737] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Tue Feb 21 10:17:31 PST 2012


Revision: 8737
          http://trac.macosforge.org/projects/calendarserver/changeset/8737
Author:   sagen at apple.com
Date:     2012-02-21 10:17:28 -0800 (Tue, 21 Feb 2012)
Log Message:
-----------
Unify the CUA normalization lookup functions, and add Scheduling.Options.PrincipalHostAliases which is CUA hostnames are validated against.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/principal.py
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/resource.py
    CalendarServer/trunk/twistedcaldav/scheduling/ischedule.py
    CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py
    CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
    CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
    CalendarServer/trunk/twistedcaldav/upgrade.py
    CalendarServer/trunk/twistedcaldav/util.py

Modified: CalendarServer/trunk/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/principal.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/directory/principal.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -288,7 +288,8 @@
             else:
                 port = int(netloc[1])
 
-            if host != config.ServerHostName:
+            if (host != config.ServerHostName and
+                host not in config.Scheduling.Options.PrincipalHostAliases):
                 return None
 
             if port != {

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -2509,7 +2509,8 @@
                     if dataValue.find(dropboxPrefix) != -1:
                         self.removeProperty(attachment)
 
-    def normalizeCalendarUserAddresses(self, lookupFunction, toUUID=True):
+    def normalizeCalendarUserAddresses(self, lookupFunction, principalFunction,
+        toUUID=True):
         """
         Do the ORGANIZER/ATTENDEE property normalization.
 
@@ -2527,7 +2528,8 @@
                 # Check that we can lookup this calendar user address - if not
                 # we cannot do anything with it
                 cuaddr = normalizeCUAddr(prop.value())
-                name, guid, cuaddrs = lookupFunction(cuaddr)
+                name, guid, cuaddrs = lookupFunction(cuaddr, principalFunction,
+                    config)
                 if guid is None:
                     continue
 

Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/resource.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -79,6 +79,7 @@
     getPubSubAPSConfiguration,
 )
 from twistedcaldav.sharing import SharedCollectionMixin, SharedHomeMixin
+from twistedcaldav.util import normalizationLookup
 from twistedcaldav.vcard import Component as vComponent
 
 from txdav.common.icommondatastore import InternalDataStoreError, \
@@ -1188,19 +1189,10 @@
         @param ical: calendar object to normalize.
         @type ical: L{Component}
         """
+        ical.normalizeCalendarUserAddresses(normalizationLookup,
+            self.principalForCalendarUserAddress)
 
-        def lookupFunction(cuaddr):
-            principal = self.principalForCalendarUserAddress(cuaddr)
-            if principal is None:
-                return (None, None, None)
-            else:
-                return (principal.record.fullName,
-                    principal.record.guid,
-                    principal.record.calendarUserAddresses)
 
-        ical.normalizeCalendarUserAddresses(lookupFunction)
-
-
     def principalForCalendarUserAddress(self, address):
         for principalCollection in self.principalCollections():
             principal = principalCollection.principalForCalendarUserAddress(address)

Modified: CalendarServer/trunk/twistedcaldav/scheduling/ischedule.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/ischedule.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/scheduling/ischedule.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -41,7 +41,7 @@
 from twistedcaldav.scheduling.ischeduleservers import IScheduleServers
 from twistedcaldav.scheduling.ischeduleservers import IScheduleServerRecord
 from twistedcaldav.scheduling.itip import iTIPRequestStatus
-from twistedcaldav.util import utf8String
+from twistedcaldav.util import utf8String, normalizationLookup
 from twistedcaldav.scheduling.cuaddress import PartitionedCalendarUser, RemoteCalendarUser,\
     OtherServerCalendarUser
 
@@ -304,26 +304,11 @@
 
     def _prepareData(self):
         if self.server.unNormalizeAddresses and self.scheduler.method == "PUT": 
-            def lookupFunction(cuaddr):
-                principal = self.scheduler.resource.principalForCalendarUserAddress(cuaddr)
-                if principal is None:
-                    return (None, None, None)
-                else:
-                    # TODO: remove V1Compatibility when V1 migration is complete
-                    if config.Scheduling.Options.V1Compatibility:
-                        # Allow /principals-form CUA
-                        return (principal.record.fullName.decode("utf-8"),
-                            principal.record.guid,
-                            principal.calendarUserAddresses()
-                        )
-                    else:
-                        return (principal.record.fullName.decode("utf-8"),
-                            principal.record.guid,
-                            principal.record.calendarUserAddresses
-                        )
-
             normalizedCalendar = self.scheduler.calendar.duplicate()
-            normalizedCalendar.normalizeCalendarUserAddresses(lookupFunction, toUUID=False)
+            normalizedCalendar.normalizeCalendarUserAddresses(
+                normalizationLookup,
+                self.scheduler.resource.principalForCalendarUserAddresses,
+                toUUID=False)
         else:
             normalizedCalendar = self.scheduler.calendar
         self.data = str(normalizedCalendar)

Modified: CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -51,6 +51,7 @@
 from twistedcaldav.scheduling.ischeduleservers import IScheduleServers
 from twistedcaldav.scheduling.itip import iTIPRequestStatus
 from twistedcaldav.servers import Servers
+from twistedcaldav.util import normalizationLookup
 
 """
 CalDAV/Server-to-Server scheduling behavior.
@@ -847,26 +848,9 @@
         """
 
         if not self.checkForFreeBusy():
-            def lookupFunction(cuaddr):
-                principal = self.resource.principalForCalendarUserAddress(cuaddr)
-                if principal is None:
-                    return (None, None, None)
-                else:
-                    # TODO: remove V1Compatibility when V1 migration is complete
-                    if config.Scheduling.Options.V1Compatibility:
-                        # Allow /principals-form CUA
-                        return (principal.record.fullName.decode("utf-8"),
-                            principal.record.guid,
-                            principal.calendarUserAddresses()
-                        )
-                    else:
-                        return (principal.record.fullName.decode("utf-8"),
-                            principal.record.guid,
-                            principal.record.calendarUserAddresses
-                        )
+            self.calendar.normalizeCalendarUserAddresses(normalizationLookup,
+                self.resource.principalForCalendarUserAddress)
 
-            self.calendar.normalizeCalendarUserAddresses(lookupFunction)
-
     def checkAuthorization(self):
         # Must have an unauthenticated user
         if self.resource.currentPrincipal(self.request) != davxml.Principal(davxml.Unauthenticated()):

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -645,6 +645,7 @@
             "UIDLockTimeoutSeconds"               :  60,    # Time for implicit UID lock timeout
             "UIDLockExpirySeconds"                : 300,    # Expiration time for UID lock,
             "V1Compatibility"                     : False,  # Allow /path-based CUAs in scheduling replies
+            "PrincipalHostAliases"                : [],     # Hostnames matched in http(s) CUAs
             
             "AutoSchedule" : {
                 "Enabled"                         : True,   # Auto-scheduling will never occur if set to False

Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -6000,7 +6000,7 @@
 
         component = Component.fromString(data)
 
-        def lookupFunction(cuaddr):
+        def lookupFunction(cuaddr, ignored1, ignored2):
             return {
                 "urn:uuid:foo" : (
                     "Foo",
@@ -6024,7 +6024,7 @@
                 ),
             }[cuaddr]
 
-        component.normalizeCalendarUserAddresses(lookupFunction, toUUID=False)
+        component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=False)
 
         self.assertEquals("mailto:bar at example.com",
             component.getAttendeeProperty(("mailto:bar at example.com",)).value())
@@ -6057,7 +6057,7 @@
 
         component = Component.fromString(data)
 
-        def lookupFunction(cuaddr):
+        def lookupFunction(cuaddr, ignored1, ignored2):
             return {
                 "/principals/users/foo" : (
                     "Foo",
@@ -6071,7 +6071,7 @@
                 ),
             }[cuaddr]
 
-        component.normalizeCalendarUserAddresses(lookupFunction, toUUID=True)
+        component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=True)
 
         # /principal CUAs are not stored in CALENDARSERVER-OLD-CUA
         prop = component.getAttendeeProperty(("urn:uuid:foo",))

Modified: CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_upgrade.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/test/test_upgrade.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -1482,13 +1482,7 @@
         # would have been 8 times without the cuaCache.
         self.assertEquals(directory.count, 3)
 
-        # Ensure normalization ignores the non-path part of http(s) CUAs
-        newData, changed = normalizeCUAddrs(normalizeEventWithHTTP, directory, cuaCache)
-        self.assertTrue("urn:uuid:123" in newData)
-        self.assertTrue("urn:uuid:234" in newData)
-        self.assertFalse("http" in newData)
 
-
 normalizeEvent = """BEGIN:VCALENDAR
 VERSION:2.0
 BEGIN:VEVENT
@@ -1506,24 +1500,7 @@
 END:VCALENDAR
 """.replace("\n", "\r\n")
 
-normalizeEventWithHTTP = """BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-TRANSP:OPAQUE
-UID:1E238CA1-3C95-4468-B8CD-C8A399F78C71
-DTSTART:20090203
-DTEND:20090204
-ORGANIZER;CN="User A":http://example.com/principals/users/a/
-SUMMARY:New Event
-DESCRIPTION:Foo
-ATTENDEE;CN="User A";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:http://example.com/principals/users/a/
-ATTENDEE;CN="User B";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:http://example.com/principals/users/b/
-END:VEVENT
-END:VCALENDAR
-""".replace("\n", "\r\n")
 
-
-
 event01_before = """BEGIN:VCALENDAR
 VERSION:2.0
 PRODID:-//Apple Inc.//iCal 3.0//EN

Modified: CalendarServer/trunk/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/upgrade.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/upgrade.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -20,7 +20,6 @@
 import xattr, os, zlib, hashlib, datetime, pwd, grp, shutil, errno, operator
 from zlib import compress
 from cPickle import loads as unpickle, UnpicklingError
-from urlparse import urlsplit
 
 from twext.python.log import Logger
 from twext.web2.dav import davxml
@@ -38,6 +37,7 @@
 from twistedcaldav.mail import MailGatewayTokensDatabase
 from twistedcaldav.scheduling.cuaddress import LocalCalendarUser
 from twistedcaldav.scheduling.scheduler import DirectScheduler
+from twistedcaldav.util import normalizationLookup
 
 from twisted.application.service import Service
 from twisted.internet import reactor
@@ -588,42 +588,20 @@
     """
     cal = Component.fromString(data)
 
-    def lookupFunction(cuaddr):
+    def lookupFunction(cuaddr, principalFunction, config):
 
-        # If cuaddr is http(s), examine only the path portion, ignoring the
-        # hostname and port
-        if cuaddr.startswith("http"):
-            cuaddr = urlsplit(cuaddr)[2]
-
         # Return cached results, if any.
         if cuaCache.has_key(cuaddr):
             return cuaCache[cuaddr]
 
-        try:
-            principal = directory.principalForCalendarUserAddress(cuaddr)
-        except Exception, e:
-            log.debug("Lookup of %s failed: %s" % (cuaddr, e))
-            principal = None
+        result = normalizationLookup(cuaddr, principalFunction, config)
 
-        if principal is None:
-            result = (None, None, None)
-        else:
-            rec = principal.record
-
-            # RFC5545 syntax does not allow backslash escaping in
-            # parameter values. A double-quote is thus not allowed
-            # in a parameter value except as the start/end delimiters.
-            # Single quotes are allowed, so we convert any double-quotes
-            # to single-quotes.
-            fullName = rec.fullName.replace('"', "'")
-
-            result = (fullName, rec.guid, rec.calendarUserAddresses)
-
         # Cache the result
         cuaCache[cuaddr] = result
         return result
 
-    cal.normalizeCalendarUserAddresses(lookupFunction)
+    cal.normalizeCalendarUserAddresses(lookupFunction,
+        directory.principalForCalendarUserAddress)
 
     newData = str(cal)
     return newData, not newData == data

Modified: CalendarServer/trunk/twistedcaldav/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/util.py	2012-02-21 17:46:18 UTC (rev 8736)
+++ CalendarServer/trunk/twistedcaldav/util.py	2012-02-21 18:17:28 UTC (rev 8737)
@@ -25,8 +25,10 @@
 from twisted.internet import ssl, reactor
 from twisted.web import client
 from twisted.python import failure
-from twext.python.log import LoggingMixIn
+from twext.python.log import LoggingMixIn, Logger
 
+log = Logger()
+
 ##
 # System Resources (Memory size and processor count)
 ##
@@ -428,3 +430,38 @@
             self.factory.deferred.errback(failure.Failure(Unauthorized("Mail gateway not able to process reply; calendar server returned 401 and doesn't support basic or digest")))
             return self.factory.deferred
 
+
+
+def normalizationLookup(cuaddr, principalFunction, config):
+    """
+    Lookup function to be passed to ical.normalizeCalendarUserAddresses.
+    Returns a tuple of (Full name, guid, and calendar user address list)
+    for the given cuaddr.  The principalFunction is called to retrieve the
+    principal for the cuaddr.
+    """
+    try:
+        principal = principalFunction(cuaddr)
+    except Exception, e:
+        log.debug("Lookup of %s failed: %s" % (cuaddr, e))
+        principal = None
+
+    if principal is None:
+        return (None, None, None)
+    else:
+        rec = principal.record
+
+        # RFC5545 syntax does not allow backslash escaping in
+        # parameter values. A double-quote is thus not allowed
+        # in a parameter value except as the start/end delimiters.
+        # Single quotes are allowed, so we convert any double-quotes
+        # to single-quotes.
+        fullName = rec.fullName.decode("utf-8").replace('"', "'")
+
+        # TODO: remove V1Compatibility when V1 migration is complete
+        if config.Scheduling.Options.V1Compatibility:
+            # Allow /principals-form CUA
+            cuas = principal.calendarUserAddresses()
+        else:
+            cuas = principal.record.calendarUserAddresses
+
+        return (fullName, rec.guid, cuas)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120221/df471d2c/attachment-0001.html>


More information about the calendarserver-changes mailing list