[CalendarServer-changes] [1908]
CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav
/directory
source_changes at macosforge.org
source_changes at macosforge.org
Tue Sep 25 16:03:25 PDT 2007
Revision: 1908
http://trac.macosforge.org/projects/calendarserver/changeset/1908
Author: wsanchez at apple.com
Date: 2007-09-25 16:03:25 -0700 (Tue, 25 Sep 2007)
Log Message:
-----------
Pulled up r1896 from trunk.
Modified Paths:
--------------
CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py
CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/test/test_opendirectoryschema.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-25 23:02:56 UTC (rev 1907)
+++ CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/appleopendirectory.py 2007-09-25 23:03:25 UTC (rev 1908)
@@ -183,24 +183,17 @@
attrs = [
dsattributes.kDS1AttrGeneratedUID,
dsattributes.kDSNAttrRecordName,
- dsattributes.kDS1AttrXMLPlist,
dsattributes.kDSNAttrMetaNodeLocation,
'dsAttrTypeNative:apple-serviceinfo',
]
- from dsquery import expression, match
-
records = opendirectory.queryRecordsWithAttributes(
self.directory,
- expression(
- expression.OR,
- (
- match(dsattributes.kDS1AttrXMLPlist,
- vhostname,
- dsattributes.eDSContains),
- match('dsAttrTypeNative:apple-serviceinfo',
- vhostname,
- dsattributes.eDSContains))).generate(),
+ dsquery.match(
+ 'dsAttrTypeNative:apple-serviceinfo',
+ vhostname,
+ dsattributes.eDSContains,
+ ).generate(),
True, # case insentive for hostnames
dsattributes.kDSStdRecordTypeComputers,
attrs
@@ -222,9 +215,9 @@
# Prefering the remote OD node to the local OD Node and
# the local OD Node to the local node.
- _localNode = None
- _localODNode = None
- _remoteNode = None
+ _localNodes = []
+ _localODNodes = []
+ _remoteNodes = []
for recordname, record in records.iteritems():
# May have an apple-serviceinfo
@@ -251,19 +244,38 @@
continue
if record[dsattributes.kDSNAttrMetaNodeLocation] == localNodePath:
- _localNode = (recordname, plist, record[dsattributes.kDS1AttrGeneratedUID])
+ _localNodes.append((recordname, plist, record[dsattributes.kDS1AttrGeneratedUID]))
elif record[dsattributes.kDSNAttrMetaNodeLocation] == localODNodePath:
- _localODNode = (recordname, plist, record[dsattributes.kDS1AttrGeneratedUID])
+ _localODNodes.append((recordname, plist, record[dsattributes.kDS1AttrGeneratedUID]))
else:
- _remoteNode = (recordname, plist, record[dsattributes.kDS1AttrGeneratedUID])
+ _remoteNodes.append((recordname, plist, record[dsattributes.kDS1AttrGeneratedUID]))
- # XXX: These calls to self._parseXMLPlist will cause the plsit to be parsed _again_
+ # Verify that we only have a single record type to match
+ if len(_remoteNodes) > 1:
+ raise OpenDirectoryInitError(
+ "Open Directory (node=%s) too many remote /Computers records (%s) were found matching virtual hostname: %s"
+ % (self.realmName, ", ".join([r[0] for r in _remoteNodes]), vhostname,)
+ )
+
+ if len(_remoteNodes) == 0 and len(_localODNodes) > 1:
+ raise OpenDirectoryInitError(
+ "Open Directory (node=%s) too many local OD /Computers records (%s) were found matching virtual hostname: %s"
+ % (self.realmName, ", ".join([r[0] for r in _localODNodes]), vhostname,)
+ )
+
+ if len(_remoteNodes) == 0 and len(_localODNodes) == 0 and len(_localNodes) > 1:
+ raise OpenDirectoryInitError(
+ "Open Directory (node=%s) too many local /Computers records (%s) were found matching virtual hostname: %s"
+ % (self.realmName, ", ".join([r[0] for r in _localNodes]), vhostname,)
+ )
+
+ # XXX: These calls to self._parseServiceInfo will cause the plist to be parsed _again_
# refactor later so we only ever parse it once.
- for node in (_remoteNode, _localODNode, _localNode):
- if node and self._parseXMLPlist(vhostname, *node):
+ for node in itertools.chain(_remoteNodes, _localODNodes, _localNodes):
+ if node and self._parseServiceInfo(vhostname, *node):
break
else:
@@ -273,14 +285,14 @@
% (self.realmName, vhostname,)
)
- def _parseXMLPlist(self, vhostname, recordname, plist, recordguid):
+ def _parseServiceInfo(self, vhostname, recordname, plist, recordguid):
# Parse the plist and look for our special entry
plist = readPlistFromString(plist)
vhosts = plist.get("com.apple.macosxserver.virtualhosts", None)
if not vhosts:
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have a "
- "com.apple.macosxserver.virtualhosts in its XMLPlist attribute value"
+ "com.apple.macosxserver.virtualhosts in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
@@ -298,7 +310,7 @@
if not hostguid:
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have a "
- "calendar service in its XMLPlist attribute value"
+ "calendar service in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
@@ -308,7 +320,7 @@
if not hostname:
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have "
- "any host name in its XMLPlist attribute value"
+ "any host name in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
@@ -325,7 +337,7 @@
if not hostdetails:
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have "
- "any host details in its XMLPlist attribute value"
+ "any host details in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
@@ -339,7 +351,7 @@
if not serviceInfos or not serviceInfos.has_key("calendar"):
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have a "
- "calendar service in its XMLPlist attribute value"
+ "calendar service in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
@@ -350,7 +362,7 @@
if not enabled:
log.msg(
"Open Directory (node=%s) /Computers/%s record does not have an "
- "enabled calendar service in its XMLPlist attribute value"
+ "enabled calendar service in its ServiceInfo attribute value"
% (self.realmName, recordname)
)
return False
Modified: CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/test/test_opendirectoryschema.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/test/test_opendirectoryschema.py 2007-09-25 23:02:56 UTC (rev 1907)
+++ CalendarServer/branches/release/CalendarServer-1.0-dev/twistedcaldav/directory/test/test_opendirectoryschema.py 2007-09-25 23:03:25 UTC (rev 1908)
@@ -823,10 +823,132 @@
</plist>
"""
+ plist_duplicate = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>ReplicaName</key>
+ <string>Master</string>
+
+ <key>com.apple.od.role</key>
+ <string>master</string>
+
+ <key>com.apple.macosxserver.virtualhosts</key>
+ <dict>
+ <key>F4088107-51FD-4DE5-904D-C20AD9C6C893</key>
+ <dict>
+ <key>hostname</key>
+ <string>foo.apple.com</string>
+
+ <key>hostDetails</key>
+ <dict>
+ <key>access</key>
+ <dict>
+ <key>somethingorother</key>
+ <string>somethingelse</string>
+ </dict>
+ <key>http</key>
+ <dict>
+ <key>port</key>
+ <integer>80</integer>
+ </dict>
+ <key>https</key>
+ <dict>
+ <key>port</key>
+ <string>443</string>
+ </dict>
+ </dict>
+
+ <key>serviceType</key>
+ <array>
+ <string>wiki</string>
+ <string>webCalendar</string>
+ <string>webMailingList</string>
+ </array>
+
+ <key>serviceInfo</key>
+ <dict>
+ <key>webCalendar</key>
+ <dict>
+ <key>enabled</key>
+ <true/>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/webcalendar</string>
+ </dict>
+ <key>wiki</key>
+ <dict>
+ <key>enabled</key>
+ <true/>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/wiki</string>
+ </dict>
+ <key>webMailingList</key>
+ <dict>
+ <key>enabled</key>
+ <true/>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/mailinglist</string>
+ </dict>
+ </dict>
+ </dict>
+
+ <key>1C8C34AC-3D9E-403C-8A33-FBC303F3840E</key>
+ <dict>
+ <key>hostname</key>
+ <string>calendar.apple.com</string>
+
+ <key>hostDetails</key>
+ <dict>
+ <key>access</key>
+ <dict>
+ <key>somethingorother</key>
+ <string>somethingelse</string>
+ </dict>
+ <key>http</key>
+ <dict>
+ <key>port</key>
+ <integer>8008</integer>
+ </dict>
+ <key>https</key>
+ <dict>
+ <key>port</key>
+ <integer>8443</integer>
+ </dict>
+ </dict>
+
+ <key>serviceType</key>
+ <array>
+ <string>calendar</string>
+ </array>
+
+ <key>serviceInfo</key>
+ <dict>
+ <key>calendar</key>
+ <dict>
+ <key>templates</key>
+ <dict>
+ <key>principalPath</key>
+ <string>/principals/%(type)s/%(name)s</string>
+ <key>calendarUserAddresses</key>
+ <array>
+ <string>%(scheme)s://%(hostname)s:%(port)s/principals/%(type)s/%(name)s</string>
+ <string>mailto:%(email)s</string>
+ <string>urn:uuid:%(guid)s</string>
+ </array>
+ </dict>
+ </dict>
+ </dict>
+ </dict>
+
+ </dict>
+ </dict>
+</plist>
+"""
+
def test_plist_errors(self):
def _doParse(plist, title):
service = OpenDirectoryService(node="/Search", dosetup=False)
- if service._parseXMLPlist("calendar.apple.com", "recordit", plist, "GUIDIFY"):
+ if service._parseServiceInfo("calendar.apple.com", "recordit", plist, "GUIDIFY"):
self.fail(msg="Plist parse should have failed: %s" % (title,))
plists = (
@@ -842,7 +964,7 @@
def test_goodplist(self):
service = OpenDirectoryService(node="/Search", dosetup=False)
- if not service._parseXMLPlist("calendar.apple.com", "recordit", PlistParse.plist_good, "GUIDIFY"):
+ if not service._parseServiceInfo("calendar.apple.com", "recordit", PlistParse.plist_good, "GUIDIFY"):
self.fail(msg="Plist parse should not have failed")
else:
# Verify that we extracted the proper items
@@ -851,7 +973,7 @@
def test_expandcuaddrs(self):
def _doTest(recordName, record, result, title):
service = OpenDirectoryService(node="/Search", dosetup=False)
- if not service._parseXMLPlist("calendar.apple.com", recordName, PlistParse.plist_good, "GUIDIFY"):
+ if not service._parseServiceInfo("calendar.apple.com", recordName, PlistParse.plist_good, "GUIDIFY"):
self.fail(msg="Plist parse should not have failed: %s" % (recordName,))
else:
expanded = service._getCalendarUserAddresses(DirectoryService.recordType_users, recordName, record)
@@ -898,30 +1020,48 @@
class ODRecordsParse (twisted.trial.unittest.TestCase):
- record_good = ("computer1.apple.com", {
+ record_localod_good = ("computer1.apple.com", {
dsattributes.kDS1AttrGeneratedUID : "GUID1",
dsattributes.kDSNAttrRecordName : "computer1.apple.com",
'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/127.0.0.1",
})
- record_good_other = ("computer2.apple.com", {
+ record_localod_good_other = ("computer2.apple.com", {
dsattributes.kDS1AttrGeneratedUID : "GUID1",
dsattributes.kDSNAttrRecordName : "computer2.apple.com",
'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good_other,
dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/127.0.0.1",
})
- record_good_duplicate = ("computer3.apple.com", {
+ record_localod_duplicate = ("computer1", {
+ dsattributes.kDS1AttrGeneratedUID : "GUID1_bad",
+ dsattributes.kDSNAttrRecordName : "computer1",
+ 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_duplicate,
+ dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/127.0.0.1",
+ })
+ record_remoteod_good = ("computer3.apple.com", {
dsattributes.kDS1AttrGeneratedUID : "GUID2",
- dsattributes.kDSNAttrRecordName : "computer2.apple.com",
+ dsattributes.kDSNAttrRecordName : "computer3.apple.com",
'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/directory.apple.com",
})
- record_good_local_duplicate = ("ServiceInformation", {
+ record_remoteod_duplicate = ("computer3", {
+ dsattributes.kDS1AttrGeneratedUID : "GUID2",
+ dsattributes.kDSNAttrRecordName : "computer3",
+ 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_duplicate,
+ dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/directory.apple.com",
+ })
+ record_default_good = ("computer4.apple.com", {
dsattributes.kDS1AttrGeneratedUID : "GUID3",
- dsattributes.kDSNAttrRecordName : "computer2.apple.com",
+ dsattributes.kDSNAttrRecordName : "computer4.apple.com",
'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
dsattributes.kDSNAttrMetaNodeLocation : "/Local/Default",
})
+ record_default_duplicate = ("computer4", {
+ dsattributes.kDS1AttrGeneratedUID : "GUID3",
+ dsattributes.kDSNAttrRecordName : "computer4",
+ 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_duplicate,
+ dsattributes.kDSNAttrMetaNodeLocation : "/Local/Default",
+ })
def test_odrecords_error(self):
def _doParseRecords(recordlist, title):
@@ -935,7 +1075,7 @@
records = (
({}, "no records found"),
({
- ODRecordsParse.record_good_other[0] : ODRecordsParse.record_good_other[1],
+ ODRecordsParse.record_localod_good_other[0] : ODRecordsParse.record_localod_good_other[1],
}, "non-matching record found"),
)
@@ -952,11 +1092,11 @@
records = (
({
- ODRecordsParse.record_good[0] : ODRecordsParse.record_good[1],
+ ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
}, "single good plist"),
({
- ODRecordsParse.record_good[0] : ODRecordsParse.record_good[1],
- ODRecordsParse.record_good_other[0] : ODRecordsParse.record_good_other[1],
+ ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
+ ODRecordsParse.record_localod_good_other[0] : ODRecordsParse.record_localod_good_other[1],
}, "multiple plists"),
)
@@ -973,23 +1113,50 @@
"Got wrong guid, %s: Expected %s not %s" % (title, guid, gotGuid))
records = (
- ({ODRecordsParse.record_good_other[0] : ODRecordsParse.record_good_other[1],
- ODRecordsParse.record_good_duplicate[0] : ODRecordsParse.record_good_duplicate[1],
- ODRecordsParse.record_good_local_duplicate[0] :
- ODRecordsParse.record_good_local_duplicate[1]},
+ ({ODRecordsParse.record_remoteod_good[0] : ODRecordsParse.record_remoteod_good[1],
+ ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
+ ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1]},
"Remote Record Preferred", "GUID2"),
- ({ODRecordsParse.record_good[0] : ODRecordsParse.record_good[1],
- ODRecordsParse.record_good_local_duplicate[0] :
- ODRecordsParse.record_good_local_duplicate[1]},
+ ({ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
+ ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1]},
"Local OD Preferred", "GUID1"),
- ({ODRecordsParse.record_good_local_duplicate[0] :
- ODRecordsParse.record_good_local_duplicate[1]},
+ ({ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1]},
"Local Node Preferred", "GUID3"),
)
for recordlist, title, guid in records:
_doParseRecords(recordlist, title, guid)
+ def test_odrecords_duplicates(self):
+ def _doParseRecords(recordlist, title, items):
+ service = OpenDirectoryService(node="/Search", dosetup=False)
+ try:
+ service._parseComputersRecords(recordlist, "calendar.apple.com")
+ except OpenDirectoryInitError, ex:
+ for item in items:
+ if item not in str(ex):
+ self.fail(msg="Record parse should have failed: \"%s\" with error: %s containing %s" % (title, ex, item))
+ else:
+ self.fail(msg="Record parse should have failed: \"%s\"" % (title, ))
+
+ records = (
+ ({ODRecordsParse.record_remoteod_good[0] : ODRecordsParse.record_remoteod_good[1],
+ ODRecordsParse.record_remoteod_duplicate[0] : ODRecordsParse.record_remoteod_duplicate[1],
+ ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
+ ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1]},
+ "Remote Record Duplicated", ("computer3.apple.com", "computer3",)),
+ ({ODRecordsParse.record_localod_good[0] : ODRecordsParse.record_localod_good[1],
+ ODRecordsParse.record_localod_duplicate[0] : ODRecordsParse.record_localod_duplicate[1],
+ ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1]},
+ "Local OD Duplicated", ("computer1.apple.com", "computer1",)),
+ ({ODRecordsParse.record_default_good[0] : ODRecordsParse.record_default_good[1],
+ ODRecordsParse.record_default_duplicate[0] : ODRecordsParse.record_default_duplicate[1]},
+ "Local Node Duplicated", ("computer4.apple.com", "computer4",)),
+ )
+
+ for recordlist, title, items in records:
+ _doParseRecords(recordlist, title, items)
+
class ODResourceInfoParse (twisted.trial.unittest.TestCase):
plist_good_false = """<?xml version="1.0" encoding="UTF-8"?>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070925/2561b36f/attachment.html
More information about the calendarserver-changes
mailing list