[CalendarServer-changes] [2190] CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav /directory
source_changes at macosforge.org
source_changes at macosforge.org
Tue Mar 4 14:42:35 PST 2008
Revision: 2190
http://trac.macosforge.org/projects/calendarserver/changeset/2190
Author: wsanchez at apple.com
Date: 2008-03-04 14:42:34 -0800 (Tue, 04 Mar 2008)
Log Message:
-----------
Pull up support for non-calendaring principals.
Modified Paths:
--------------
CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/appleopendirectory.py
CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/test/test_opendirectoryrecords.py
Modified: CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/appleopendirectory.py 2008-03-04 22:22:01 UTC (rev 2189)
+++ CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/appleopendirectory.py 2008-03-04 22:42:34 UTC (rev 2190)
@@ -12,8 +12,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-# DRI: Wilfredo Sanchez, wsanchez at apple.com
##
"""
@@ -148,7 +146,8 @@
for GUID in self._expandGroupMembership(
group.get(dsattributes.kDSNAttrGroupMembers, []),
group.get(dsattributes.kDSNAttrNestedGroups, []),
- processedGUIDs):
+ processedGUIDs
+ ):
yield GUID
def __cmp__(self, other):
@@ -186,13 +185,13 @@
dsattributes.kDS1AttrGeneratedUID,
dsattributes.kDSNAttrRecordName,
dsattributes.kDSNAttrMetaNodeLocation,
- 'dsAttrTypeNative:apple-serviceinfo',
+ "dsAttrTypeNative:apple-serviceinfo",
]
records = opendirectory.queryRecordsWithAttributes_list(
self.directory,
dsquery.match(
- 'dsAttrTypeNative:apple-serviceinfo',
+ "dsAttrTypeNative:apple-serviceinfo",
vhostname,
dsattributes.eDSContains,
).generate(),
@@ -241,7 +240,7 @@
recordlocation = "%s/Computers/%s" % (record[dsattributes.kDSNAttrMetaNodeLocation], recordname)
# First check for apple-serviceinfo attribute
- plist = record.get('dsAttrTypeNative:apple-serviceinfo', None)
+ plist = record.get("dsAttrTypeNative:apple-serviceinfo", None)
if not plist:
return False
@@ -456,18 +455,47 @@
enabledForCalendaring = True
if self.requireComputerRecord:
- if not value.get(dsattributes.kDSNAttrServicesLocator):
- if recordType == DirectoryService.recordType_groups:
+ servicesLocators = value.get(dsattributes.kDSNAttrServicesLocator)
+
+ def allowForACLs():
+ return recordType in (
+ DirectoryService.recordType_users,
+ DirectoryService.recordType_groups,
+ )
+
+ def disableForCalendaring():
+ logging.debug(
+ "Record (%s) %s is not enabled for calendaring but may be used in ACLs"
+ % (recordType, recordShortName), system="OpenDirectoryService"
+ )
+
+ def invalidRecord():
+ logging.err(
+ "Directory (incorrectly) returned a record with no applicable "
+ "ServicesLocator attribute: (%s) %s"
+ % (recordType, recordShortName), system="OpenDirectoryService"
+ )
+
+ 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
- logging.debug(
- "Group %s is not enabled for calendaring but may be used in ACLs"
- % (recordShortName,), system="OpenDirectoryService"
- )
else:
- logging.err(
- "Directory (incorrectly) returned a record with no ServicesLocator attribute: %s"
- % (recordShortName,), system="OpenDirectoryService"
- )
+ invalidRecord()
continue
# Now get useful record info.
@@ -486,7 +514,7 @@
else:
calendarUserAddresses = ()
- # Special case for groups.
+ # Special case for groups, which have members.
if recordType == DirectoryService.recordType_groups:
memberGUIDs = value.get(dsattributes.kDSNAttrGroupMembers)
if memberGUIDs is None:
@@ -525,9 +553,6 @@
proxyGUIDs = proxyGUIDs,
)
- del recordShortName
- del recordGUID
-
def disableRecord(record):
logging.warn("Record disabled due to conflict: %s" % (record,), system="OpenDirectoryService")
@@ -653,10 +678,13 @@
query = dsquery.expression(dsquery.expression.OR, guidQueries)
#
- # For groups, we'll load all entries, even if they don't
- # have a services locator for this server.
+ # 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_groups:
+ elif (
+ recordType != DirectoryService.recordType_users and
+ recordType != DirectoryService.recordType_groups
+ ):
tag_queries = []
for tag in self.servicetags:
@@ -807,31 +835,34 @@
except opendirectory.ODError, e:
logging.err("Open Directory (node=%s) error while performing basic authentication for user %s: %s"
% (self.service.realmName, self.shortName, e), system="OpenDirectoryService")
- return False
+
+ return False
+
elif isinstance(credentials, DigestedCredentials):
+ #
+ # We need a special format for the "challenge" and "response" strings passed into open directory, as it is
+ # picky about exactly what it receives.
+ #
try:
- # We need a special format for the "challenge" and "response" strings passed into open directory, as it is
- # picky about exactly what it receives.
-
- try:
- challenge = 'Digest realm="%(realm)s", nonce="%(nonce)s", algorithm=%(algorithm)s' % credentials.fields
- response = (
- 'Digest username="%(username)s", '
- 'realm="%(realm)s", '
- 'nonce="%(nonce)s", '
- 'uri="%(uri)s", '
- 'response="%(response)s",'
- 'algorithm=%(algorithm)s'
- ) % credentials.fields
- except KeyError, e:
- logging.err(
- "Open Directory (node=%s) error while performing digest authentication for user %s: "
- "missing digest response field: %s in: %s"
- % (self.service.realmName, self.shortName, e, credentials.fields),
- system="OpenDirectoryService"
- )
- return False
+ challenge = 'Digest realm="%(realm)s", nonce="%(nonce)s", algorithm=%(algorithm)s' % credentials.fields
+ response = (
+ 'Digest username="%(username)s", '
+ 'realm="%(realm)s", '
+ 'nonce="%(nonce)s", '
+ 'uri="%(uri)s", '
+ 'response="%(response)s",'
+ 'algorithm=%(algorithm)s'
+ ) % credentials.fields
+ except KeyError, e:
+ logging.err(
+ "Open Directory (node=%s) error while performing digest authentication for user %s: "
+ "missing digest response field: %s in: %s"
+ % (self.service.realmName, self.shortName, e, credentials.fields),
+ system="OpenDirectoryService"
+ )
+ return False
+ try:
if self.digestcache[credentials.fields["uri"]] == response:
return True
except (AttributeError, KeyError):
@@ -861,6 +892,8 @@
)
return False
+ return False
+
return super(OpenDirectoryRecord, self).verifyCredentials(credentials)
class OpenDirectoryInitError(DirectoryError):
Modified: CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/test/test_opendirectoryrecords.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/test/test_opendirectoryrecords.py 2008-03-04 22:22:01 UTC (rev 2189)
+++ CalendarServer/branches/release/CalendarServer-1.2-dev/twistedcaldav/directory/test/test_opendirectoryrecords.py 2008-03-04 22:42:34 UTC (rev 2190)
@@ -12,8 +12,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-# DRI: Wilfredo Sanchez, wsanchez at apple.com
##
import twisted.trial.unittest
@@ -48,6 +46,7 @@
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:
@@ -63,6 +62,17 @@
self.assertTrue(len(missing) == 0, msg="Directory records not found: %s" % (missing,))
self.assertTrue(len(extras) == 0, msg="Directory records not expected: %s" % (extras,))
+ def _verifyRecordsCheckEnabled(self, recordType, expected, enabled):
+ expected = set(expected)
+ found = set([item for item in self._service._records[recordType]["records"].iterkeys()
+ if self._service._records[recordType]["records"][item].enabledForCalendaring == enabled])
+
+ missing = expected.difference(found)
+ extras = found.difference(expected)
+
+ self.assertTrue(len(missing) == 0, msg="Directory records not found: %s" % (missing,))
+ self.assertTrue(len(extras) == 0, msg="Directory records not expected: %s" % (extras,))
+
def _verifyDisabledRecords(self, recordType, expectedNames, expectedGUIDs):
def check(disabledType, expected):
expected = set(expected)
@@ -114,6 +124,51 @@
self._verifyRecords(DirectoryService.recordType_locations, ("location01", "location02"))
self._verifyDisabledRecords(DirectoryService.recordType_locations, (), ())
+ def test_normal_disabledusers(self):
+ self._service.fakerecords = {
+ DirectoryService.recordType_users: [
+ fakeODRecord("User 01"),
+ fakeODRecord("User 02"),
+ fakeODRecord("User 03", addLocator=False),
+ fakeODRecord("User 04", addLocator=False),
+ ],
+ DirectoryService.recordType_groups: [
+ fakeODRecord("Group 01"),
+ fakeODRecord("Group 02"),
+ fakeODRecord("Group 03", addLocator=False),
+ fakeODRecord("Group 04", addLocator=False),
+ ],
+ DirectoryService.recordType_resources: [
+ fakeODRecord("Resource 01"),
+ fakeODRecord("Resource 02"),
+ fakeODRecord("Resource 03", addLocator=False),
+ fakeODRecord("Resource 04", addLocator=False),
+ ],
+ DirectoryService.recordType_locations: [
+ fakeODRecord("Location 01"),
+ fakeODRecord("Location 02"),
+ fakeODRecord("Location 03", addLocator=False),
+ fakeODRecord("Location 04", addLocator=False),
+ ],
+ }
+
+ self._service.reloadCache(DirectoryService.recordType_users)
+ self._service.reloadCache(DirectoryService.recordType_groups)
+ self._service.reloadCache(DirectoryService.recordType_resources)
+ self._service.reloadCache(DirectoryService.recordType_locations)
+
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_users, ("user01", "user02"), True)
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_users, ("user03", "user04"), False)
+
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_groups, ("group01", "group02"), True)
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_groups, ("group03", "group04"), False)
+
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_resources, ("resource01", "resource02"), True)
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_resources, (), False)
+
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_locations, ("location01", "location02"), True)
+ self._verifyRecordsCheckEnabled(DirectoryService.recordType_locations, (), False)
+
def test_normalCacheMiss(self):
self._service.fakerecords = {
DirectoryService.recordType_users: [
@@ -245,7 +300,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):
+def fakeODRecord(fullName, shortName=None, guid=None, email=None, addLocator=True):
if shortName is None:
shortName = shortNameForFullName(fullName)
@@ -257,16 +312,18 @@
if email is None:
email = "%s at example.com" % (shortName,)
- return [
- shortName, {
- dsattributes.kDS1AttrDistinguishedName: fullName,
- dsattributes.kDS1AttrGeneratedUID: guid,
- dsattributes.kDSNAttrEMailAddress: email,
- dsattributes.kDSNAttrServicesLocator: "FE588D50-0514-4DF9-BCB5-8ECA5F3DA274:030572AE-ABEC-4E0F-83C9-FCA304769E5F:calendar",
- dsattributes.kDSNAttrMetaNodeLocation: "/LDAPv3/127.0.0.1",
- }
- ]
+ attrs = {
+ dsattributes.kDS1AttrDistinguishedName: fullName,
+ dsattributes.kDS1AttrGeneratedUID: guid,
+ dsattributes.kDSNAttrEMailAddress: email,
+ 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):
return fullName.lower().replace(" ", "")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080304/0a3e4f3a/attachment-0001.html
More information about the calendarserver-changes
mailing list