[CalendarServer-changes] [3098] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Oct 1 18:09:19 PDT 2008
Revision: 3098
http://trac.macosforge.org/projects/calendarserver/changeset/3098
Author: cdaboo at apple.com
Date: 2008-10-01 18:09:19 -0700 (Wed, 01 Oct 2008)
Log Message:
-----------
Merged byebye-serviceslocator to trunk, with some minor changes to config options.
Modified Paths:
--------------
CalendarServer/trunk/conf/caldavd-test.plist
CalendarServer/trunk/conf/caldavd.plist
CalendarServer/trunk/twistedcaldav/config.py
CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py
CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryschema.py
CalendarServer/trunk/twistedcaldav/test/test_config.py
CalendarServer/trunk/twistedcaldav/test/test_tap.py
Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/conf/caldavd-test.plist 2008-10-02 01:09:19 UTC (rev 3098)
@@ -120,8 +120,10 @@
<dict>
<key>node</key>
<string>/Search</string>
- <key>requireComputerRecord</key>
- <true/>
+ <key>restrictEnabledRecords</key>
+ <false/>
+ <key>restrictToGroup</key>
+ <string></string>
</dict>
</dict>
-->
Modified: CalendarServer/trunk/conf/caldavd.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd.plist 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/conf/caldavd.plist 2008-10-02 01:09:19 UTC (rev 3098)
@@ -123,8 +123,10 @@
<dict>
<key>node</key>
<string>/Search</string>
- <key>requireComputerRecord</key>
- <true/>
+ <key>restrictEnabledRecords</key>
+ <false/>
+ <key>restrictToGroup</key>
+ <string></string>
</dict>
</dict>
Modified: CalendarServer/trunk/twistedcaldav/config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/config.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/config.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -35,7 +35,8 @@
},
"twistedcaldav.directory.appleopendirectory.OpenDirectoryService": {
"node": "/Search",
- "requireComputerRecord": True,
+ "restrictEnabledRecords": False,
+ "restrictToGroup": "",
"cacheTimeout": 30,
},
}
Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from uuid import UUID
"""
Apple Open Directory directory service implementation.
@@ -25,7 +26,6 @@
import itertools
import sys
-import os
from random import random
import opendirectory
@@ -37,15 +37,11 @@
from twisted.cred.credentials import UsernamePassword
from twisted.web2.auth.digest import DigestedCredentials
-from twistedcaldav.config import config
from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
-from plistlib import readPlistFromString, readPlist
+from plistlib import readPlistFromString
-serverPreferences = '/Library/Preferences/com.apple.servermgr_info.plist'
-saclGroup = 'com.apple.access_calendar'
-
class OpenDirectoryService(DirectoryService):
"""
Open Directory implementation of L{IDirectoryService}.
@@ -55,14 +51,23 @@
def __repr__(self):
return "<%s %r: %r>" % (self.__class__.__name__, self.realmName, self.node)
- def __init__(self, node="/Search", requireComputerRecord=True, dosetup=True, cacheTimeout=30):
+ def __init__(
+ self,
+ node="/Search",
+ restrictEnabledRecords=False,
+ restrictToGroup="",
+ dosetup=True,
+ cacheTimeout=30
+ ):
"""
@param node: an OpenDirectory node name to bind to.
- @param requireComputerRecord: C{True} if the directory schema is to be used to determine
+ @param restrictEnabledRecords: C{True} if a group in the directory is to be used to determine
which calendar users are enabled.
+ @param restrictToGroup: C{str} guid or name of group used to restrict enabled users.
@param dosetup: if C{True} then the directory records are initialized,
if C{False} they are not.
This should only be set to C{False} when doing unit tests.
+ @param cacheTimeout: C{int} number of minutes before cache is invalidated.
"""
try:
directory = opendirectory.odInit(node)
@@ -73,36 +78,41 @@
self.realmName = node
self.directory = directory
self.node = node
- self.requireComputerRecord = requireComputerRecord
- self.computerRecords = {}
- self.servicetags = set()
+ self.restrictEnabledRecords = restrictEnabledRecords
+ self.restrictToGroup = restrictToGroup
+ try:
+ UUID(self.restrictToGroup)
+ except:
+ self.restrictToGUID = False
+ else:
+ self.restrictToGUID = True
+ self.restrictedGUIDs = None
self.cacheTimeout = cacheTimeout
self._records = {}
self._delayedCalls = set()
- self.isWorkgroupServer = False
-
if dosetup:
- if self.requireComputerRecord:
- try:
- self._lookupVHostRecord()
- except Exception, e:
- self.log_error("Unable to locate virtual host record: %s" % (e,))
- raise
+ for recordType in self.recordTypes():
+ self.recordsForType(recordType)
- if os.path.exists(serverPreferences):
- serverInfo = readPlist(serverPreferences)
+ def __cmp__(self, other):
+ if not isinstance(other, DirectoryRecord):
+ return super(DirectoryRecord, self).__eq__(other)
- self.isWorkgroupServer = serverInfo.get('ServiceConfig', {}).get('IsWorkgroupServer', False)
+ for attr in ("directory", "node"):
+ diff = cmp(getattr(self, attr), getattr(other, attr))
+ if diff != 0:
+ return diff
+ return 0
- if self.isWorkgroupServer:
- self.log_info("Enabling Workgroup Server compatibility mode")
+ def __hash__(self):
+ h = hash(self.__class__)
+ for attr in ("directory", "node"):
+ h = (h + hash(getattr(self, attr))) & sys.maxint
+ return h
- for recordType in self.recordTypes():
- self.recordsForType(recordType)
+ def _expandGroupMembership(self, members, nestedGroups, processedGUIDs=None, returnGroups=False):
- def _expandGroupMembership(self, members, nestedGroups, processedGUIDs=None):
-
if processedGUIDs is None:
processedGUIDs = set()
@@ -148,192 +158,17 @@
group = result[0][1]
processedGUIDs.add(groupGUID)
+ if returnGroups:
+ yield groupGUID
for GUID in self._expandGroupMembership(
group.get(dsattributes.kDSNAttrGroupMembers, []),
group.get(dsattributes.kDSNAttrNestedGroups, []),
- processedGUIDs
+ processedGUIDs,
+ returnGroups,
):
yield GUID
- def __cmp__(self, other):
- if not isinstance(other, DirectoryRecord):
- return super(DirectoryRecord, self).__eq__(other)
-
- for attr in ("directory", "node"):
- diff = cmp(getattr(self, attr), getattr(other, attr))
- if diff != 0:
- return diff
- return 0
-
- def __hash__(self):
- h = hash(self.__class__)
- for attr in ("directory", "node"):
- h = (h + hash(getattr(self, attr))) & sys.maxint
- return h
-
- def _lookupVHostRecord(self):
- """
- Get the OD service record for this host.
- """
-
- # The server must have been configured with a virtual hostname.
- vhostname = config.ServerHostName
- if not vhostname:
- raise OpenDirectoryInitError(
- "There is no virtual hostname configured for the server for use with Open Directory (node=%s)"
- % (self.realmName,)
- )
-
- # Find a record in /Computers with an apple-serviceinfo attribute value equal to the virtual hostname
- # and return some useful attributes.
- attrs = [
- dsattributes.kDS1AttrGeneratedUID,
- dsattributes.kDSNAttrRecordName,
- dsattributes.kDSNAttrMetaNodeLocation,
- "dsAttrTypeNative:apple-serviceinfo",
- ]
-
- self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r)" % (
- self.directory,
- dsquery.match(
- "dsAttrTypeNative:apple-serviceinfo",
- vhostname,
- dsattributes.eDSContains,
- ).generate(),
- True, # case insentive for hostnames
- dsattributes.kDSStdRecordTypeComputers,
- attrs
- ))
- records = opendirectory.queryRecordsWithAttributes_list(
- self.directory,
- dsquery.match(
- "dsAttrTypeNative:apple-serviceinfo",
- vhostname,
- dsattributes.eDSContains,
- ).generate(),
- True, # case insentive for hostnames
- dsattributes.kDSStdRecordTypeComputers,
- attrs
- )
- self._parseComputersRecords(records, vhostname)
-
- def _parseComputersRecords(self, records, vhostname):
- # Must have some results
- if len(records) == 0:
- raise OpenDirectoryInitError(
- "Open Directory (node=%s) has no /Computers records with a virtual hostname: %s"
- % (self.realmName, vhostname)
- )
-
- # Now find all appropriate records and determine the enabled (only) service tags for each.
- for recordname, record in records:
- self._parseServiceInfo(vhostname, recordname, record)
-
- # Log all the matching records
- for key, value in self.computerRecords.iteritems():
- _ignore_recordname, enabled, servicetag = value
- self.log_info("Matched Directory record: %s with ServicesLocator: %s, state: %s" % (
- key,
- servicetag,
- {True:"enabled", False:"disabled"}[enabled]
- ))
-
- # Log all the enabled service tags - or generate an error if there are none
- if self.servicetags:
- for tag in self.servicetags:
- self.log_info("Enabled ServicesLocator: %s" % (tag,))
- else:
- raise OpenDirectoryInitError(
- "Open Directory (node=%s) no /Computers records with an enabled and valid "
- "calendar service were found matching virtual hostname: %s"
- % (self.realmName, vhostname)
- )
-
- def _parseServiceInfo(self, vhostname, recordname, record):
-
- # Extract some useful attributes
- recordguid = record[dsattributes.kDS1AttrGeneratedUID]
- recordlocation = "%s/Computers/%s" % (record[dsattributes.kDSNAttrMetaNodeLocation], recordname)
-
- # First check for apple-serviceinfo attribute
- plist = record.get("dsAttrTypeNative:apple-serviceinfo", None)
- if not plist:
- return False
-
- # Parse the plist and look for our special entry
- plist = readPlistFromString(plist)
- vhosts = plist.get("com.apple.macosxserver.virtualhosts", None)
- if not vhosts:
- self.log_error(
- "Open Directory (node=%s) %s record does not have a "
- "com.apple.macosxserver.virtualhosts in its apple-serviceinfo attribute value"
- % (self.realmName, recordlocation)
- )
- return False
-
- # Iterate over each vhost and find one that is a calendar service
- hostguid = None
- for key, value in vhosts.iteritems():
- serviceTypes = value.get("serviceType", None)
- if serviceTypes:
- for type in serviceTypes:
- if type == "calendar":
- hostguid = key
- break
-
- if not hostguid:
- # We can get false positives from the query - we ignore those.
- return False
-
- # Get host name
- hostname = vhosts[hostguid].get("hostname", None)
- if not hostname:
- self.log_error(
- "Open Directory (node=%s) %s record does not have "
- "any host name in its apple-serviceinfo attribute value"
- % (self.realmName, recordlocation)
- )
- return False
- if hostname != vhostname:
- # We can get false positives from the query - we ignore those.
- return False
-
- # Get host details. At this point we only check that it is present. We actually
- # ignore the details themselves (scheme/port) as we use our own config for that.
- hostdetails = vhosts[hostguid].get("hostDetails", None)
- if not hostdetails:
- self.log_error(
- "Open Directory (node=%s) %s record does not have "
- "any host details in its apple-serviceinfo attribute value"
- % (self.realmName, recordlocation)
- )
- return False
-
- # Look at the service data
- serviceInfos = vhosts[hostguid].get("serviceInfo", None)
- if not serviceInfos or not serviceInfos.has_key("calendar"):
- self.log_error(
- "Open Directory (node=%s) %s record does not have a "
- "calendar service in its apple-serviceinfo attribute value"
- % (self.realmName, recordlocation)
- )
- return False
- serviceInfo = serviceInfos["calendar"]
-
- # Check that this service is enabled
- enabled = serviceInfo.get("enabled", True)
-
- # Create the string we will use to match users with accounts on this server
- servicetag = "%s:%s:calendar" % (recordguid, hostguid)
-
- self.computerRecords[recordlocation] = (recordname, enabled, servicetag)
-
- if enabled:
- self.servicetags.add(servicetag)
-
- return True
-
def _calendarUserAddresses(self, recordType, recordName, record):
"""
Extract specific attributes from the directory record for use as calendar user address.
@@ -409,6 +244,10 @@
% (recordType, f)
)
+ # Reload the restricted access group details if reloading user records
+ if recordType == DirectoryService.recordType_users:
+ self.restrictedGUIDs = None
+
d = deferToThread(self.reloadCache, recordType)
d.addErrback(onError)
@@ -418,7 +257,7 @@
"""
@param recordType: a record type
@return: a dictionary containing all records for the given record
- type. Keys are short names and values are the cooresponding
+ type. Keys are short names and values are the corresponding
OpenDirectoryRecord for the given record type.
"""
return self._storage(recordType)["records"]
@@ -552,53 +391,9 @@
disabledNames = storage["disabled names"]
disabledGUIDs = storage["disabled guids"]
+ enabled_count = 0
for (recordShortName, value) in results:
- enabledForCalendaring = True
- if self.requireComputerRecord:
- servicesLocators = value.get(dsattributes.kDSNAttrServicesLocator)
-
- def allowForACLs():
- return recordType in (
- DirectoryService.recordType_users,
- DirectoryService.recordType_groups,
- )
-
- def disableForCalendaring():
- self.log_debug(
- "Record (%s) %s is not enabled for calendaring but may be used in ACLs"
- % (recordType, recordShortName)
- )
-
- def invalidRecord():
- self.log_error(
- "Directory (incorrectly) returned a record with no applicable "
- "ServicesLocator attribute: (%s) %s"
- % (recordType, recordShortName)
- )
-
- if servicesLocators:
- if type(servicesLocators) is str:
- servicesLocators = (servicesLocators,)
-
- for locator in servicesLocators:
- if locator in self.servicetags:
- break
- else:
- if allowForACLs():
- disableForCalendaring()
- enabledForCalendaring = False
- else:
- invalidRecord()
- continue
- else:
- if allowForACLs():
- disableForCalendaring()
- enabledForCalendaring = False
- else:
- invalidRecord()
- continue
-
# Now get useful record info.
recordGUID = value.get(dsattributes.kDS1AttrGeneratedUID)
recordFullName = value.get(dsattributes.kDS1AttrDistinguishedName)
@@ -612,6 +407,32 @@
% (recordType, recordShortName, recordNodeName))
continue
+ # Determine enabled state
+ enabledForCalendaring = True
+
+ if self.restrictEnabledRecords and self.restrictedGUIDs is not None:
+ enabledForCalendaring = recordGUID in self.restrictedGUIDs
+
+ if not enabledForCalendaring:
+ # Some records we want to keep even though they are not enabled for calendaring.
+ # Others we discard.
+ if recordType in (
+ DirectoryService.recordType_users,
+ DirectoryService.recordType_groups,
+ ):
+ self.log_debug(
+ "Record (%s) %s is not enabled for calendaring but may be used in ACLs"
+ % (recordType, recordShortName)
+ )
+ else:
+ self.log_debug(
+ "Record (%s) %s is not enabled for calendaring"
+ % (recordType, recordShortName)
+ )
+ continue
+ else:
+ enabled_count += 1
+
# Get calendar user addresses from directory record.
if enabledForCalendaring:
calendarUserAddresses = self._calendarUserAddresses(recordType, recordShortName, value)
@@ -702,6 +523,9 @@
if record.guid != existing_record.guid or record.shortName != existing_record.shortName:
disableRecord(existing_record)
disableRecord(record)
+
+ if existing_record.enabledForCalendaring:
+ enabled_count -= 1
if record.shortName not in disabledNames:
records[record.shortName] = guids[record.guid] = record
@@ -740,8 +564,8 @@
self._records[recordType] = storage
self.log_info(
- "Added %d records to %s OD record cache; expires in %d seconds"
- % (len(self._records[recordType]["guids"]), recordType, cacheTimeout)
+ "Added %d (%d enabled) records to %s OD record cache; expires in %d seconds"
+ % (len(self._records[recordType]["guids"]), enabled_count, recordType, cacheTimeout)
)
def _queryDirectory(self, recordType, shortName=None, guid=None):
@@ -751,11 +575,9 @@
dsattributes.kDS1AttrFirstName,
dsattributes.kDS1AttrLastName,
dsattributes.kDSNAttrEMailAddress,
- dsattributes.kDSNAttrServicesLocator,
dsattributes.kDSNAttrMetaNodeLocation,
]
- query = None
if recordType == DirectoryService.recordType_users:
listRecordType = dsattributes.kDSStdRecordTypeUsers
@@ -775,120 +597,70 @@
else:
raise UnknownRecordTypeError("Unknown Open Directory record type: %s" % (recordType))
- if self.requireComputerRecord:
- if self.isWorkgroupServer and recordType == DirectoryService.recordType_users:
- if shortName is None and guid is None:
- self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
- self.directory,
- dsattributes.kDSNAttrRecordName,
- saclGroup,
- dsattributes.eDSExact,
- False,
- dsattributes.kDSStdRecordTypeGroups,
- [dsattributes.kDSNAttrGroupMembers, dsattributes.kDSNAttrNestedGroups],
- ))
- results = opendirectory.queryRecordsWithAttribute_list(
- self.directory,
- dsattributes.kDSNAttrRecordName,
- saclGroup,
- dsattributes.eDSExact,
- False,
- dsattributes.kDSStdRecordTypeGroups,
- [dsattributes.kDSNAttrGroupMembers, dsattributes.kDSNAttrNestedGroups]
- )
+ # If restricting enabled records, then make sure the restricted group member
+ # details are loaded. Do nested group expansion and include the nested groups
+ # as enabled records too.
+ if self.restrictEnabledRecords and self.restrictedGUIDs is None:
- if len(results) == 1:
- members = results[0][1].get(dsattributes.kDSNAttrGroupMembers, [])
- nestedGroups = results[0][1].get(dsattributes.kDSNAttrNestedGroups, [])
- else:
- members = []
- nestedGroups = []
+ attributeToMatch = dsattributes.kDS1AttrGeneratedUID if self.restrictToGUID else dsattributes.kDSNAttrRecordName
+ valueToMatch = self.restrictToGroup
- guidQueries = []
+ self.log_debug("Doing restricted group membership check")
+ self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
+ self.directory,
+ attributeToMatch,
+ valueToMatch,
+ dsattributes.eDSExact,
+ False,
+ dsattributes.kDSStdRecordTypeGroups,
+ [dsattributes.kDSNAttrGroupMembers, dsattributes.kDSNAttrNestedGroups,],
+ ))
+ results = opendirectory.queryRecordsWithAttribute_list(
+ self.directory,
+ attributeToMatch,
+ valueToMatch,
+ dsattributes.eDSExact,
+ False,
+ dsattributes.kDSStdRecordTypeGroups,
+ [dsattributes.kDSNAttrGroupMembers, dsattributes.kDSNAttrNestedGroups,],
+ )
+
+ if len(results) == 1:
+ members = results[0][1].get(dsattributes.kDSNAttrGroupMembers, [])
+ nestedGroups = results[0][1].get(dsattributes.kDSNAttrNestedGroups, [])
+ else:
+ members = []
+ nestedGroups = []
- for GUID in self._expandGroupMembership(members, nestedGroups):
- guidQueries.append(
- dsquery.match(dsattributes.kDS1AttrGeneratedUID, GUID, dsattributes.eDSExact)
- )
+ self.restrictedGUIDs = set(self._expandGroupMembership(members, nestedGroups, returnGroups=True))
+ self.log_debug("Got %d restricted group members" % (len(self.restrictedGUIDs),))
- if not guidQueries:
- self.log_warn("No SACL enabled users found.")
- return ()
-
- query = dsquery.expression(dsquery.expression.OR, guidQueries)
-
- #
- # For users and groups, we'll load all entries, even if
- # they don't have a services locator for this server.
- #
- elif (
- recordType != DirectoryService.recordType_users and
- recordType != DirectoryService.recordType_groups
- ):
- tag_queries = []
-
- for tag in self.servicetags:
- tag_queries.append(dsquery.match(dsattributes.kDSNAttrServicesLocator, tag, dsattributes.eDSExact))
-
- if len(tag_queries) == 1:
- subquery = tag_queries[0]
- else:
- subquery = dsquery.expression(dsquery.expression.OR, tag_queries)
-
- if query is None:
- query = subquery
- else:
- query = dsquery.expression(dsquery.expression.AND, (subquery, query))
-
+ query = None
if shortName is not None:
- subquery = dsquery.match(dsattributes.kDSNAttrRecordName, shortName, dsattributes.eDSExact)
+ query = dsquery.match(dsattributes.kDSNAttrRecordName, shortName, dsattributes.eDSExact)
elif guid is not None:
- subquery = dsquery.match(dsattributes.kDS1AttrGeneratedUID, guid, dsattributes.eDSExact)
- else:
- subquery = None
+ query = dsquery.match(dsattributes.kDS1AttrGeneratedUID, guid, dsattributes.eDSExact)
- if subquery is not None:
- if query is None:
- query = subquery
- else:
- query = dsquery.expression(dsquery.expression.AND, (subquery, query))
-
try:
if query:
- if isinstance(query, dsquery.match):
- self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
- self.directory,
- query.attribute,
- query.value,
- query.matchType,
- False,
- listRecordType,
- attrs,
- ))
- results = opendirectory.queryRecordsWithAttribute_list(
- self.directory,
- query.attribute,
- query.value,
- query.matchType,
- False,
- listRecordType,
- attrs,
- )
- else:
- self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r)" % (
- self.directory,
- query.generate(),
- False,
- listRecordType,
- attrs,
- ))
- results = opendirectory.queryRecordsWithAttributes_list(
- self.directory,
- query.generate(),
- False,
- listRecordType,
- attrs,
- )
+ self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
+ self.directory,
+ query.attribute,
+ query.value,
+ query.matchType,
+ False,
+ listRecordType,
+ attrs,
+ ))
+ results = opendirectory.queryRecordsWithAttribute_list(
+ self.directory,
+ query.attribute,
+ query.value,
+ query.matchType,
+ False,
+ listRecordType,
+ attrs,
+ )
else:
self.log_debug("opendirectory.listAllRecordsWithAttributes_list(%r,%r,%r)" % (
self.directory,
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -15,6 +15,7 @@
##
import twisted.trial.unittest
+from uuid import uuid4
try:
from twistedcaldav.directory.appleopendirectory import OpenDirectoryService as RealOpenDirectoryService
@@ -46,7 +47,6 @@
def setUp(self):
super(ReloadCache, self).setUp()
self._service = OpenDirectoryService(node="/Search", dosetup=False)
- self._service.servicetags.add("FE588D50-0514-4DF9-BCB5-8ECA5F3DA274:030572AE-ABEC-4E0F-83C9-FCA304769E5F:calendar")
def tearDown(self):
for call in self._service._delayedCalls:
@@ -87,6 +87,27 @@
check("disabled names", expectedNames)
check("disabled guids", (guid.lower() for guid in expectedGUIDs))
+ def test_restrictionGroupName(self):
+ service = OpenDirectoryService(
+ node="/Search",
+ restrictEnabledRecords=True,
+ restrictToGroup="group_name",
+ dosetup=False)
+ self.assertTrue(service.restrictEnabledRecords)
+ self.assertEqual(service.restrictToGroup, "group_name")
+ self.assertFalse(service.restrictToGUID)
+
+ def test_restrictionGroupGUID(self):
+ guid = str(uuid4())
+ service = OpenDirectoryService(
+ node="/Search",
+ restrictEnabledRecords=True,
+ restrictToGroup=guid,
+ dosetup=False)
+ self.assertTrue(service.restrictEnabledRecords)
+ self.assertEqual(service.restrictToGroup, guid)
+ self.assertTrue(service.restrictToGUID)
+
def test_normal(self):
self._service.fakerecords = {
DirectoryService.recordType_users: [
@@ -125,33 +146,49 @@
self._verifyDisabledRecords(DirectoryService.recordType_locations, (), ())
def test_normal_disabledusers(self):
+
+ self._service.restrictEnabledRecords = True
+ self._service.restrictToGroup = "restrictedaccess"
+
self._service.fakerecords = {
DirectoryService.recordType_users: [
fakeODRecord("User 01"),
fakeODRecord("User 02"),
- fakeODRecord("User 03", addLocator=False),
- fakeODRecord("User 04", addLocator=False),
+ fakeODRecord("User 03"),
+ fakeODRecord("User 04"),
],
DirectoryService.recordType_groups: [
fakeODRecord("Group 01"),
fakeODRecord("Group 02"),
- fakeODRecord("Group 03", addLocator=False),
- fakeODRecord("Group 04", addLocator=False),
+ fakeODRecord("Group 03"),
+ fakeODRecord("Group 04"),
],
DirectoryService.recordType_resources: [
fakeODRecord("Resource 01"),
fakeODRecord("Resource 02"),
- fakeODRecord("Resource 03", addLocator=False),
- fakeODRecord("Resource 04", addLocator=False),
+ fakeODRecord("Resource 03"),
+ fakeODRecord("Resource 04"),
],
DirectoryService.recordType_locations: [
fakeODRecord("Location 01"),
fakeODRecord("Location 02"),
- fakeODRecord("Location 03", addLocator=False),
- fakeODRecord("Location 04", addLocator=False),
+ fakeODRecord("Location 03"),
+ fakeODRecord("Location 04"),
],
}
+ # Disable certain records
+ self._service.restrictedGUIDs = set((
+ self._service.fakerecords[DirectoryService.recordType_users][0][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_users][1][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_resources][0][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_resources][1][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_locations][0][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_locations][1][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_groups][0][1][dsattributes.kDS1AttrGeneratedUID],
+ self._service.fakerecords[DirectoryService.recordType_groups][1][1][dsattributes.kDS1AttrGeneratedUID],
+ ))
+
self._service.reloadCache(DirectoryService.recordType_users)
self._service.reloadCache(DirectoryService.recordType_groups)
self._service.reloadCache(DirectoryService.recordType_resources)
@@ -300,7 +337,7 @@
("EDB9EE55-31F2-4EA9-B5FB-D8AE2A8BA35E", "62368DDF-0C62-4C97-9A58-DE9FD46131A0", "D10F3EE0-5014-41D3-8488-3819D3EF3B2A"),
)
-def fakeODRecord(fullName, shortName=None, guid=None, email=None, addLocator=True):
+def fakeODRecord(fullName, shortName=None, guid=None, email=None):
if shortName is None:
shortName = shortNameForFullName(fullName)
@@ -319,9 +356,6 @@
dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1",
}
- if addLocator:
- attrs[dsattributes.kDSNAttrServicesLocator] = "FE588D50-0514-4DF9-BCB5-8ECA5F3DA274:030572AE-ABEC-4E0F-83C9-FCA304769E5F:calendar"
-
return [ shortName, attrs ]
def shortNameForFullName(fullName):
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryschema.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryschema.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryschema.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -16,1162 +16,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):
- """
- Test Open Directory service schema.
- """
-
- plist_nomacosxserver_key = """<?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>
- </dict>
-</plist>
-"""
-
- plist_nocalendarservice = """<?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>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>
- <integer>443</integer>
- </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>
-
- </dict>
- </dict>
-</plist>
-"""
-
- plist_noserviceinfo = """<?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>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>
- <integer>443</integer>
- </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>C18C34AC-3D9E-403C-8A33-BFC303F3840E</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>webCalendar</key>
- <dict>
- <key>enabled</key>
- <true/>
- <key>urlMask</key>
- <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/webcalendar</string>
- </dict>
- </dict>
- </dict>
-
- </dict>
- </dict>
-</plist>
-"""
-
- plist_disabledservice = """<?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>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>C18C34AC-3D9E-403C-8A33-BFC303F3840E</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>enabled</key>
- <false/>
- <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_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>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>C18C34AC-3D9E-403C-8A33-BFC303F3840E</key>
- <dict>
- <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>
-"""
-
- 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>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>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_good = """<?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>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>C18C34AC-3D9E-403C-8A33-BFC303F3840E</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>
-"""
-
- plist_good_other = """<?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>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>C18C34AC-3D9E-403C-8A33-BFC303F3840E</key>
- <dict>
- <key>hostname</key>
- <string>privatecalendar.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>
-"""
-
- 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._parseServiceInfo("calendar.apple.com", "recordit", {
- 'dsAttrTypeNative:apple-serviceinfo' : plist,
- dsattributes.kDS1AttrGeneratedUID: "GUIDIFY",
- dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1"}) and service.servicetags:
- self.fail(msg="Plist parse should have failed: %s" % (title,))
-
- plists = (
- (PlistParse.plist_nomacosxserver_key, "nomacosxserver_key"),
- (PlistParse.plist_nocalendarservice, "nocalendarservice"),
- (PlistParse.plist_noserviceinfo, "noserviceinfo"),
- (PlistParse.plist_disabledservice, "disabledservice"),
- (PlistParse.plist_nohostname, "nohostname"),
- (PlistParse.plist_nohostdetails, "nohostdetails"),
- )
- for plist, title in plists:
- _doParse(plist, title)
-
- def test_goodplist(self):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- if not service._parseServiceInfo("calendar.apple.com", "recordit", {
- 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
- dsattributes.kDS1AttrGeneratedUID: "GUIDIFY",
- dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1"}):
- self.fail(msg="Plist parse should not have failed")
- else:
- # Verify that we extracted the proper items
- self.assertEqual(service.servicetags.pop(), "GUIDIFY:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")
-
- def test_expandcuaddrs(self):
- def doTest(recordName, record, result, title):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- if not service._parseServiceInfo("calendar.apple.com", recordName, {
- 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
- dsattributes.kDS1AttrGeneratedUID: "GUIDIFY",
- dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1"}):
- self.fail(msg="Plist parse should not have failed: %s" % (recordName,))
- else:
- expanded = service._calendarUserAddresses(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((
- "mailto:user01 at example.com",
- )),
- "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((
- "mailto:user02 at example.com",
- "mailto:user02 at calendar.example.com",
- )),
- "User with multiple email addresses, %s != %s",
- ),
- (
- "user03",
- {
- dsattributes.kDS1AttrGeneratedUID: "GUID-USER-03",
- },
- set(()),
- "User with no email addresses, %s != %s",
- ),
- )
-
- for recordName, record, result, title in data:
- doTest(recordName, record, result, title)
-
- class ODRecordsParse (twisted.trial.unittest.TestCase):
-
- 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_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_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 : "computer3.apple.com",
- 'dsAttrTypeNative:apple-serviceinfo' : PlistParse.plist_good,
- dsattributes.kDSNAttrMetaNodeLocation : "/LDAPv3/directory.apple.com",
- })
- 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 : "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):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- try:
- service._parseComputersRecords(recordlist, "calendar.apple.com")
- self.fail(msg="Record parse should have failed: %s" % (title,))
- except OpenDirectoryInitError:
- pass
-
- records = (
- ((), "no records found"),
- ((
- (ODRecordsParse.record_localod_good_other[0], ODRecordsParse.record_localod_good_other[1]),
- ), "non-matching record found"),
- )
-
- for recordlist, title in records:
- _doParseRecords(recordlist, title)
-
- def test_odrecords_good(self):
- def _doParseRecords(recordlist, title):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- try:
- service._parseComputersRecords(recordlist, "calendar.apple.com")
- except OpenDirectoryInitError, ex:
- self.fail(msg="Record parse should not have failed: \"%s\" with error: %s" % (title, ex))
-
- records = (
- ((
- (ODRecordsParse.record_localod_good[0], ODRecordsParse.record_localod_good[1]),
- ), "single good plist"),
- ((
- (ODRecordsParse.record_localod_good[0], ODRecordsParse.record_localod_good[1]),
- (ODRecordsParse.record_localod_good_other[0], ODRecordsParse.record_localod_good_other[1]),
- ), "multiple plists"),
- )
-
- for recordlist, title in records:
- _doParseRecords(recordlist, title)
-
- def test_odrecords_multiple(self):
- def _doParseRecords(recordlist, title, tags):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- service._parseComputersRecords(recordlist, "calendar.apple.com")
-
- self.assertEquals(service.servicetags, set(tags),
- "Got wrong service tags: %s and %s" % (service.servicetags, set(tags),))
-
- records = (
- (((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])),
- "Three records",
- ("GUID2:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID1:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")),
- (((ODRecordsParse.record_localod_good[0], ODRecordsParse.record_localod_good[1]),
- (ODRecordsParse.record_default_good[0], ODRecordsParse.record_default_good[1])),
- "Two records",
- ("GUID1:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")),
- (((ODRecordsParse.record_default_good[0], ODRecordsParse.record_default_good[1]),),
- "One record",
- ("GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",)),
- )
-
- for recordlist, title, tags in records:
- _doParseRecords(recordlist, title, tags)
-
- def test_odrecords_duplicates(self):
- def _doParseRecords(recordlist, title, items, tags):
- service = OpenDirectoryService(node="/Search", dosetup=False)
- service._parseComputersRecords(recordlist, "calendar.apple.com")
- self.assertEquals(service.servicetags, set(tags))
-
- 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",),
- ("GUID2:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID2:1C8C34AC-3D9E-403C-8A33-FBC303F3840E:calendar",
- "GUID1:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")),
- (((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",),
- ("GUID1:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID1_bad:1C8C34AC-3D9E-403C-8A33-FBC303F3840E:calendar",
- "GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar")),
- (((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",),
- ("GUID3:C18C34AC-3D9E-403C-8A33-BFC303F3840E:calendar",
- "GUID3:1C8C34AC-3D9E-403C-8A33-FBC303F3840E:calendar")),
- )
-
- for recordlist, title, items, tags in records:
- _doParseRecords(recordlist, title, items, tags)
-
class ODResourceInfoParse (twisted.trial.unittest.TestCase):
plist_good_false = """<?xml version="1.0" encoding="UTF-8"?>
Modified: CalendarServer/trunk/twistedcaldav/test/test_config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_config.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/test/test_config.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -158,24 +158,28 @@
self.assertEquals(config.DirectoryService["type"], "twistedcaldav.directory.appleopendirectory.OpenDirectoryService")
self.assertNotIn("xmlFile", config.DirectoryService["params"])
self.assertEquals(config.DirectoryService["params"]["node"], "/Search")
- self.assertEquals(config.DirectoryService["params"]["requireComputerRecord"], True)
+ self.assertEquals(config.DirectoryService["params"]["restrictEnabledRecords"], False)
def testDirectoryService_newParam(self):
self.assertEquals(config.DirectoryService["type"], "twistedcaldav.directory.xmlfile.XMLDirectoryService")
self.assertEquals(config.DirectoryService["params"]["xmlFile"], "/etc/caldavd/accounts.xml")
config.update({"DirectoryService": {"type": "twistedcaldav.directory.appleopendirectory.OpenDirectoryService"}})
- config.update({"DirectoryService": {"params": {"requireComputerRecord": False}}})
+ config.update({"DirectoryService": {"params": {
+ "restrictEnabledRecords": True,
+ "restrictToGroup": "12345",
+ }}})
self.assertEquals(config.DirectoryService["type"], "twistedcaldav.directory.appleopendirectory.OpenDirectoryService")
self.assertEquals(config.DirectoryService["params"]["node"], "/Search")
- self.assertEquals(config.DirectoryService["params"]["requireComputerRecord"], False)
+ self.assertEquals(config.DirectoryService["params"]["restrictEnabledRecords"], True)
+ self.assertEquals(config.DirectoryService["params"]["restrictToGroup"], "12345")
def testDirectoryService_badParam(self):
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": {"requireComputerRecord": False}}})
+ 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/test/test_tap.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_tap.py 2008-10-01 18:40:28 UTC (rev 3097)
+++ CalendarServer/trunk/twistedcaldav/test/test_tap.py 2008-10-02 01:09:19 UTC (rev 3098)
@@ -158,7 +158,7 @@
a '/' seperated path. Such as '-o MultiProcess/ProcessCount=1'
"""
- argv = ['-o', 'MultiProcess/ProcessCount=102']
+ argv = ['-o', 'MultiProcess/ProcessCount=102', '-f', 'conf/caldavd.plist',]
self.config.parseOptions(argv)
self.assertEquals(config.MultiProcess['ProcessCount'], 102)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081001/189943da/attachment-0001.html
More information about the calendarserver-changes
mailing list