[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