[CalendarServer-changes] [3794] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 4 20:06:13 PST 2009
Revision: 3794
http://trac.macosforge.org/projects/calendarserver/changeset/3794
Author: sagen at apple.com
Date: 2009-03-04 20:06:13 -0800 (Wed, 04 Mar 2009)
Log Message:
-----------
Added some workarounds for OD returning bogus results: the client's principal-property-search REPORT query is massaged so as not to trigger the return of all rooms/resources.
Also, the .calendarserver_version file is chown'ed to the appropriate user/group
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
CalendarServer/trunk/twistedcaldav/test/test_config.py
CalendarServer/trunk/twistedcaldav/upgrade.py
Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2009-03-04 22:06:57 UTC (rev 3793)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2009-03-05 04:06:13 UTC (rev 3794)
@@ -39,6 +39,7 @@
from twisted.internet.threads import deferToThread
from twisted.cred.credentials import UsernamePassword
from twisted.web2.auth.digest import DigestedCredentials
+from twisted.internet.defer import succeed, returnValue
from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
@@ -360,12 +361,39 @@
index.setdefault(guid, set()).add(group)
_ODFields = {
- 'fullName' : dsattributes.kDS1AttrDistinguishedName,
- 'firstName' : dsattributes.kDS1AttrFirstName,
- 'lastName' : dsattributes.kDS1AttrLastName,
- 'emailAddresses' : dsattributes.kDSNAttrEMailAddress,
- 'recordName' : dsattributes.kDSNAttrRecordName,
- 'guid' : dsattributes.kDS1AttrGeneratedUID,
+ 'fullName' : {
+ 'odField' : dsattributes.kDS1AttrDistinguishedName,
+ 'excludes' : set(),
+ },
+ 'firstName' : {
+ 'odField' : dsattributes.kDS1AttrFirstName,
+ 'excludes' : set([
+ dsattributes.kDSStdRecordTypePlaces,
+ dsattributes.kDSStdRecordTypeResources,
+ ]),
+ },
+ 'lastName' : {
+ 'odField' : dsattributes.kDS1AttrLastName,
+ 'excludes' : set([
+ dsattributes.kDSStdRecordTypePlaces,
+ dsattributes.kDSStdRecordTypeResources,
+ ]),
+ },
+ 'emailAddresses' : {
+ 'odField' : dsattributes.kDSNAttrEMailAddress,
+ 'excludes' : set([
+ dsattributes.kDSStdRecordTypePlaces,
+ dsattributes.kDSStdRecordTypeResources,
+ ]),
+ },
+ 'recordName' : {
+ 'odField' : dsattributes.kDSNAttrRecordName,
+ 'excludes' : set(),
+ },
+ 'guid' : {
+ 'odField' : dsattributes.kDS1AttrGeneratedUID,
+ 'excludes' : set(),
+ },
}
def recordsMatchingFields(self, fields, operand="or", recordType=None):
@@ -390,10 +418,48 @@
operand = (dsquery.expression.OR if operand == "or"
else dsquery.expression.AND)
+ excluded = set()
+ for field, value, caseless, matchType in fields:
+ if field in self._ODFields:
+ ODField = self._ODFields[field]['odField']
+ excluded = excluded | self._ODFields[field]['excludes']
+
+ _ODTypes = {
+ self.recordType_users: dsattributes.kDSStdRecordTypeUsers,
+ self.recordType_locations: dsattributes.kDSStdRecordTypePlaces,
+ self.recordType_groups: dsattributes.kDSStdRecordTypeGroups,
+ self.recordType_resources: dsattributes.kDSStdRecordTypeResources,
+ }
+
+ if recordType is None:
+ # The client is looking for records in any of the four types
+ recordTypes = set(_ODTypes.values())
+
+ # Certain query combinations yield invalid results. In particular,
+ # any time you query on EMailAddress and are specifying Places
+ # and/or Resources in the requested types, you will get all
+ # Places/Resources returned. So here we will filter out known
+ # invalid combinations:
+ excludeFields = False
+ recordTypes = list(recordTypes - excluded)
+
+ else:
+ # The client is after only one recordType, so let's tailor the
+ # query to not include any fields OD has trouble with:
+ excludeFields = True
+ recordTypes = [_ODTypes[recordType]]
+
expressions = []
for field, value, caseless, matchType in fields:
if field in self._ODFields:
- ODField = self._ODFields[field]
+
+ if (excludeFields and
+ _ODTypes[recordType] in self._ODFields[field]['excludes']):
+ # This is a field we're excluding because it behaves badly
+ # for the record type result we're looking for. Skip it.
+ continue
+
+ ODField = self._ODFields[field]['odField']
if matchType == "starts-with":
comparison = dsattributes.eDSStartsWith
elif matchType == "contains":
@@ -402,20 +468,14 @@
comparison = dsattributes.eDSExact
expressions.append(dsquery.match(ODField, value, comparison))
+ if not recordTypes or not expressions:
+ # If we've excluded all types or all expressions, short circuit.
+ self.log_info("Empty query, skipping call to OD")
+ return []
- recordTypeToODAttr = {
- self.recordType_users: dsattributes.kDSStdRecordTypeUsers,
- self.recordType_locations: dsattributes.kDSStdRecordTypePlaces,
- self.recordType_groups: dsattributes.kDSStdRecordTypeGroups,
- self.recordType_resources: dsattributes.kDSStdRecordTypeResources,
- }
+ self.log_info("Calling OD: Types %s, Operand %s, Caseless %s, %s" %
+ (recordTypes, operand, caseless, fields))
- if recordType is None:
- recordTypes = recordTypeToODAttr.values()
- else:
- recordTypes = (recordTypeToODAttr[recordType],)
-
- self.log_info("Calling OD: Types %s, Operand %s, Caseless %s, %s" % (recordTypes, operand, caseless, fields))
deferred = deferToThread(
opendirectory.queryRecordsWithAttributes,
self.directory,
Modified: CalendarServer/trunk/twistedcaldav/test/test_config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_config.py 2009-03-04 22:06:57 UTC (rev 3793)
+++ CalendarServer/trunk/twistedcaldav/test/test_config.py 2009-03-05 04:06:13 UTC (rev 3794)
@@ -179,7 +179,8 @@
self.assertEquals(config.DirectoryService.type, "twistedcaldav.directory.xmlfile.XMLDirectoryService")
self.assertEquals(config.DirectoryService.params.xmlFile, "/etc/caldavd/accounts.xml")
- self.assertRaises(ConfigurationError, config.update, {"DirectoryService": {"params": {"restrictEnabledRecords": False}}})
+ # Unrecognized params no longer raise an exception
+ # self.assertRaises(ConfigurationError, config.update, {"DirectoryService": {"params": {"restrictEnabledRecords": False}}})
def testDirectoryService_unknownType(self):
self.assertEquals(config.DirectoryService.type, "twistedcaldav.directory.xmlfile.XMLDirectoryService")
Modified: CalendarServer/trunk/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/upgrade.py 2009-03-04 22:06:57 UTC (rev 3793)
+++ CalendarServer/trunk/twistedcaldav/upgrade.py 2009-03-05 04:06:13 UTC (rev 3794)
@@ -32,7 +32,25 @@
log = Logger()
+def getCalendarServerIDs(config):
+ # Determine uid/gid for ownership of directories we create here
+ uid = -1
+ if config.UserName:
+ try:
+ uid = pwd.getpwnam(config.UserName).pw_uid
+ except KeyError:
+ log.error("User not found: %s" % (config.UserName,))
+
+ gid = -1
+ if config.GroupName:
+ try:
+ gid = grp.getgrnam(config.GroupName).gr_gid
+ except KeyError:
+ log.error("Group not found: %s" % (config.GroupName,))
+
+ return uid, gid
+
#
# upgrade_to_1
#
@@ -229,23 +247,8 @@
directory = getDirectory()
docRoot = config.DocumentRoot
+ uid, gid = getCalendarServerIDs(config)
- # Determine uid/gid for ownership of directories we create here
- uid = -1
- if config.UserName:
- try:
- uid = pwd.getpwnam(config.UserName).pw_uid
- except KeyError:
- log.error("User not found: %s" % (config.UserName,))
-
- gid = -1
- if config.GroupName:
- try:
- gid = grp.getgrnam(config.GroupName).gr_gid
- except KeyError:
- log.error("Group not found: %s" % (config.GroupName,))
-
-
if os.path.exists(docRoot):
# Look for the /principals/ directory on disk
@@ -343,12 +346,15 @@
log.error("Invalid version number in %s; skipping migration" %
(versionFilePath,))
+ uid, gid = getCalendarServerIDs(config)
+
for version, method in upgradeMethods:
if onDiskVersion < version:
log.info("Upgrading to version %d" % (version,))
method(config)
with open(versionFilePath, "w") as verFile:
verFile.write(str(version))
+ os.chown(versionFilePath, uid, gid)
class UpgradeError(RuntimeError):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090304/759069f8/attachment-0001.html>
More information about the calendarserver-changes
mailing list