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

source_changes at macosforge.org source_changes at macosforge.org
Fri Sep 23 12:13:08 PDT 2011


Revision: 8116
          http://trac.macosforge.org/projects/calendarserver/changeset/8116
Author:   sagen at apple.com
Date:     2011-09-23 12:13:08 -0700 (Fri, 23 Sep 2011)
Log Message:
-----------
Take advantage of efficient retrieval of location/resource delegate assignments from LDAP if properly configured.

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

Modified: CalendarServer/trunk/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2011-09-23 13:47:06 UTC (rev 8115)
+++ CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2011-09-23 19:13:08 UTC (rev 8116)
@@ -225,6 +225,12 @@
                     results.append(result)
         return results
 
+
+    def getExternalProxyAssignments(self):
+        service = self.serviceForRecordType(self.recordType_locations)
+        return service.getExternalProxyAssignments()
+
+
     def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
         fullName=None, firstName=None, lastName=None, emailAddresses=set(),
         uid=None, password=None, **kwargs):

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2011-09-23 13:47:06 UTC (rev 8115)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2011-09-23 19:13:08 UTC (rev 8116)
@@ -363,6 +363,32 @@
         return (autoaccept, proxy, read_only_proxy,)
 
 
+    def getExternalProxyAssignments(self):
+        """
+        Retrieve proxy assignments for locations and resources from the
+        directory and return a list of (principalUID, ([memberUIDs)) tuples,
+        suitable for passing to proxyDB.setGroupMembers( )
+
+        This generic implementation fetches all locations and resources.
+        More specialized implementations can perform whatever operation is
+        most efficient for their particular directory service.
+        """
+        assignments = []
+
+        resources = itertools.chain(
+            self.listRecords(self.recordType_locations),
+            self.listRecords(self.recordType_resources)
+        )
+        for record in resources:
+            guid = record.guid
+            assignments.append(("%s#calendar-proxy-write" % (guid,),
+                               record.externalProxies()))
+            assignments.append(("%s#calendar-proxy-read" % (guid,),
+                               record.externalReadOnlyProxies()))
+
+        return assignments
+
+
     def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
         fullName=None, firstName=None, lastName=None, emailAddresses=set(),
         uid=None, password=None, **kwargs):
@@ -472,8 +498,8 @@
         self.proxyDB = proxyDB
         self.directory = directory
         self.useExternalProxies = useExternalProxies
-        if externalProxiesSource is None:
-            externalProxiesSource = self.getExternalProxyAssignments
+        if useExternalProxies and externalProxiesSource is None:
+            externalProxiesSource = self.directory.getExternalProxyAssignments
         self.externalProxiesSource = externalProxiesSource
 
         if cache is None:
@@ -694,30 +720,8 @@
 
 
 
-    def getExternalProxyAssignments(self):
-        """
-        Retrieve proxy assignments for locations and resources from the
-        directory and return a list of (principalUID, ([memberUIDs)) tuples,
-        suitable for passing to proxyDB.setGroupMembers( )
-        """
-        assignments = []
 
-        resources = itertools.chain(
-            self.directory.listRecords(self.directory.recordType_locations),
-            self.directory.listRecords(self.directory.recordType_resources)
-        )
-        for record in resources:
-            guid = record.guid
-            assignments.append(("%s#calendar-proxy-write" % (guid,),
-                               record.externalProxies()))
-            assignments.append(("%s#calendar-proxy-read" % (guid,),
-                               record.externalReadOnlyProxies()))
 
-        return assignments
-
-
-
-
 class GroupMembershipCacherOptions(Options):
     optParameters = [[
         "config", "f", DEFAULT_CONFIG_FILE, "Path to configuration file."

Modified: CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-09-23 13:47:06 UTC (rev 8115)
+++ CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-09-23 19:13:08 UTC (rev 8116)
@@ -342,7 +342,48 @@
 
         return records
 
+    def getExternalProxyAssignments(self):
+        """
+        Retrieve proxy assignments for locations and resources from the
+        directory and return a list of (principalUID, ([memberUIDs)) tuples,
+        suitable for passing to proxyDB.setGroupMembers( )
+        """
+        assignments = []
 
+        guidAttr = self.rdnSchema["guidAttr"]
+        readAttr = self.resourceSchema["proxyAttr"]
+        writeAttr = self.resourceSchema["readOnlyProxyAttr"]
+        if not (guidAttr and readAttr and writeAttr):
+            self.log_error("LDAP configuration requires guidAttr, proxyAttr, and readOnlyProxyAttr in order to use external proxy assignments efficiently; falling back to slower method")
+            # Fall back to the less-specialized version
+            return super(LdapDirectoryService, self).getExternalProxyAssignments()
+
+        # Build filter
+        filterstr = "(|(%s=*)(%s=*))" % (readAttr, writeAttr)
+        attrlist = [guidAttr, readAttr, writeAttr]
+
+        # Query the LDAP server
+        self.log_debug("Querying ldap for records matching base %s and filter %s for attributes %s." %
+            (ldap.dn.dn2str(self.base), filterstr, attrlist))
+
+        results = self.timedSearch(ldap.dn.dn2str(self.base),
+            ldap.SCOPE_SUBTREE, filterstr=filterstr, attrlist=attrlist)
+
+        for dn, attrs in results:
+            guid = self._getUniqueLdapAttribute(attrs, guidAttr)
+            if guid:
+                readDelegate = self._getUniqueLdapAttribute(attrs, readAttr)
+                if readDelegate:
+                    assignments.append(("%s#calendar-proxy-read" % (guid,),
+                        [readDelegate]))
+                writeDelegate = self._getUniqueLdapAttribute(attrs, writeAttr)
+                if writeDelegate:
+                    assignments.append(("%s#calendar-proxy-write" % (guid,),
+                        [writeDelegate]))
+
+        return assignments
+
+
     def createLDAPConnection(self):
         """
         Create and configure LDAP connection
@@ -386,6 +427,7 @@
                 self.authLDAP = self.createLDAPConnection()
 
             try:
+                startTime = time.time()
                 self.authLDAP.simple_bind_s(dn, password)
                 # Getting here means success, so break the retry loop
                 break
@@ -402,6 +444,11 @@
                 self.log_error("LDAP authentication failed with %s." % (e,))
                 raise
 
+            finally:
+                totalTime = time.time() - startTime
+                if totalTime > self.warningThresholdSeconds:
+                    self.log_error("LDAP auth exceeded threshold: %.2f seconds for %s" % (totalTime, dn))
+
         else:
             self.log_error("Giving up on LDAP authentication after %d tries.  Responding with 503." % (TRIES,))
             raise HTTPError(StatusResponse(responsecode.SERVICE_UNAVAILABLE, "LDAP server unavailable"))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110923/f02094cf/attachment.html>


More information about the calendarserver-changes mailing list