[CalendarServer-changes] [3635] CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 4 11:04:47 PST 2009


Revision: 3635
          http://trac.macosforge.org/projects/calendarserver/changeset/3635
Author:   cdaboo at apple.com
Date:     2009-02-04 11:04:46 -0800 (Wed, 04 Feb 2009)
Log Message:
-----------
Support multiple shortnames in directory records.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/calendarserver/provision/root.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts-test.xml
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts.dtd
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/accesslog.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/apache.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendar.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendaruserproxy.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/directory.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/idirectory.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/principal.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sqldb.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sudo.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectory.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectoryrecords.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_principal.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_sudo.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_xmlfile.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/util.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/wiki.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlaccountsparser.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlfile.py
    CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/static.py

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/calendarserver/provision/root.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/calendarserver/provision/root.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/calendarserver/provision/root.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -127,7 +127,7 @@
         request.checkingSACL = True
         principal = (yield request.locateResource(authzUser.children[0].children[0].data))
         delattr(request, "checkingSACL")
-        username = principal.record.shortName
+        username = principal.record.shortNames[0]
 
         if RootResource.CheckSACL(username, self.saclService) != 0:
             log.msg("User %r is not enabled with the %r SACL" % (username, self.saclService,))

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts-test.xml
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts-test.xml	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts-test.xml	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -40,18 +40,18 @@
     <guid>user%02d</guid>
     <password>user%02d</password>
     <name>User %02d</name>
-    <cuaddr>mailto:user%02d at example.com</cuaddr>
     <first-name>User</first-name>
     <last-name>%02d</last-name>
+    <cuaddr>mailto:user%02d at example.com</cuaddr>
   </user>
   <user repeat="10">
     <uid>public%02d</uid>
     <guid>public%02d</guid>
     <password>public%02d</password>
     <name>Public %02d</name>
-    <cuaddr>mailto:public%02d at example.com</cuaddr>
     <first-name>Public</first-name>
     <last-name>%02d</last-name>
+    <cuaddr>mailto:public%02d at example.com</cuaddr>
   </user>
   <location repeat="10">
     <uid>location%02d</uid>

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts.dtd
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts.dtd	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/conf/auth/accounts.dtd	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 <!--
-Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -17,16 +17,16 @@
 <!ELEMENT accounts (user*, group*, resource*, location*) >
   <!ATTLIST accounts realm CDATA "">
 
-  <!ELEMENT user (uid, guid, password, name, cuaddr*, disable-calendar?)>
+  <!ELEMENT user (uid+, guid, password, name, first-name?, last-name?, email-address*, cuaddr*, disable-calendar?)>
     <!ATTLIST user repeat CDATA "1">
 
-  <!ELEMENT group (uid, guid, password, name, members, cuaddr*, disable-calendar?)>
+  <!ELEMENT group (uid+, guid, password, name, members, cuaddr*, disable-calendar?)>
     <!ATTLIST group repeat CDATA "1">
 
-  <!ELEMENT resource (uid, guid, password, name, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
+  <!ELEMENT resource (uid+, guid, password, name, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
     <!ATTLIST resource repeat CDATA "1">
 
-  <!ELEMENT location (uid, guid, password, name, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
+  <!ELEMENT location (uid+, guid, password, name, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
     <!ATTLIST location repeat CDATA "1">
 
   <!ELEMENT member (#PCDATA)>

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/accesslog.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/accesslog.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/accesslog.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -84,9 +84,9 @@
                         record = request.site.resource.getDirectory().recordWithUID(uid)
                         if record:
                             if record.recordType == DirectoryService.recordType_users:
-                                return record.shortName
+                                return record.shortNames[0]
                             else:
-                                return "(%s)%s" % (record.recordType, record.shortName,)
+                                return "(%s)%s" % (record.recordType, record.shortNames[0],)
                         else:
                             return uid
                         

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/apache.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/apache.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/apache.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -143,7 +143,7 @@
             service               = service,
             recordType            = recordType,
             guid                  = None,
-            shortName             = shortName,
+            shortNames            = (shortName,),
             fullName              = None,
             firstName             = None,
             lastName              = None,

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/appleopendirectory.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/appleopendirectory.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -170,11 +170,10 @@
             ):
                 yield GUID
 
-    def _calendarUserAddresses(self, recordType, recordName, recordData):
+    def _calendarUserAddresses(self, recordType, recordData):
         """
         Extract specific attributes from the directory record for use as calendar user address.
         
-        @param recordName: a C{str} containing the record name being operated on.
         @param recordData: a C{dict} containing the attributes retrieved from the directory.
         @return: a C{set} of C{str} for each expanded calendar user address.
         """
@@ -475,12 +474,17 @@
         for (recordShortName, value) in results:
 
             # Now get useful record info.
-            recordGUID     = value.get(dsattributes.kDS1AttrGeneratedUID)
-            recordFullName = value.get(dsattributes.kDS1AttrDistinguishedName)
-            recordFirstName = value.get(dsattributes.kDS1AttrFirstName)
-            recordLastName = value.get(dsattributes.kDS1AttrLastName)
+            recordGUID         = value.get(dsattributes.kDS1AttrGeneratedUID)
+            recordShortNames   = value.get(dsattributes.kDSNAttrRecordName)
+            if isinstance(recordShortNames, str):
+                recordShortNames = (recordShortNames,)
+            else:
+                recordShortNames = tuple(recordShortNames) if recordShortNames else ()
+            recordFullName     = value.get(dsattributes.kDS1AttrDistinguishedName)
+            recordFirstName    = value.get(dsattributes.kDS1AttrFirstName)
+            recordLastName     = value.get(dsattributes.kDS1AttrLastName)
             recordEmailAddress = value.get(dsattributes.kDSNAttrEMailAddress)
-            recordNodeName = value.get(dsattributes.kDSNAttrMetaNodeLocation)
+            recordNodeName     = value.get(dsattributes.kDSNAttrMetaNodeLocation)
 
             if not recordGUID:
                 self.log_debug("Record (%s)%s in node %s has no GUID; ignoring."
@@ -520,7 +524,7 @@
 
             # Get calendar user addresses from directory record.
             if enabledForCalendaring:
-                calendarUserAddresses = self._calendarUserAddresses(recordType, recordShortName, value)
+                calendarUserAddresses = self._calendarUserAddresses(recordType, value)
             else:
                 calendarUserAddresses = ()
 
@@ -568,7 +572,7 @@
                 recordType            = recordType,
                 guid                  = recordGUID,
                 nodeName              = recordNodeName,
-                shortName             = recordShortName,
+                shortNames            = recordShortNames,
                 fullName              = recordFullName,
                 firstName             = recordFirstName,
                 lastName              = recordLastName,
@@ -584,39 +588,48 @@
             def disableRecord(record):
                 self.log_warn("Record disabled due to conflict (record name and GUID must match): %s" % (record,))
 
-                shortName = record.shortName
-                guid      = record.guid
+                shortNames = record.shortNames
+                guid       = record.guid
 
-                disabledNames.add(shortName)
+                disabledNames.update(shortNames)
                 disabledGUIDs.add(guid)
 
-                if shortName in records:
-                    del records[shortName]
+                for shortName in shortNames:
+                    if shortName in records:
+                        del records[shortName]
                 if guid in guids:
                     del guids[guid]
 
             # Check for disabled items
-            if record.shortName in disabledNames or record.guid in disabledGUIDs:
+            if disabledNames.intersection(record.shortNames) or record.guid in disabledGUIDs:
                 disableRecord(record)
             else:
                 # Check for duplicate items and disable all names/guids for mismatched duplicates.
-                if record.shortName in records:
-                    existing_record = records[record.shortName]
-                elif record.guid in guids:
-                    existing_record = guids[record.guid]
-                else:
-                    existing_record = None
+                existing_records = set()
+                for shortName in record.shortNames:
+                    if shortName in records:
+                        existing_records.add(records[shortName])
+                if record.guid in guids:
+                    existing_records.add(guids[record.guid])
 
-                if existing_record is not None:
-                    if record.guid != existing_record.guid or record.shortName != existing_record.shortName:
-                        disableRecord(existing_record)
+                if existing_records:
+                    disable = False
+                    for existing_record in existing_records:
+                        if record.guid != existing_record.guid or record.shortNames != existing_record.shortNames:
+                            disable = True
+                            break
+                        
+                    if disable:
+                        for existing_record in existing_records:
+                            disableRecord(existing_record)
+                            if existing_record.enabledForCalendaring:
+                                enabled_count -= 1
                         disableRecord(record)
-                        
-                        if existing_record.enabledForCalendaring:
-                            enabled_count -= 1
 
-                if record.shortName not in disabledNames:
-                    records[record.shortName] = guids[record.guid] = record
+                if len(disabledNames.intersection(record.shortNames)) == 0:
+                    guids[record.guid] = record
+                    for shortName in record.shortNames:
+                        records[shortName] = record
                     self.log_debug("Added record %s to OD record cache" % (record,))
 
                     # Do group indexing if needed
@@ -701,6 +714,7 @@
     def _queryDirectory(self, recordType, lookup=None):
         attrs = [
             dsattributes.kDS1AttrGeneratedUID,
+            dsattributes.kDSNAttrRecordName,
             dsattributes.kDS1AttrDistinguishedName,
             dsattributes.kDS1AttrFirstName,
             dsattributes.kDS1AttrLastName,
@@ -817,7 +831,7 @@
     Open Directory implementation of L{IDirectoryRecord}.
     """
     def __init__(
-        self, service, recordType, guid, nodeName, shortName, fullName,
+        self, service, recordType, guid, nodeName, shortNames, fullName,
         firstName, lastName, emailAddresses,
         calendarUserAddresses, autoSchedule, enabledForCalendaring,
         memberGUIDs, proxyGUIDs, readOnlyProxyGUIDs,
@@ -826,7 +840,7 @@
             service               = service,
             recordType            = recordType,
             guid                  = guid,
-            shortName             = shortName,
+            shortNames            = shortNames,
             fullName              = fullName,
             firstName             = firstName,
             lastName              = lastName,
@@ -852,7 +866,7 @@
             self.service.guid,
             location,
             self.guid,
-            self.shortName,
+            ",".join(self.shortNames),
             self.fullName
         )
 
@@ -875,7 +889,11 @@
         for guid in self._proxyGUIDs:
             proxyRecord = self.service.recordWithGUID(guid)
             if proxyRecord is None:
-                self.log_error("No record for proxy in %s with GUID %s" % (self.shortName, guid))
+                self.log_error("No record for proxy in (%s)%s with GUID %s" % (
+                    self.recordType,
+                    self.shortNames[0],
+                    guid,
+                ))
             else:
                 yield proxyRecord
 
@@ -892,7 +910,11 @@
         for guid in self._readOnlyProxyGUIDs:
             proxyRecord = self.service.recordWithGUID(guid)
             if proxyRecord is None:
-                self.log_error("No record for proxy in %s with GUID %s" % (self.shortName, guid))
+                self.log_error("No record for proxy in (%s)%s with GUID %s" % (
+                    self.recordType,
+                    self.shortNames[0],
+                    guid,
+                ))
             else:
                 yield proxyRecord
 
@@ -913,13 +935,13 @@
 
             # Check with directory services
             try:
-                if opendirectory.authenticateUserBasic(self.service.directory, self.nodeName, self.shortName, credentials.password):
+                if opendirectory.authenticateUserBasic(self.service.directory, self.nodeName, self.shortNames[0], credentials.password):
                     # Cache the password to avoid future DS queries
                     self.password = credentials.password
                     return True
             except opendirectory.ODError, e:
                 self.log_error("Open Directory (node=%s) error while performing basic authentication for user %s: %s"
-                            % (self.service.realmName, self.shortName, e))
+                            % (self.service.realmName, self.shortNames[0], e))
 
             return False
 
@@ -942,7 +964,7 @@
                 self.log_error(
                     "Open Directory (node=%s) error while performing digest authentication for user %s: "
                     "missing digest response field: %s in: %s"
-                    % (self.service.realmName, self.shortName, e, credentials.fields)
+                    % (self.service.realmName, self.shortNames[0], e, credentials.fields)
                 )
                 return False
 
@@ -956,7 +978,7 @@
                 if opendirectory.authenticateUserDigest(
                     self.service.directory,
                     self.nodeName,
-                    self.shortName,
+                    self.shortNames[0],
                     challenge,
                     response,
                     credentials.method
@@ -977,12 +999,12 @@
     Challenge: %s
     Response:  %s
     Method:    %s
-""" % (self.nodeName, self.shortName, challenge, response, credentials.method))
+""" % (self.nodeName, self.shortNames[0], challenge, response, credentials.method))
 
             except opendirectory.ODError, e:
                 self.log_error(
                     "Open Directory (node=%s) error while performing digest authentication for user %s: %s"
-                    % (self.service.realmName, self.shortName, e)
+                    % (self.service.realmName, self.shortNames[0], e)
                 )
                 return False
 

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendar.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendar.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -165,11 +165,14 @@
 
     def listChildren(self):
         if config.EnablePrincipalListings:
-            return (
-                record.shortName
-                for record in self.directory.listRecords(self.recordType)
-                if record.enabledForCalendaring
-            )
+
+            def _recordShortnameExpand():
+                for record in self.directory.listRecords(self.recordType):
+                    if record.enabledForCalendaring:
+                        for shortName in record.shortNames:
+                            yield shortName
+
+            return _recordShortnameExpand()
         else:
             # Not a listable collection
             raise HTTPError(responsecode.FORBIDDEN)

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendaruserproxy.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/calendaruserproxy.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -239,7 +239,7 @@
                 """---------------------\n"""
                 """GUID: %s\n"""                   % (self.parent.record.guid,),
                 """Record type: %s\n"""            % (self.parent.record.recordType,),
-                """Short name: %s\n"""             % (self.parent.record.shortName,),
+                """Short names: %s\n"""            % (",".join(self.parent.record.shortNames,)),
                 """Full name: %s\n"""              % (self.parent.record.fullName,),
                 """Principal UID: %s\n"""          % (self.parent.principalUID(),),
                 """Principal URL: %s\n"""          % (format_link(self.parent.principalURL()),),

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/directory.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/directory.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -251,22 +251,22 @@
             self.service.guid,
             self.service.realmName,
             self.guid,
-            self.shortName,
+            ",".join(self.shortNames),
             self.fullName
         )
 
     def __init__(
-        self, service, recordType, guid, shortName, fullName,
+        self, service, recordType, guid, shortNames, fullName,
         firstName, lastName, emailAddresses,
         calendarUserAddresses, autoSchedule, enabledForCalendaring=True,
         uid=None,
     ):
         assert service.realmName is not None
         assert recordType
-        assert shortName
+        assert shortNames and isinstance(shortNames, tuple) 
 
         if not guid:
-            guid = uuidFromName(service.guid, "%s:%s" % (recordType, shortName))
+            guid = uuidFromName(service.guid, "%s:%s" % (recordType, ",".join(shortNames)))
 
         if uid is None:
             uid = guid
@@ -281,7 +281,7 @@
         self.recordType            = recordType
         self.guid                  = guid
         self.uid                   = uid
-        self.shortName             = shortName
+        self.shortNames            = shortNames
         self.fullName              = fullName
         self.firstName             = firstName
         self.lastName              = lastName
@@ -294,7 +294,7 @@
         if not isinstance(other, DirectoryRecord):
             return NotImplemented
 
-        for attr in ("service", "recordType", "shortName", "guid"):
+        for attr in ("service", "recordType", "shortNames", "guid"):
             diff = cmp(getattr(self, attr), getattr(other, attr))
             if diff != 0:
                 return diff
@@ -302,7 +302,7 @@
 
     def __hash__(self):
         h = hash(self.__class__)
-        for attr in ("service", "recordType", "shortName", "guid",
+        for attr in ("service", "recordType", "shortNames", "guid",
                      "enabledForCalendaring"):
             h = (h + hash(getattr(self, attr))) & sys.maxint
 

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/idirectory.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/idirectory.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/idirectory.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@
     recordType            = Attribute("The type of this record.")
     guid                  = Attribute("The GUID of this record.")
     uid                   = Attribute("The UID of this record.")
-    shortName             = Attribute("The name of this record.")
+    shortNames            = Attribute("The names for this record.")
     fullName              = Attribute("The full name of this record.")
     firstName             = Attribute("The first name of this record.")
     lastName              = Attribute("The last name of this record.")

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/principal.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/principal.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -33,6 +33,7 @@
 from cgi import escape
 from urllib import unquote
 from urlparse import urlparse
+import itertools
 
 from twisted.python.failure import Failure
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -380,7 +381,13 @@
 
     def listChildren(self):
         if config.EnablePrincipalListings:
-            return (record.shortName for record in self.directory.listRecords(self.recordType))
+
+            def _recordShortnameExpand():
+                for record in self.directory.listRecords(self.recordType):
+                    for shortName in record.shortNames:
+                        yield shortName
+
+            return _recordShortnameExpand()
         else:
             # Not a listable collection
             raise HTTPError(responsecode.FORBIDDEN)
@@ -491,12 +498,12 @@
         self.parent = parent
         self._url   = url
 
-        self._alternate_urls = (
-            joinURL(parent.parent.principalCollectionURL(), record.recordType, record.shortName) + slash,
-        )
+        self._alternate_urls = tuple([
+            joinURL(parent.parent.principalCollectionURL(), record.recordType, shortName) + slash for shortName in record.shortNames
+        ])
 
     def __str__(self):
-        return "(%s) %s" % (self.record.recordType, self.record.shortName)
+        return "(%s) %s" % (self.record.recordType, self.record.shortNames[0])
 
     def deadProperties(self):
         if not hasattr(self, "_dead_properties"):
@@ -536,7 +543,7 @@
             """---------------------\n"""
             """GUID: %s\n"""                   % (self.record.guid,),
             """Record type: %s\n"""            % (self.record.recordType,),
-            """Short name: %s\n"""             % (self.record.shortName,),
+            """Short names: %s\n"""            % (",".join(self.record.shortNames),),
             """Full name: %s\n"""              % (self.record.fullName,),
             """First name: %s\n"""             % (self.record.firstName,),
             """Last name: %s\n"""              % (self.record.lastName,),
@@ -563,7 +570,7 @@
         if self.record.fullName:
             return self.record.fullName
         else:
-            return self.record.shortName
+            return self.record.shortNames[0]
 
     ##
     # ACL
@@ -749,7 +756,7 @@
             """---------------------\n"""
             """GUID: %s\n"""                   % (self.record.guid,),
             """Record type: %s\n"""            % (self.record.recordType,),
-            """Short name: %s\n"""             % (self.record.shortName,),
+            """Short names: %s\n"""            % (",".join(self.record.shortNames),),
             """Full name: %s\n"""              % (self.record.fullName,),
             """First name: %s\n"""             % (self.record.firstName,),
             """Last name: %s\n"""              % (self.record.lastName,),
@@ -905,20 +912,17 @@
     return "".join(genlist())
 
 def format_principals(principals):
-    def sort(a, b):
-        def sortkey(principal):
+    def recordKey(principal):
+        try:
+            record = principal.record
+        except AttributeError:
             try:
-                record = principal.record
-            except AttributeError:
-                try:
-                    record = principal.parent.record
-                except:
-                    return None
+                record = principal.parent.record
+            except:
+                return None
 
-            return [record.recordType, record.shortName]
+        return (record.recordType, record.shortNames[0])
 
-        return cmp(sortkey(a), sortkey(b))
-
     def describe(principal):
         if hasattr(principal, "record"):
             return " - %s" % (principal.record.fullName,)
@@ -928,7 +932,7 @@
     return format_list(
         """<a href="%s">%s%s</a>"""
         % (principal.principalURL(), escape(str(principal)), describe(principal))
-        for principal in sorted(principals, sort)
+        for principal in sorted(principals, key=recordKey)
     )
 
 def format_link(url):

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sqldb.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sqldb.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sqldb.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -173,7 +173,7 @@
     def _add_to_db(self, record):
         # Do regular account entry
         recordType = record.recordType
-        shortName = record.shortName
+        shortName = record.shortNames[0]
         guid = record.guid
         password = record.password
         name = record.name
@@ -348,7 +348,7 @@
             service               = service,
             recordType            = recordType,
             guid                  = guid,
-            shortName             = shortName,
+            shortNames            = (shortName,),
             fullName              = name,
             firstName             = None,
             lastName              = None,

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sudo.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sudo.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/sudo.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -127,7 +127,7 @@
             service=service,
             recordType=recordType,
             guid=None,
-            shortName=shortName,
+            shortNames=(shortName,),
             fullName=shortName,
             firstName="",
             lastName="",

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectory.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectory.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectory.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@
                 recordType            = DirectoryService.recordType_users,
                 guid                  = "B1F93EB1-DA93-4772-9141-81C250DA35B3",
                 nodeName              = "/LDAPv2/127.0.0.1",
-                shortName             = "user",
+                shortNames            = ("user",),
                 fullName              = "Some user",
                 firstName             = "Some",
                 lastName              = "User",

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectoryrecords.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectoryrecords.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_opendirectoryrecords.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -675,6 +675,7 @@
     attrs = {
         dsattributes.kDS1AttrDistinguishedName: fullName,
         dsattributes.kDS1AttrGeneratedUID: guid,
+        dsattributes.kDSNAttrRecordName: shortName,
         dsattributes.kDSNAttrEMailAddress: email,
         dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1",
     }

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_principal.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_principal.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_principal.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -102,7 +102,7 @@
                 self.assertEquals(set((provisioningURL,)), set(pc.principalCollectionURL() for pc in principalCollections))
 
                 shortNames = set(typeResource.listChildren())
-                self.assertEquals(shortNames, set(r.shortName for r in directory.listRecords(recordType)))
+                self.assertEquals(shortNames, set(r.shortNames[0] for r in directory.listRecords(recordType)))
 
                 for shortName in shortNames:
                     #print "     -> %s" % (shortName,)
@@ -131,7 +131,7 @@
         DirectoryPrincipalProvisioningResource.principalForShortName()
         """
         for provisioningResource, recordType, recordResource, record in self._allRecords():
-            principal = provisioningResource.principalForShortName(recordType, record.shortName)
+            principal = provisioningResource.principalForShortName(recordType, record.shortNames[0])
             self.failIf(principal is None)
             self.assertEquals(record, principal.record)
 
@@ -143,7 +143,7 @@
             provisioningResource = self.principalRootResources[directory.__class__.__name__]
 
             for user in directory.listRecords(DirectoryService.recordType_users):
-                userResource = provisioningResource.principalForUser(user.shortName)
+                userResource = provisioningResource.principalForUser(user.shortNames[0])
                 self.failIf(userResource is None)
                 self.assertEquals(user, userResource.record)
 
@@ -193,7 +193,7 @@
             self.failIf(principal is None)
             if record.enabledForCalendaring:
                 self.assertEquals(record.autoSchedule, principal.autoSchedule())
-                if record.shortName == "gemini":
+                if record.shortNames[0] == "gemini":
                     self.assertTrue(principal.autoSchedule())
                 else:
                     self.assertFalse(principal.autoSchedule())

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_sudo.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_sudo.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_sudo.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -53,8 +53,8 @@
 
     def test_listRecords(self):
         for record in self.service().listRecords(self.recordType):
-            self.failUnless(record.shortName in self.sudoers)
-            self.assertEqual(self.sudoers[record.shortName]['password'],
+            self.failUnless(record.shortNames[0] in self.sudoers)
+            self.assertEqual(self.sudoers[record.shortNames[0]]['password'],
                              record.password)
 
     def test_recordWithShortName(self):

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_xmlfile.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_xmlfile.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/test_xmlfile.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -116,7 +116,7 @@
             ( DirectoryService.recordType_resources , ()         ),
         ):
             self.assertEquals(
-                set(r.shortName for r in service.listRecords(recordType)),
+                set(r.shortNames[0] for r in service.listRecords(recordType)),
                 set(expectedRecords)
             )
 
@@ -143,7 +143,7 @@
             ( DirectoryService.recordType_resources , ()             ),
         ):
             self.assertEquals(
-                set(r.shortName for r in service.listRecords(recordType)),
+                set(r.shortNames[0] for r in service.listRecords(recordType)),
                 set(expectedRecords)
             )
         self.assertTrue(service.recordWithShortName(DirectoryService.recordType_locations, "my office").autoSchedule)
@@ -166,7 +166,7 @@
         )
         
         def _findRecords():
-            set(r.shortName for r in service.listRecords(DirectoryService.recordType_users))
+            set(r.shortNames[0] for r in service.listRecords(DirectoryService.recordType_users))
 
         self.assertRaises(ValueError, _findRecords)
         
@@ -198,7 +198,7 @@
             ( DirectoryService.recordType_resources , ()                       ),
         ):
             self.assertEquals(
-                set(r.shortName for r in service.listRecords(recordType)),
+                set(r.shortNames[0] for r in service.listRecords(recordType)),
                 set(expectedRecords)
             )
         self.assertTrue(service.recordWithShortName(DirectoryService.recordType_groups, "enabled").enabledForCalendaring)
@@ -222,7 +222,7 @@
         )
         
         def _findRecords():
-            set(r.shortName for r in service.listRecords(DirectoryService.recordType_users))
+            set(r.shortNames[0] for r in service.listRecords(DirectoryService.recordType_users))
 
         self.assertRaises(ValueError, _findRecords)
 
@@ -257,7 +257,7 @@
             ( DirectoryService.recordType_resources , ()             ),
         ):
             self.assertEquals(
-                set(r.shortName for r in service.listRecords(recordType)),
+                set(r.shortNames[0] for r in service.listRecords(recordType)),
                 set(expectedRecords)
             )
         self.assertEqual(set([("users", "test",)],), service.recordWithShortName(DirectoryService.recordType_locations, "my office")._proxies)
@@ -283,6 +283,6 @@
         )
         
         def _findRecords():
-            set(r.shortName for r in service.listRecords(DirectoryService.recordType_users))
+            set(r.shortNames[0] for r in service.listRecords(DirectoryService.recordType_users))
 
         self.assertRaises(ValueError, _findRecords)

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/util.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/util.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/test/util.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -163,7 +163,7 @@
         for group, info in self.groups.iteritems():
             prefix = info.get("prefix", "")
             groupRecord = service.recordWithShortName(prefix + DirectoryService.recordType_groups, group)
-            result = set((m.recordType, prefix + m.shortName) for m in groupRecord.members())
+            result = set((m.recordType, prefix + m.shortNames[0]) for m in groupRecord.members())
             expected = set(self.groups[group]["members"])
             self.assertEquals(
                 result, expected,
@@ -187,7 +187,7 @@
             for shortName, info in data.iteritems():
                 prefix = info.get("prefix", "")
                 record = service.recordWithShortName(prefix + recordType, shortName)
-                result = set(prefix + g.shortName for g in record.groups())
+                result = set(prefix + g.shortNames[0] for g in record.groups())
                 expected = set(g for g in self.groups if (record.recordType, shortName) in self.groups[g]["members"])
                 self.assertEquals(
                     result, expected,
@@ -204,7 +204,7 @@
                 continue
             assert records is not None, "%r(%r) returned None" % (service.listRecords, recordType)
             for record in records:
-                names.add(prefix + record.shortName)
+                names.add(prefix + record.shortNames[0])
 
         return names
 
@@ -238,7 +238,7 @@
         else:
             prefix = ""
 
-        self.assertEquals(prefix + record.shortName, shortName)
+        self.assertEquals(prefix + record.shortNames[0], shortName)
         self.assertEquals(set(record.calendarUserAddresses), addresses)
 
         if value("guid"):

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/wiki.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/wiki.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/wiki.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@
             recordType=recordType,
             guid=None,
             uid="%s%s" % (WikiDirectoryService.UIDPrefix, shortName),
-            shortName=shortName,
+            shortNames=(shortName,),
             fullName=shortName,
             firstName="",
             lastName="",
@@ -146,7 +146,7 @@
 
     wikiConfig = config.Authentication.Wiki
     userID = "unauthenticated"
-    wikiID = resource.record.shortName
+    wikiID = resource.record.shortNames[0]
 
     try:
         url = str(request.authzUser.children[0])

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlaccountsparser.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlaccountsparser.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -106,22 +106,22 @@
         def updateMembership(group):
             # Update group membership
             for recordType, shortName in group.members:
-                item = self.items[recordType].get(shortName, None)
+                item = self.items[recordType].get(shortName)
                 if item is not None:
-                    item.groups.add(group.shortName)
+                    item.groups.add(group.shortNames[0])
 
         def updateProxyFor(proxier):
             # Update proxy membership
             for recordType, shortName in proxier.proxies:
-                item = self.items[recordType].get(shortName, None)
+                item = self.items[recordType].get(shortName)
                 if item is not None:
-                    item.proxyFor.add((proxier.recordType, proxier.shortName))
+                    item.proxyFor.add((proxier.recordType, proxier.shortNames[0]))
 
             # Update read-only proxy membership
             for recordType, shortName in proxier.readOnlyProxies:
-                item = self.items[recordType].get(shortName, None)
+                item = self.items[recordType].get(shortName)
                 if item is not None:
-                    item.readOnlyProxyFor.add((proxier.recordType, proxier.shortName))
+                    item.readOnlyProxyFor.add((proxier.recordType, proxier.shortNames[0]))
 
         for child in node._get_childNodes():
             child_name = child._get_localName()
@@ -143,9 +143,9 @@
             if repeat > 1:
                 for i in xrange(1, repeat+1):
                     newprincipal = principal.repeat(i)
-                    self.items[recordType][newprincipal.shortName] = newprincipal
+                    self.items[recordType][newprincipal.shortNames[0]] = newprincipal
             else:
-                self.items[recordType][principal.shortName] = principal
+                self.items[recordType][principal.shortNames[0]] = principal
 
         # Do reverse membership mapping only after all records have been read in
         for records in self.items.itervalues():
@@ -162,7 +162,7 @@
         @param recordType: record type for directory entry.
         """
         self.recordType = recordType
-        self.shortName = None
+        self.shortNames = []
         self.guid = None
         self.password = None
         self.name = None
@@ -185,10 +185,12 @@
         done on them with the numeric value provided.
         @param ctr: an integer to substitute into text.
         """
-        if self.shortName.find("%") != -1:
-            shortName = self.shortName % ctr
-        else:
-            shortName = self.shortName
+        shortNames = []
+        for shortName in self.shortNames:
+            if shortName.find("%") != -1:
+                shortNames.append(shortName % ctr)
+            else:
+                shortNames.append(shortName)
         if self.guid and self.guid.find("%") != -1:
             guid = self.guid % ctr
         else:
@@ -223,7 +225,7 @@
                 calendarUserAddresses.add(cuaddr)
         
         result = XMLAccountRecord(self.recordType)
-        result.shortName = shortName
+        result.shortNames = shortNames
         result.guid = guid
         result.password = password
         result.name = name
@@ -245,7 +247,7 @@
                 continue
             elif child_name == ELEMENT_SHORTNAME:
                 if child.firstChild is not None:
-                    self.shortName = child.firstChild.data.encode("utf-8")
+                    self.shortNames.append(child.firstChild.data.encode("utf-8"))
             elif child_name == ELEMENT_GUID:
                 if child.firstChild is not None:
                     guid = child.firstChild.data.encode("utf-8")

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlfile.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlfile.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/directory/xmlfile.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -64,30 +64,30 @@
         return recordTypes
 
     def listRecords(self, recordType):
-        for entryShortName, xmlPrincipal in self._entriesForRecordType(recordType):
+        for _ignore_entryShortName, xmlPrincipal in self._entriesForRecordType(recordType):
             yield XMLDirectoryRecord(
                 service       = self,
                 recordType    = recordType,
-                shortName     = entryShortName,
+                shortNames    = tuple(xmlPrincipal.shortNames),
                 xmlPrincipal  = xmlPrincipal,
             )
 
     def recordWithShortName(self, recordType, shortName):
-        for entryShortName, xmlprincipal in self._entriesForRecordType(recordType):
-            if entryShortName == shortName:
+        for _ignore_entryShortName, xmlPrincipal in self._entriesForRecordType(recordType):
+            if shortName in xmlPrincipal.shortNames:
                 return XMLDirectoryRecord(
                     service       = self,
                     recordType    = recordType,
-                    shortName     = entryShortName,
-                    xmlPrincipal  = xmlprincipal,
+                    shortNames    = tuple(xmlPrincipal.shortNames),
+                    xmlPrincipal  = xmlPrincipal,
                 )
 
         return None
 
     def _entriesForRecordType(self, recordType):
         try:
-            for entry in sorted(self._accounts()[recordType].itervalues(), key=lambda x: x.shortName):
-                yield entry.shortName, entry
+            for shortName, entry in sorted(self._accounts()[recordType].iteritems(), key=lambda x: x[0]):
+                yield shortName, entry
         except KeyError:
             return
 
@@ -108,12 +108,12 @@
     """
     XML based implementation implementation of L{IDirectoryRecord}.
     """
-    def __init__(self, service, recordType, shortName, xmlPrincipal):
+    def __init__(self, service, recordType, shortNames, xmlPrincipal):
         super(XMLDirectoryRecord, self).__init__(
             service               = service,
             recordType            = recordType,
             guid                  = xmlPrincipal.guid,
-            shortName             = shortName,
+            shortNames            = shortNames,
             fullName              = xmlPrincipal.name,
             firstName             = xmlPrincipal.firstName,
             lastName              = xmlPrincipal.lastName,

Modified: CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/static.py	2009-02-04 17:52:18 UTC (rev 3634)
+++ CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/twistedcaldav/static.py	2009-02-04 19:04:46 UTC (rev 3635)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -48,6 +48,7 @@
 from twisted.web2.dav.fileop import mkcollection, rmdir
 from twisted.web2.dav.http import ErrorResponse
 from twisted.web2.dav.idav import IDAVResource
+from twisted.web2.dav.noneprops import NonePropertyStore
 from twisted.web2.dav.resource import AccessDeniedError
 from twisted.web2.dav.resource import davPrivilegeSet
 from twisted.web2.dav.util import parentForURL, bindMethods
@@ -610,7 +611,7 @@
                 # Pre 2.0: All in one directory
                 self.fp.child(name),
                 # Pre 1.2: In types hierarchy instead of the GUID hierarchy
-                self.parent.getChild(record.recordType).fp.child(record.shortName),
+                self.parent.getChild(record.recordType).fp.child(record.shortNames[0]),
             ):
                 if oldPath.exists():
                     # The child exists at an old location.  Move to new location.
@@ -864,9 +865,6 @@
     def __init__(self, path, parent):
         CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
         IScheduleInboxResource.__init__(self, parent)
-        
-        self.fp.open("w").close()
-        self.fp.restat(False)
 
     def __repr__(self):
         return "<%s (server-to-server inbox resource): %s>" % (self.__class__.__name__, self.fp.path)
@@ -892,8 +890,10 @@
             (caldav_namespace, "calendar-collection-location-ok")
         )
 
-    def hasDeadProperty(self, name):
-        return False
+    def deadProperties(self):
+        if not hasattr(self, "_dead_properties"):
+            self._dead_properties = NonePropertyStore(self)
+        return self._dead_properties
 
     def etag(self):
         return None
@@ -1015,8 +1015,10 @@
             (caldav_namespace, "calendar-collection-location-ok")
         )
 
-    def hasDeadProperty(self, name):
-        return False
+    def deadProperties(self):
+        if not hasattr(self, "_dead_properties"):
+            self._dead_properties = NonePropertyStore(self)
+        return self._dead_properties
 
     def etag(self):
         return None
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090204/3fcc9e7f/attachment-0001.html>


More information about the calendarserver-changes mailing list