[CalendarServer-changes] [1056]
CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/
directory
source_changes at macosforge.org
source_changes at macosforge.org
Wed Jan 17 11:35:05 PST 2007
Revision: 1056
http://trac.macosforge.org/projects/calendarserver/changeset/1056
Author: cdaboo at apple.com
Date: 2007-01-17 11:35:05 -0800 (Wed, 17 Jan 2007)
Log Message:
-----------
Do calendar user address template substitutions.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/appleopendirectory.py
CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/test/test_opendirectoryschema.py
Modified: CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/appleopendirectory.py 2007-01-17 16:27:13 UTC (rev 1055)
+++ CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/appleopendirectory.py 2007-01-17 19:35:05 UTC (rev 1056)
@@ -166,6 +166,24 @@
log.msg(msg)
raise OpenDirectoryInitError(msg)
+ # Get host name
+ hostname = vhosts[hostguid].get("hostname", None)
+ if not hostname:
+ msg = "Open Directory (node=%s) /Computers/%s record does not have any host name in its XMLPlist attribute value" % (self.realmName, self.computerRecordName,)
+ log.msg(msg)
+ raise OpenDirectoryInitError(msg)
+
+ # Get host details and create host templates
+ hostdetails = vhosts[hostguid].get("hostDetails", None)
+ if not hostdetails:
+ msg = "Open Directory (node=%s) /Computers/%s record does not have any host details in its XMLPlist attribute value" % (self.realmName, self.computerRecordName,)
+ log.msg(msg)
+ raise OpenDirectoryInitError(msg)
+ self.hostvariants = []
+ for key, value in hostdetails.iteritems():
+ self.hostvariants.append((key, hostname, value["port"],))
+ self.hostvariants = tuple(self.hostvariants)
+
# Look at the service data
serviceInfos = vhosts[hostguid].get("serviceInfo", None)
if not serviceInfos or not serviceInfos.has_key("calendar"):
@@ -189,11 +207,66 @@
raise OpenDirectoryInitError(msg)
# Grab the templates we need for calendar user addresses
- self.cuaddrtemplates = templates["calendarUserAddresses"]
+ self.cuaddrtemplates = tuple(templates["calendarUserAddresses"])
# Create the string we will use to match users with accounts on this server
self.servicetag = "%s:%s:calendar" % (recordguid, hostguid,)
+ def _templateExpandCalendarUserAddresses(self, recordType, recordName, record):
+ """
+ Expand this services calendar user address templates for the specified record.
+
+ @param recordName: a C{str} containing the record name being operated on.
+ @param record: a C{dict} containing the attributes retrieved from the directory.
+ @return: a C{set} of C{str} for each expanded calendar user address.
+ """
+
+ # Make a dict of the substitutions we can do for this record. The only record parameters
+ # we substitute are name, guid and email. Note that email is multi-valued so we have to
+ # create a list of dicts for each one of those.
+ name = recordName
+ type = recordType
+ guid = record.get(dsattributes.kDS1AttrGeneratedUID)
+ emails = record.get(dsattributes.kDSNAttrEMailAddress)
+ if emails is not None and isinstance(emails, str):
+ emails = [emails]
+
+ subslist = []
+ if emails:
+ for email in emails:
+ subslist.append({
+ "name" : name,
+ "type" : type,
+ "guid" : guid,
+ "email" : email,
+ })
+ else:
+ subslist.append({
+ "name" : name,
+ "type" : type,
+ "guid" : guid,
+ })
+
+ # Now do substitutions
+ result = set()
+ for template in self.cuaddrtemplates:
+ for scheme, hostname, port in self.hostvariants:
+ for subs in subslist:
+ # Add in host substitution values
+ subs.update({
+ "scheme" : scheme,
+ "hostname" : hostname,
+ "port" : port,
+ })
+
+ # Special check for no email address for this record
+ if (template.find("%(email)s") != -1) and not emails:
+ continue
+
+ result.add(template % subs)
+
+ return result
+
def setup(self):
self._lookupVHostRecord()
@@ -221,7 +294,7 @@
attrs = [
dsattributes.kDS1AttrGeneratedUID,
dsattributes.kDS1AttrDistinguishedName,
- dsattributes.kDSNAttrCalendarPrincipalURI,
+ dsattributes.kDSNAttrEMailAddress,
]
if recordType == DirectoryService.recordType_users:
@@ -251,15 +324,8 @@
continue
realName = value.get(dsattributes.kDS1AttrDistinguishedName)
- # FIXME: We get email address also
- # FIXME: In new schema, kDSNAttrCalendarPrincipalURI goes away
- cuaddrs = value.get(dsattributes.kDSNAttrCalendarPrincipalURI)
- cuaddrset = set()
- if cuaddrs is not None:
- if isinstance(cuaddrs, str):
- cuaddrset.add(cuaddrs)
- else:
- cuaddrset.update(cuaddrs)
+ # Get calendar user addresses expanded from service record templates.
+ cuaddrset = self._templateExpandCalendarUserAddresses(recordType, key, value)
if recordType == DirectoryService.recordType_groups:
memberGUIDs = value.get(dsattributes.kDSNAttrGroupMembers)
Modified: CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/test/test_opendirectoryschema.py
===================================================================
--- CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/test/test_opendirectoryschema.py 2007-01-17 16:27:13 UTC (rev 1055)
+++ CalendarServer/branches/users/cdaboo/od-schema-1044/twistedcaldav/directory/test/test_opendirectoryschema.py 2007-01-17 19:35:05 UTC (rev 1056)
@@ -19,9 +19,11 @@
try:
from twistedcaldav.directory.appleopendirectory import OpenDirectoryService
from twistedcaldav.directory.appleopendirectory import OpenDirectoryInitError
+ import dsattributes
except ImportError:
pass
else:
+ from twistedcaldav.directory.directory import DirectoryService
import twisted.trial.unittest
class PlistParse (twisted.trial.unittest.TestCase):
@@ -316,7 +318,7 @@
<string>/principals/%(type)s/%(name)s</string>
<key>calendarUserAddresses</key>
<array>
- <string>%(principal URI)s</string>
+ <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>
@@ -330,6 +332,213 @@
</plist>
"""
+ plist_nohostname = """<?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>4F088107-51FD-4DE5-904D-2C0AD9C6C893</key>
+ <dict>
+ <key>hostname</key>
+ <string>foo.apple.com</string>
+
+ <key>hostDetails</key>
+ <dict>
+ <key>http</key>
+ <dict>
+ <key>port</key>
+ <string>80</string>
+ </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>
+ <string>YES</string>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/webcalendar</string>
+ </dict>
+ <key>wiki</key>
+ <dict>
+ <key>enabled</key>
+ <string>YES</string>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/wiki</string>
+ </dict>
+ <key>webMailingList</key>
+ <dict>
+ <key>enabled</key>
+ <true/>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/mailinglist</string>
+ </dict>
+ </dict>
+ </dict>
+
+ <key>C18C34AC-3D9E-403C-8A33-BFC303F3840E</key>
+ <dict>
+ <key>hostDetails</key>
+ <dict>
+ <key>http</key>
+ <dict>
+ <key>port</key>
+ <string>8008</string>
+ </dict>
+ <key>https</key>
+ <dict>
+ <key>port</key>
+ <string>8443</string>
+ </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>
+"""
+
+ plist_nohostdetails = """<?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>4F088107-51FD-4DE5-904D-2C0AD9C6C893</key>
+ <dict>
+ <key>hostname</key>
+ <string>foo.apple.com</string>
+
+ <key>hostDetails</key>
+ <dict>
+ <key>http</key>
+ <dict>
+ <key>port</key>
+ <string>80</string>
+ </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>
+ <string>YES</string>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/webcalendar</string>
+ </dict>
+ <key>wiki</key>
+ <dict>
+ <key>enabled</key>
+ <string>YES</string>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/wiki</string>
+ </dict>
+ <key>webMailingList</key>
+ <dict>
+ <key>enabled</key>
+ <true/>
+ <key>urlMask</key>
+ <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(groupname)s/mailinglist</string>
+ </dict>
+ </dict>
+ </dict>
+
+ <key>C18C34AC-3D9E-403C-8A33-BFC303F3840E</key>
+ <dict>
+ <key>hostname</key>
+ <string>calendar.apple.com</string>
+
+ <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>
+"""
+
plist_nocuaddrtemplates = """<?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">
@@ -534,7 +743,7 @@
<string>/principals/%(type)s/%(name)s</string>
<key>calendarUserAddresses</key>
<array>
- <string>%(principal URI)s</string>
+ <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>
@@ -562,6 +771,8 @@
(PlistParse.plist_nocalendarservice, "nocalendarservice"),
(PlistParse.plist_noserviceinfo, "noserviceinfo"),
(PlistParse.plist_disabledservice, "disabledservice"),
+ (PlistParse.plist_nohostname, "nohostname"),
+ (PlistParse.plist_nohostdetails, "nohostdetails"),
(PlistParse.plist_nocuaddrtemplates, "nocuaddrtemplates"),
)
for plist, title in plists:
@@ -573,6 +784,62 @@
# Verify that we extracted the proper items
self.assertEqual(service.servicetag, "GUIDIFY:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")
- self.assertEqual(service.cuaddrtemplates, ["%(principal URI)s", "mailto:%(email)s", "urn:uuid:%(guid)s"])
+ self.assertEqual(service.hostvariants, (("http", "calendar.apple.com", "8008"), ("https", "calendar.apple.com", "8443")))
+ self.assertEqual(service.cuaddrtemplates, ("%(scheme)s://%(hostname)s:%(port)s/principals/%(type)s/%(name)s", "mailto:%(email)s", "urn:uuid:%(guid)s"))
+
+ def test_expandcuaddrs(self):
+ def _doTest(recordName, record, result, title):
+ service = OpenDirectoryService(node="/Search", dosetup=False)
+ service._parseXMLPlist(PlistParse.plist_good, "GUIDIFY")
+ expanded = service._templateExpandCalendarUserAddresses(DirectoryService.recordType_users, recordName, record)
+
+ # Verify that we extracted the proper items
+ self.assertEqual(expanded, result, msg=title % (expanded, result,))
+ data = (
+ (
+ "user01",
+ {
+ dsattributes.kDS1AttrGeneratedUID: "GUID-USER-01",
+ dsattributes.kDSNAttrEMailAddress: "user01 at example.com",
+ },
+ set((
+ "http://calendar.apple.com:8008/principals/users/user01",
+ "https://calendar.apple.com:8443/principals/users/user01",
+ "mailto:user01 at example.com",
+ "urn:uuid:GUID-USER-01",
+ )),
+ "User with one email address, %s != %s",
+ ),
+ (
+ "user02",
+ {
+ dsattributes.kDS1AttrGeneratedUID: "GUID-USER-02",
+ dsattributes.kDSNAttrEMailAddress: ["user02 at example.com", "user02 at calendar.example.com"],
+ },
+ set((
+ "http://calendar.apple.com:8008/principals/users/user02",
+ "https://calendar.apple.com:8443/principals/users/user02",
+ "mailto:user02 at example.com",
+ "mailto:user02 at calendar.example.com",
+ "urn:uuid:GUID-USER-02",
+ )),
+ "User with multiple email addresses, %s != %s",
+ ),
+ (
+ "user03",
+ {
+ dsattributes.kDS1AttrGeneratedUID: "GUID-USER-03",
+ },
+ set((
+ "http://calendar.apple.com:8008/principals/users/user03",
+ "https://calendar.apple.com:8443/principals/users/user03",
+ "urn:uuid:GUID-USER-03",
+ )),
+ "User with no email addresses, %s != %s",
+ ),
+ )
+
+ for recordName, record, result, title in data:
+ _doTest(recordName, record, result, title)
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070117/ab1ae51e/attachment.html
More information about the calendarserver-changes
mailing list