[CalendarServer-changes] [1861] CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav /directory/appleopendirectory.py

source_changes at macosforge.org source_changes at macosforge.org
Mon Sep 10 16:40:50 PDT 2007


Revision: 1861
          http://trac.macosforge.org/projects/calendarserver/changeset/1861
Author:   wsanchez at apple.com
Date:     2007-09-10 16:40:49 -0700 (Mon, 10 Sep 2007)

Log Message:
-----------
Pulled up r1850 r1857 r1859 r1860 from trunk.

Modified Paths:
--------------
    CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py

Modified: CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py	2007-09-10 21:10:11 UTC (rev 1860)
+++ CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py	2007-09-10 23:40:49 UTC (rev 1861)
@@ -27,6 +27,7 @@
 
 import itertools
 import sys
+import os
 
 import opendirectory
 import dsattributes
@@ -42,8 +43,11 @@
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
 from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
 
-from plistlib import readPlistFromString
+from plistlib import readPlistFromString, readPlist
 
+_serverPreferences = '/Library/Preferences/com.apple.servermgr_info.plist'
+_saclGroup = 'com.apple.access_calendar'
+
 recordListCacheTimeout = 60 * 30 # 30 minutes
 
 class OpenDirectoryService(DirectoryService):
@@ -78,6 +82,8 @@
         self._records = {}
         self._delayedCalls = set()
 
+        self.isWorkgroupServer = False
+
         if dosetup:
             if self.requireComputerRecord:
                 try:
@@ -86,9 +92,63 @@
                     log.err("Unable to locate virtual host record: %s" % (e,))
                     raise
 
+                if os.path.exists(_serverPreferences):
+                    serverInfo = readPlist(_serverPreferences)
+
+                    self.isWorkgroupServer = serverInfo.get(
+                        'ServiceConfig', {}).get(
+                        'IsWorkgroupServer', False)
+
+                    if self.isWorkgroupServer:
+                        log.msg("Enabling Workgroup Server compatibility mode")
+
             for recordType in self.recordTypes():
                 self.recordsForType(recordType)
 
+    def _expandGroupMembership(self, members, nestedGroups, processedGUIDs=None):
+
+        if processedGUIDs is None:
+            processedGUIDs = set()
+
+        if isinstance(members, str):
+            members = [members]
+
+        if isinstance(nestedGroups, str):
+            nestedGroups = [nestedGroups]
+
+        for memberGUID in members:
+            if memberGUID not in processedGUIDs:
+                processedGUIDs.add(memberGUID)
+                yield memberGUID
+
+        for groupGUID in nestedGroups:
+            if groupGUID in processedGUIDs:
+                continue
+
+            result = opendirectory.queryRecordsWithAttribute(
+                self.directory,
+                dsattributes.kDS1AttrGeneratedUID,
+                groupGUID,
+                dsattributes.eDSExact,
+                False,
+                dsattributes.kDSStdRecordTypeGroups,
+                [dsattributes.kDSNAttrGroupMembers,
+                 dsattributes.kDSNAttrNestedGroups])
+
+            if not result:
+                log.err("Couldn't find group %s when trying to expand nested groups." % (groupGUID,))
+                continue
+
+            group = result.values()[0]
+
+            processedGUIDs.add(groupGUID)
+
+            for GUID in self._expandGroupMembership(
+                group.get(dsattributes.kDSNAttrGroupMembers, []),
+                group.get(dsattributes.kDSNAttrNestedGroups, []),
+                processedGUIDs):
+                yield GUID
+
     def __cmp__(self, other):
         if not isinstance(other, DirectoryRecord):
             return super(DirectoryRecord, self).__eq__(other)
@@ -429,12 +489,43 @@
                                          % (recordType,))
 
         if self.requireComputerRecord:
-            subquery = dsquery.match(dsattributes.kDSNAttrServicesLocator, self.servicetag, dsattributes.eDSExact)
-            if query is None:
-                query = subquery
+            if self.isWorkgroupServer and recordType == DirectoryService.recordType_users:
+                if shortName is None:
+                    results = opendirectory.queryRecordsWithAttribute(
+                        self.directory,
+                        dsattributes.kDSNAttrRecordName,
+                        _saclGroup,
+                        dsattributes.eDSExact,
+                        False,
+                        dsattributes.kDSStdRecordTypeGroups,
+                        [dsattributes.kDSNAttrGroupMembers,
+                         dsattributes.kDSNAttrNestedGroups])
+
+                    members = results.get(_saclGroup, {}).get(
+                        dsattributes.kDSNAttrGroupMembers, [])
+
+                    nestedGroups = results.get(_saclGroup, {}).get(
+                        dsattributes.kDSNAttrNestedGroups, [])
+
+                    guidQueries = []
+
+                    for GUID in self._expandGroupMembership(members,
+                                                            nestedGroups):
+                        guidQueries.append(
+                            dsquery.match(dsattributes.kDS1AttrGeneratedUID,
+                                          GUID, dsattributes.eDSExact))
+
+
+                    query = dsquery.expression(dsquery.expression.OR,
+                                               guidQueries)
+
             else:
-                query = dsquery.expression(dsquery.expression.AND, (subquery, query))
-            
+                subquery = dsquery.match(dsattributes.kDSNAttrServicesLocator, self.servicetag, dsattributes.eDSExact)
+                if query is None:
+                    query = subquery
+                else:
+                    query = dsquery.expression(dsquery.expression.AND, (subquery, query))
+
         if shortName is not None:
             subquery = dsquery.match(dsattributes.kDSNAttrRecordName, shortName, dsattributes.eDSExact)
             if query is None:
@@ -442,6 +533,7 @@
             else:
                 query = dsquery.expression(dsquery.expression.AND, (subquery, query))
 
+
         try:
             if query:
                 if isinstance(query, dsquery.match):
@@ -565,6 +657,7 @@
             storage["records"][shortName] = record
             storage["guids"][record.guid] = record
 
+
 class OpenDirectoryRecord(DirectoryRecord):
     """
     Open Directory implementation of L{IDirectoryRecord}.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070910/b388e09d/attachment.html


More information about the calendarserver-changes mailing list