[CalendarServer-changes] [1850] CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py

source_changes at macosforge.org source_changes at macosforge.org
Sun Sep 9 14:07:43 PDT 2007


Revision: 1850
          http://trac.macosforge.org/projects/calendarserver/changeset/1850
Author:   dreid at apple.com
Date:     2007-09-09 14:07:43 -0700 (Sun, 09 Sep 2007)

Log Message:
-----------
Allow provisioning of users out of the com.apple.access_calendar SACL group in certain circumanstances where we can't search based on the services locator.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py

Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-09-09 16:03:18 UTC (rev 1849)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-09-09 21:07:43 UTC (rev 1850)
@@ -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,47 @@
                     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):
+        if isinstance(members, str):
+            members = [members]
+
+        if isinstance(nestedGroups, str):
+            nestedGroups = [nestedGroups]
+
+        for memberGUID in members:
+            yield memberGUID
+
+        for groupGUID in nestedGroups:
+            result = opendirectory.queryRecordsWithAttribute(
+                self.directory,
+                dsattributes.kDS1AttrGeneratedUID,
+                groupGUID,
+                dsattributes.eDSExact,
+                False,
+                dsattributes.kDSStdRecordTypeGroups,
+                [dsattributes.kDSNAttrGroupMembers,
+                 dsattributes.kDSNAttrNestedGroups])
+
+            group = result.values()[0]
+
+            for GUID in self._expandGroupMembership(
+                group.get(dsattributes.kDSNAttrGroupMembers, []),
+                group.get(dsattributes.kDSNAttrNestedGroups, [])):
+                yield GUID
+
     def __cmp__(self, other):
         if not isinstance(other, DirectoryRecord):
             return super(DirectoryRecord, self).__eq__(other)
@@ -429,12 +473,40 @@
                                          % (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:
+                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:
@@ -565,6 +637,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/20070909/249c2902/attachment.html


More information about the calendarserver-changes mailing list