[CalendarServer-changes] [8274] CalendarServer/trunk/twistedcaldav/directory

source_changes at macosforge.org source_changes at macosforge.org
Thu Nov 10 16:44:53 PST 2011


Revision: 8274
          http://trac.macosforge.org/projects/calendarserver/changeset/8274
Author:   sagen at apple.com
Date:     2011-11-10 16:44:52 -0800 (Thu, 10 Nov 2011)
Log Message:
-----------
Handle variable whitespace in DNs by normalizing them as soon as we retrieve them from LDAP.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/directory.py
    CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2011-11-10 20:47:08 UTC (rev 8273)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2011-11-11 00:44:52 UTC (rev 8274)
@@ -637,10 +637,13 @@
             self.log_info("Applying proxy assignment changes")
             assignmentCount = 0
             for principalUID, members in assignments:
-                current = (yield self.proxyDB.getMembers(principalUID))
-                if members != current:
-                    assignmentCount += 1
-                    yield self.proxyDB.setGroupMembers(principalUID, members)
+                try:
+                    current = (yield self.proxyDB.getMembers(principalUID))
+                    if members != current:
+                        assignmentCount += 1
+                        yield self.proxyDB.setGroupMembers(principalUID, members)
+                except Exception, e:
+                    self.log_error("Unable to apply proxy assignment: principal=%s, members=%s, error=%s" % (principalUID, members, e))
             self.log_info("Applied %d assignment%s to proxy database" %
                 (assignmentCount, "" if assignmentCount == 1 else "s"))
 

Modified: CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-11-10 20:47:08 UTC (rev 8273)
+++ CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-11-11 00:44:52 UTC (rev 8274)
@@ -314,6 +314,7 @@
         numMissingGuids = 0
         guidAttr = self.rdnSchema["guidAttr"]
         for dn, attrs in results:
+            dn = normalizeDNstr(dn)
 
             unrestricted = True
             if self.restrictedGUIDs is not None:
@@ -370,6 +371,7 @@
             ldap.SCOPE_SUBTREE, filterstr=filterstr, attrlist=attrlist)
 
         for dn, attrs in results:
+            dn = normalizeDNstr(dn)
             guid = self._getUniqueLdapAttribute(attrs, guidAttr)
             if guid:
                 readDelegate = self._getUniqueLdapAttribute(attrs, readAttr)
@@ -508,12 +510,13 @@
 
                 if len(result) == 1:
                     dn, attrs = result[0]
+                    dn = normalizeDNstr(dn)
                     if self.groupSchema["membersAttr"]:
-                        members = self._getMultipleLdapAttributes(attrs,
-                            self.groupSchema["membersAttr"])
+                        members = set(self._getMultipleLdapAttributes(attrs,
+                            self.groupSchema["membersAttr"]))
                     if self.groupSchema["nestedGroupsAttr"]:
-                        nestedGroups = self._getMultipleLdapAttributes(attrs,
-                            self.groupSchema["nestedGroupsAttr"])
+                        nestedGroups = set(self._getMultipleLdapAttributes(attrs,
+                            self.groupSchema["nestedGroupsAttr"]))
 
                 else:
                     members = []
@@ -563,15 +566,16 @@
 
             if len(result) == 1:
                 dn, attrs = result[0]
+                dn = normalizeDNstr(dn)
                 if self.groupSchema["membersAttr"]:
-                    subMembers = self._getMultipleLdapAttributes(attrs,
-                        self.groupSchema["membersAttr"])
+                    subMembers = set(self._getMultipleLdapAttributes(attrs,
+                        self.groupSchema["membersAttr"]))
                 else:
                     subMembers = []
 
                 if self.groupSchema["nestedGroupsAttr"]:
-                    subNestedGroups = self._getMultipleLdapAttributes(attrs,
-                        self.groupSchema["nestedGroupsAttr"])
+                    subNestedGroups = set(self._getMultipleLdapAttributes(attrs,
+                        self.groupSchema["nestedGroupsAttr"]))
                 else:
                     subNestedGroups = []
 
@@ -605,7 +609,7 @@
             values = attrs.get(key)
             if values is not None:
                 results += values
-        return set(results)
+        return results
 
 
     def _ldapResultToRecord(self, dn, attrs, recordType):
@@ -640,7 +644,7 @@
                 raise MissingGuidException()
 
         # Find or build email
-        emailAddresses = self._getMultipleLdapAttributes(attrs, self.rdnSchema[recordType]["mapping"]["emailAddresses"])
+        emailAddresses = set(self._getMultipleLdapAttributes(attrs, self.rdnSchema[recordType]["mapping"]["emailAddresses"]))
         emailSuffix = self.rdnSchema[recordType]["emailSuffix"]
 
         if len(emailAddresses) == 0 and emailSuffix:
@@ -651,7 +655,7 @@
         proxyGUIDs = ()
         readOnlyProxyGUIDs = ()
         autoSchedule = False
-        memberGUIDs = set()
+        memberGUIDs = []
 
         # LDAP attribute -> principal matchings
         if recordType == self.recordType_users:
@@ -669,18 +673,16 @@
 
             if self.groupSchema["membersAttr"]:
                 members = self._getMultipleLdapAttributes(attrs, self.groupSchema["membersAttr"])
-                if members:
-                    if type(members) is str:
-                        members = set([members])
-                    memberGUIDs.update(members)
+                memberGUIDs.extend(members)
             if self.groupSchema["nestedGroupsAttr"]:
                 members = self._getMultipleLdapAttributes(attrs, self.groupSchema["nestedGroupsAttr"])
-                if members:
-                    if type(members) is str:
-                        members = set([members])
-                    memberGUIDs.update(members)
+                memberGUIDs.extend(members)
 
+            # Normalize members if they're in DN form
+            if not self.groupSchema["memberIdAttr"]: # empty = dn
+                memberGUIDs = [normalizeDNstr(dnStr) for dnStr in list(memberGUIDs)]
 
+
         elif recordType in (self.recordType_resources,
             self.recordType_locations):
             fullName = self._getUniqueLdapAttribute(attrs, self.rdnSchema[recordType]["mapping"]["fullName"])
@@ -715,11 +717,11 @@
                     autoSchedule = (autoScheduleValue ==
                         self.resourceSchema["autoScheduleEnabledValue"])
                 if self.resourceSchema["proxyAttr"]:
-                    proxyGUIDs = self._getMultipleLdapAttributes(attrs,
-                        self.resourceSchema["proxyAttr"])
+                    proxyGUIDs = set(self._getMultipleLdapAttributes(attrs,
+                        self.resourceSchema["proxyAttr"]))
                 if self.resourceSchema["readOnlyProxyAttr"]:
-                    readOnlyProxyGUIDs = self._getMultipleLdapAttributes(attrs,
-                        self.resourceSchema["readOnlyProxyAttr"])
+                    readOnlyProxyGUIDs = set(self._getMultipleLdapAttributes(attrs,
+                        self.resourceSchema["readOnlyProxyAttr"]))
 
         serverID = partitionID = None
         if self.partitionSchema["serverIdAttr"]:
@@ -854,6 +856,7 @@
 
             if result:
                 dn, attrs = result.pop()
+                dn = normalizeDNstr(dn)
 
                 unrestricted = True
                 if self.restrictedGUIDs is not None:
@@ -934,6 +937,7 @@
                 self.log_debug("LDAP search returned %d results" % (len(results),))
                 numMissingGuids = 0
                 for dn, attrs in results:
+                    dn = normalizeDNstr(dn)
                     # Skip if group restriction is in place and guid is not
                     # a member
                     if (recordType != self.recordType_groups and
@@ -985,6 +989,7 @@
         attributeToSearch = "guid"
         valuesToFetch = guids
 
+
         while valuesToFetch:
             results = []
 
@@ -1013,10 +1018,10 @@
                 if alias not in recordsByAlias:
                     recordsByAlias[alias] = record
 
-                # record._memberIds contains the members of this group,
+                # record.memberGUIDs() contains the members of this group,
                 # but it might not be in guid form; it will be data from
                 # self.groupSchema["memberIdAttr"]
-                for memberAlias in record._memberIds:
+                for memberAlias in record.memberGUIDs():
                     if not memberIdAttr:
                         # Members are identified by dn so we can take a short
                         # cut:  we know we only need to examine groups, and
@@ -1056,6 +1061,16 @@
     return child[-len(parent):] == parent
 
 
+def normalizeDNstr(dnStr):
+    """
+    Convert to lowercase and remove extra whitespace
+    @param dnStr: dn
+    @type dnStr: C{str}
+    @return: normalized dn C{str}
+    """
+    return ldap.dn.dn2str(ldap.dn.str2dn(dnStr.lower()))
+
+
 def buildFilter(mapping, fields, operand="or"):
     """
     Create an LDAP filter string from a list of tuples representing directory
@@ -1138,22 +1153,13 @@
         # Store copy of member guids
         self._memberGUIDs = memberGUIDs
 
-        # Identifiers of the members of this record if it is a group
-        membersAttrs = []
-        if self.service.groupSchema["membersAttr"]:
-            membersAttrs.append(self.service.groupSchema["membersAttr"])
-        if self.service.groupSchema["nestedGroupsAttr"]:
-            membersAttrs.append(self.service.groupSchema["nestedGroupsAttr"])
-        self._memberIds = self.service._getMultipleLdapAttributes(attrs,
-            *membersAttrs)
-
         # Identifier of this record as a group member
         memberIdAttr = self.service.groupSchema["memberIdAttr"]
         if memberIdAttr:
             self._memberId = self.service._getUniqueLdapAttribute(attrs,
                 memberIdAttr)
         else:
-            self._memberId = self.dn
+            self._memberId = normalizeDNstr(self.dn)
 
 
     def members(self):
@@ -1171,7 +1177,7 @@
         memberIdAttr = self.service.groupSchema["memberIdAttr"]
         results = []
 
-        for memberId in self._memberIds:
+        for memberId in self._memberGUIDs:
 
             if memberIdAttr:
 
@@ -1194,6 +1200,7 @@
             if result:
 
                 dn, attrs = result.pop()
+                dn = normalizeDNstr(dn)
                 self.log_debug("Retrieved: %s %s" % (dn,attrs))
                 recordType = self.service.recordTypeForDN(dn)
                 if recordType is None:
@@ -1245,6 +1252,7 @@
                 ldap.SCOPE_SUBTREE, filterstr=filterstr, attrlist=self.service.attrlist)
 
             for dn, attrs in results:
+                dn = normalizeDNstr(dn)
                 shortName = self.service._getUniqueLdapAttribute(attrs, "cn")
                 self.log_debug("%s is a member of %s" % (self._memberId, shortName))
                 groups.append(self.service.recordWithShortName(recordType,

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py	2011-11-10 20:47:08 UTC (rev 8273)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py	2011-11-11 00:44:52 UTC (rev 8274)
@@ -17,13 +17,14 @@
 try:
     from twistedcaldav.directory.ldapdirectory import (
         buildFilter, LdapDirectoryService, MissingGuidException,
-        splitIntoBatches
+        splitIntoBatches, normalizeDNstr, dnContainedIn
     )
     from twistedcaldav.test.util import proxiesFile
     from twistedcaldav.directory.calendaruserproxyloader import XMLCalendarUserProxyLoader
     from twistedcaldav.directory import calendaruserproxy
     from twistedcaldav.directory.directory import GroupMembershipCache, GroupMembershipCacheUpdater
     from twisted.internet.defer import inlineCallbacks
+    from string import maketrans
     import ldap
 except ImportError:
     print "Skipping because ldap module not installed"
@@ -113,16 +114,150 @@
 
         def __init__(self, actual):
             self.actual = actual
-            self.testResults = []
 
-        def addTestResults(self, results):
-            self.testResults.insert(0, results)
+            # Test data returned from search_s.
+            # Note that some DNs have various extra whitespace added and mixed
+            # up case since LDAP is pretty loose about these.
+            self.records = (
+                (
+                    "cn=Recursive1_coasts, cn=gROUps,dc=example, dc=com",
+                    {
+                        'cn': ['recursive1_coasts'],
+                        'apple-generateduid': ['recursive1_coasts'],
+                        'uniqueMember': [
+                            'cn=recursive2_coasts,cn=groups,dc=example,dc=com',
+                            'uid=wsanchez ,cn=users, dc=eXAMple,dc=com',
+                        ],
+                    }
+                ),
+                (
+                    "cn=recursive2_coasts,cn=groups,dc=example,dc=com",
+                    {
+                        'cn': ['recursive2_coasts'],
+                        'apple-generateduid': ['recursive2_coasts'],
+                        'uniqueMember': [
+                            'cn=recursive1_coasts,cn=groups,dc=example,dc=com',
+                            'uid=cdaboo,cn=users,dc=example,dc=com',
+                        ],
+                    }
+                ),
+                (
+                    'cn=both_coasts,cn=groups,dc=example,dc=com',
+                    {
+                        'cn': ['both_coasts'],
+                        'apple-generateduid': ['both_coasts'],
+                        'uniqueMember': [
+                            'cn=right_coast,cn=groups,dc=example,dc=com',
+                            'cn=left_coast,cn=groups,dc=example,dc=com',
+                        ],
+                    }
+                ),
+                (
+                    'cn=right_coast,cn=groups,dc=example,dc=com',
+                    {
+                        'cn': ['right_coast'],
+                        'apple-generateduid': ['right_coast'],
+                        'uniqueMember': [
+                            'uid=cdaboo,cn=users,dc=example,dc=com',
+                        ],
+                    }
+                ),
+                (
+                    'cn=left_coast,cn=groups,dc=example,dc=com',
+                    {
+                        'cn': ['left_coast'],
+                        'apple-generateduid': ['left_coast'],
+                        'uniqueMember': [
+                            'uid=wsanchez, cn=users,dc=example,dc=com',
+                            'uid=lecroy,cn=users,dc=example,dc=com',
+                            'uid=dreid,cn=users,dc=example,dc=com',
+                        ],
+                    }
+                ),
+                (
+                    "uid=odtestamanda,cn=users,dc=example,dc=com",
+                    {
+                        'uid': ['odtestamanda'],
+                        'apple-generateduid': ['9DC04A70-E6DD-11DF-9492-0800200C9A66'],
+                        'sn': ['Test'],
+                        'mail': ['odtestamanda at example.com', 'alternate at example.com'],
+                        'givenName': ['Amanda'],
+                        'cn': ['Amanda Test']
+                    }
+                ),
+                (
+                    "uid=odtestbetty,cn=users,dc=example,dc=com",
+                    {
+                        'uid': ['odtestbetty'],
+                        'apple-generateduid': ['93A8F5C5-49D8-4641-840F-CD1903B0394C'],
+                        'sn': ['Test'],
+                        'mail': ['odtestbetty at example.com'],
+                        'givenName': ['Betty'],
+                        'cn': ['Betty Test']
+                    }
+                ),
+                (
+                    "uid=odtestcarlene,cn=users,dc=example,dc=com",
+                    {
+                        'uid': ['odtestcarlene'],
+                        # Note: no guid here, to test this record is skipped
+                        'sn': ['Test'],
+                        'mail': ['odtestcarlene at example.com'],
+                        'givenName': ['Carlene'],
+                        'cn': ['Carlene Test']
+                    }
+                ),
+                (
+                    "uid=cdaboo,cn=users,dc=example,dc=com",
+                    {
+                        'uid': ['cdaboo'],
+                        'apple-generateduid': ['5A985493-EE2C-4665-94CF-4DFEA3A89500'],
+                        'sn': ['Daboo'],
+                        'mail': ['daboo at example.com'],
+                        'givenName': ['Cyrus'],
+                        'cn': ['Cyrus Daboo']
+                    }
+                ),
+                (
+                    "uid=wsanchez  ,  cn=users  , dc=example,dc=com",
+                    {
+                        'uid': ['wsanchez'],
+                        'apple-generateduid': ['6423F94A-6B76-4A3A-815B-D52CFD77935D'],
+                        'sn': ['Sanchez'],
+                        'mail': ['wsanchez at example.com'],
+                        'givenName': ['Wilfredo'],
+                        'cn': ['Wilfredo Sanchez']
+                    }
+                ),
+            )
 
         def search_s(self, base, scope, filterstr="(objectClass=*)",
             attrlist=None):
-            return self.testResults.pop()
+            """ A simple implementation of LDAP search filter processing """
 
+            base = normalizeDNstr(base)
+            results = []
+            for dn, attrs in self.records:
+                dn = normalizeDNstr(dn)
+                if dn == base:
+                    results.append((dn, attrs))
+                elif dnContainedIn(ldap.dn.str2dn(dn), ldap.dn.str2dn(base)):
+                    if filterstr in ("(objectClass=*)", "(!(objectClass=organizationalUnit))"):
+                        results.append((dn, attrs))
+                    else:
+                        trans = maketrans("&(|)", "   |")
+                        fragments = filterstr.encode("utf-8").translate(trans).split("|")
+                        for fragment in fragments:
+                            if not fragment:
+                                continue
+                            fragment = fragment.strip()
+                            key, value = fragment.split("=")
+                            if value in attrs.get(key, []):
+                                results.append((dn, attrs))
 
+            return results
+
+
     class LdapDirectoryServiceTestCase(TestCase):
 
         def setUp(self):
@@ -156,7 +291,7 @@
                         "rdn": "cn=Users",
                         "attr": "uid", # used only to synthesize email address
                         "emailSuffix": None, # used only to synthesize email address
-                        "filter": "(objectClass=apple-user)", # additional filter for this type
+                        "filter": "", # additional filter for this type
                         "loginEnabledAttr" : "", # attribute controlling login
                         "loginEnabledValue" : "yes", # "True" value of above attribute
                         "calendarEnabledAttr" : "enable-calendar", # attribute controlling calendaring
@@ -173,7 +308,7 @@
                         "rdn": "cn=Groups",
                         "attr": "cn", # used only to synthesize email address
                         "emailSuffix": None, # used only to synthesize email address
-                        "filter": "(objectClass=apple-group)", # additional filter for this type
+                        "filter": "", # additional filter for this type
                         "mapping": { # maps internal record names to LDAP
                             "recordName": "cn",
                             "fullName" : "cn",
@@ -234,6 +369,20 @@
             self.service.ldap = LdapDirectoryTestWrapper(self.service.ldap)
 
 
+        def test_ldapWrapper(self):
+            """
+            Exercise the fake search_s implementation
+            """
+            # Get all groups
+            self.assertEquals(
+                len(self.service.ldap.search_s("cn=groups,dc=example,dc=com", 0, "(objectClass=*)", [])), 5)
+
+            self.assertEquals(
+                len(self.service.ldap.search_s("cn=recursive1_coasts,cn=groups,dc=example,dc=com", 2, "(objectClass=*)", [])), 1)
+
+            self.assertEquals(
+                len(self.service.ldap.search_s("cn=groups,dc=example,dc=com", 0, "(|(apple-generateduid=right_coast)(apple-generateduid=left_coast))", [])), 2)
+
         def test_ldapRecordCreation(self):
             """
             Exercise _ldapResultToRecord(), which converts a dictionary
@@ -321,9 +470,9 @@
                 'apple-generateduid': [guid],
                 'uniqueMember':
                     [
-                        '9DC04A70-E6DD-11DF-9492-0800200C9A66',
-                        '9DC04A71-E6DD-11DF-9492-0800200C9A66',
-                        '6C6CD282-E6E3-11DF-9492-0800200C9A66'
+                        'uid=odtestamanda,cn=users,dc=example,dc=com',
+                        'uid=odtestbetty,cn=users,dc=example,dc=com',
+                        'cn=odtestgroupb,cn=groups,dc=example,dc=com',
                     ],
                 'cn': ['odtestgrouptop']
             }
@@ -331,9 +480,11 @@
                 self.service.recordType_groups)
             self.assertEquals(record.guid, guid)
             self.assertEquals(record.memberGUIDs(),
-                set(['6C6CD282-E6E3-11DF-9492-0800200C9A66',
-                     '9DC04A70-E6DD-11DF-9492-0800200C9A66',
-                     '9DC04A71-E6DD-11DF-9492-0800200C9A66'])
+                set([
+                     'cn=odtestgroupb,cn=groups,dc=example,dc=com',
+                     'uid=odtestamanda,cn=users,dc=example,dc=com',
+                     'uid=odtestbetty,cn=users,dc=example,dc=com',
+                     ])
             )
 
             # Resource with delegates and autoSchedule = True
@@ -433,46 +584,11 @@
             and turns the results into records
             """
 
-            self.service.ldap.addTestResults([
-                (
-                    "uid=odtestamanda,cn=users,dc=example,dc=com",
-                    {
-                        'uid': ['odtestamanda'],
-                        'apple-generateduid': ['9DC04A70-E6DD-11DF-9492-0800200C9A66'],
-                        'sn': ['Test'],
-                        'mail': ['odtestamanda at example.com', 'alternate at example.com'],
-                        'givenName': ['Amanda'],
-                        'cn': ['Amanda Test']
-                    }
-                ),
-                (
-                    "uid=odtestbetty,cn=users,dc=example,dc=com",
-                    {
-                        'uid': ['odtestbetty'],
-                        'apple-generateduid': ['93A8F5C5-49D8-4641-840F-CD1903B0394C'],
-                        'sn': ['Test'],
-                        'mail': ['odtestbetty at example.com'],
-                        'givenName': ['Betty'],
-                        'cn': ['Betty Test']
-                    }
-                ),
-                (
-                    "uid=odtestcarlene,cn=users,dc=example,dc=com",
-                    {
-                        'uid': ['odtestcarlene'],
-                        # Note: no guid here, to test this record is skipped
-                        'sn': ['Test'],
-                        'mail': ['odtestcarlene at example.com'],
-                        'givenName': ['Carlene'],
-                        'cn': ['Carlene Test']
-                    }
-                ),
-            ])
             records = self.service.listRecords(self.service.recordType_users)
-            self.assertEquals(len(records), 2)
+            self.assertEquals(len(records), 4)
             self.assertEquals(
                 set([r.firstName for r in records]),
-                set(["Amanda", "Betty"]) # Carlene is skipped because no guid in LDAP
+                set(["Amanda", "Betty", "Cyrus", "Wilfredo"]) # Carlene is skipped because no guid in LDAP
             )
 
         @inlineCallbacks
@@ -496,106 +612,6 @@
             updater = GroupMembershipCacheUpdater(calendaruserproxy.ProxyDBService,
                 self.service, 30, 15, cache=cache, useExternalProxies=False)
 
-            # Fake LDAP results for the getGroups() call performed within
-            # updateCache().  Also include recursive groups to make sure we
-            # handle that situation.
-            self.service.ldap.addTestResults([
-                (
-                    "cn=recursive1_coasts,cn=groups,dc=example,dc=com",
-                    {
-                        'cn': ['recursive1_coasts'],
-                        'apple-generateduid': ['recursive1_coasts'],
-                        'uniqueMember': [
-                            'cn=recursive2_coasts,cn=groups,dc=example,dc=com',
-                            'uid=wsanchez,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-                (
-                    "cn=recursive2_coasts,cn=groups,dc=example,dc=com",
-                    {
-                        'cn': ['recursive2_coasts'],
-                        'apple-generateduid': ['recursive2_coasts'],
-                        'uniqueMember': [
-                            'cn=recursive1_coasts,cn=groups,dc=example,dc=com',
-                            'uid=cdaboo,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-                (
-                    'cn=both_coasts,cn=groups,dc=example,dc=com',
-                    {
-                        'cn': ['both_coasts'],
-                        'apple-generateduid': ['both_coasts'],
-                        'uniqueMember': [
-                            'cn=right_coast,cn=groups,dc=example,dc=com',
-                            'cn=left_coast,cn=groups,dc=example,dc=com',
-                        ],
-                    }
-                ),
-                (
-                    'cn=right_coast,cn=groups,dc=example,dc=com',
-                    {
-                        'cn': ['right_coast'],
-                        'apple-generateduid': ['right_coast'],
-                        'uniqueMember': [
-                            'uid=cdaboo,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-                (
-                    'cn=left_coast,cn=groups,dc=example,dc=com',
-                    {
-                        'cn': ['left_coast'],
-                        'apple-generateduid': ['left_coast'],
-                        'uniqueMember': [
-                            'uid=wsanchez,cn=users,dc=example,dc=com',
-                            'uid=lecroy,cn=users,dc=example,dc=com',
-                            'uid=dreid,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-            ])
-            self.service.ldap.addTestResults([
-                (
-                    "cn=recursive2_coasts,cn=groups,dc=example,dc=com",
-                    {
-                        'cn': ['recursive2_coasts'],
-                        'apple-generateduid': ['recursive2_coasts'],
-                        'uniqueMember': [
-                            'cn=recursive1_coasts,cn=groups,dc=example,dc=com',
-                            'uid=cdaboo,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-            ])
-            self.service.ldap.addTestResults([
-                (
-                    'cn=left_coast,cn=groups,dc=example,dc=com',
-                    {
-                        'cn': ['left_coast'],
-                        'apple-generateduid': ['left_coast'],
-                        'uniqueMember': [
-                            'uid=wsanchez,cn=users,dc=example,dc=com',
-                            'uid=lecroy,cn=users,dc=example,dc=com',
-                            'uid=dreid,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-            ])
-            self.service.ldap.addTestResults([
-                (
-                    'cn=right_coast,cn=groups,dc=example,dc=com',
-                    {
-                        'cn': ['right_coast'],
-                        'apple-generateduid': ['right_coast'],
-                        'uniqueMember': [
-                            'uid=cdaboo,cn=users,dc=example,dc=com',
-                        ],
-                    }
-                ),
-            ])
-
             self.assertEquals((False, 8), (yield updater.updateCache()))
 
             users = self.service.recordType_users
@@ -605,18 +621,6 @@
                 ("wsanchez", set(["both_coasts", "left_coast", "recursive1_coasts", "recursive2_coasts"])),
             ]:
 
-                # Fake LDAP results for the record lookup
-                self.service.ldap.addTestResults([
-                    (
-                        "uid=%s,cn=users,dc=example,dc=com" % (shortName,),
-                        {
-                            'uid': [shortName],
-                            'cn': [shortName],
-                            'apple-generateduid': [shortName],
-                        }
-                    ),
-                ])
-
                 record = self.service.recordWithShortName(users, shortName)
                 self.assertEquals(groups, (yield record.cachedGroups()))
 
@@ -658,3 +662,14 @@
             # No Match
             dnStr = "uid=foo,cn=US ers ,dc=EXAMple,dc=com"
             self.assertEquals(self.service.recordTypeForDN(dnStr), None)
+
+        def test_normalizeDN(self):
+            for input, expected in (
+                ("uid=foo,cn=users,dc=example,dc=com",
+                 "uid=foo,cn=users,dc=example,dc=com"),
+                ("uid=FoO,cn=uSeRs,dc=ExAmPlE,dc=CoM",
+                 "uid=foo,cn=users,dc=example,dc=com"),
+                ("uid=FoO , cn=uS eRs , dc=ExA mPlE ,   dc=CoM",
+                 "uid=foo,cn=us ers,dc=exa mple,dc=com"),
+            ):
+                self.assertEquals(expected, normalizeDNstr(input))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20111110/7c66c926/attachment-0001.html>


More information about the calendarserver-changes mailing list