[CalendarServer-changes] [10619] CalendarServer/trunk/twext/who
source_changes at macosforge.org
source_changes at macosforge.org
Fri Feb 1 12:53:29 PST 2013
Revision: 10619
http://trac.calendarserver.org//changeset/10619
Author: wsanchez at apple.com
Date: 2013-02-01 12:53:29 -0800 (Fri, 01 Feb 2013)
Log Message:
-----------
Expand base XML config with more records, add groups.
Implement membership.
Modified Paths:
--------------
CalendarServer/trunk/twext/who/directory.py
CalendarServer/trunk/twext/who/idirectory.py
CalendarServer/trunk/twext/who/test/test_xml.py
CalendarServer/trunk/twext/who/xml.py
Modified: CalendarServer/trunk/twext/who/directory.py
===================================================================
--- CalendarServer/trunk/twext/who/directory.py 2013-02-01 19:01:54 UTC (rev 10618)
+++ CalendarServer/trunk/twext/who/directory.py 2013-02-01 20:53:29 UTC (rev 10619)
@@ -187,7 +187,13 @@
raise AttributeError(name)
+ def members(self):
+ if self.recordType == RecordType.group:
+ raise NotImplementedError()
+ return succeed(())
+
+
def uniqueResult(values):
result = None
for value in values:
Modified: CalendarServer/trunk/twext/who/idirectory.py
===================================================================
--- CalendarServer/trunk/twext/who/idirectory.py 2013-02-01 19:01:54 UTC (rev 10618)
+++ CalendarServer/trunk/twext/who/idirectory.py 2013-02-01 20:53:29 UTC (rev 10619)
@@ -178,42 +178,42 @@
"""
Find records that have the given L{FieldName} with the given
value.
- @return: an iterable of L{IDirectoryRecord}s.
+ @return: a deferred iterable of L{IDirectoryRecord}s.
"""
def recordWithUID(uid):
"""
Find the record that has the given L{FieldName.uid}.
- @return: an iterable of L{IDirectoryRecord}s, or C{None} if
- there is no such record.
+ @return: a deferred iterable of L{IDirectoryRecord}s, or
+ C{None} if there is no such record.
"""
def recordWithGUID(guid):
"""
Find the record that has the given L{FieldName.guid}.
- @return: an iterable of L{IDirectoryRecord}s, or C{None} if
- there is no such record.
+ @return: a deferred iterable of L{IDirectoryRecord}s, or
+ C{None} if there is no such record.
"""
def recordsWithRecordType(recordType):
"""
Find the records that have the given L{RecordType}.
- @return: an iterable of L{IDirectoryRecord}s.
+ @return: a deferred iterable of L{IDirectoryRecord}s.
"""
def recordWithShortName(recordType, shortName):
"""
Find the record that has the given L{RecordType} and
L{FieldName.shortName}.
- @return: an iterable of L{IDirectoryRecord}s, or C{None} if
- there is no such record.
+ @return: a deferred iterable of L{IDirectoryRecord}s, or
+ C{None} if there is no such record.
"""
def recordsWithEmailAddress(emailAddress):
"""
Find the records that have the given L{FieldName.emailAddress}.
- @return: an iterable of L{IDirectoryRecord}s, or C{None} if
- there is no such record.
+ @return: a deferred iterable of L{IDirectoryRecord}s, or
+ C{None} if there is no such record.
"""
@@ -226,3 +226,11 @@
"""
service = Attribute("The L{IDirectoryService} this record exists in.")
fields = Attribute("A dictionary with L{FieldName} keys and text values.")
+
+ def members():
+ """
+ Find the records that are members of this group. Only direct
+ members are included; members of members are not expanded.
+ @return: an iterable of L{IDirectoryRecord}s which are direct
+ members of this group.
+ """
Modified: CalendarServer/trunk/twext/who/test/test_xml.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_xml.py 2013-02-01 19:01:54 UTC (rev 10618)
+++ CalendarServer/trunk/twext/who/test/test_xml.py 2013-02-01 20:53:29 UTC (rev 10619)
@@ -30,40 +30,113 @@
xmlRealmName = "Test Realm"
+testXMLConfig = """<?xml version="1.0" encoding="utf-8"?>
-
-class BaseTest(object):
- def _testService(self):
- if not hasattr(self, "_service"):
- filePath = FilePath(self.mktemp())
-
- filePath.setContent(
- """<?xml version="1.0" encoding="utf-8"?>
-
<directory realm="xyzzy">
<record type="user">
- <uid>wsanchez</uid>
+ <uid>__wsanchez__</uid>
<short-name>wsanchez</short-name>
<short-name>wilfredo_sanchez</short-name>
<full-name>Wilfredo Sanchez</full-name>
<password>zehcnasw</password>
- <email>wsanchez at calendarserver.org</email>
- <email>wsanchez at example.com</email>
+ <email>wsanchez at bitbucket.calendarserver.org</email>
+ <email>wsanchez at devnull.twistedmatrix.com</email>
</record>
<record type="user">
- <uid>glyph</uid>
+ <uid>__glyph__</uid>
<short-name>glyph</short-name>
<full-name>Glyph Lefkowitz</full-name>
<password>hpylg</password>
- <email>glyph at calendarserver.org</email>
+ <email>glyph at bitbucket.calendarserver.org</email>
+ <email>glyph at devnull.twistedmatrix.com</email>
</record>
+ <record type="user">
+ <uid>__sagen__</uid>
+ <short-name>sagen</short-name>
+ <full-name>Morgen Sagen</full-name>
+ <password>negas</password>
+ <email>sagen at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__cdaboo__</uid>
+ <short-name>cdaboo</short-name>
+ <full-name>Cyrus Daboo</full-name>
+ <password>suryc</password>
+ <email>cdaboo at bitbucket.calendarserver.org</email>
+ </record>
+
+ <record type="user">
+ <uid>__dre__</uid>
+ <short-name>dre</short-name>
+ <full-name>Andre LaBranche</full-name>
+ <password>erd</password>
+ <email>dre at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__exarkun__</uid>
+ <short-name>exarkun</short-name>
+ <full-name>Jean-Paul Calderone</full-name>
+ <password>nucraxe</password>
+ <email>exarkun at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__dreid__</uid>
+ <short-name>dreid</short-name>
+ <full-name>David Reid</full-name>
+ <password>dierd</password>
+ <email>dreid at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__joe__</uid>
+ <short-name>joe</short-name>
+ <full-name>Joe Schmoe</full-name>
+ <password>eoj</password>
+ <email>joe at example.com</email>
+ </record>
+
+ <record type="group">
+ <uid>__calendar-dev__</uid>
+ <short-name>calendar-dev</short-name>
+ <full-name>Calendar Server developers</full-name>
+ <email>dev at bitbucket.calendarserver.org</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__sagen__</member-uid>
+ <member-uid>__cdaboo__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
+ <record type="group">
+ <uid>__twisted__</uid>
+ <short-name>twisted</short-name>
+ <full-name>Twisted Matrix Laboratories</full-name>
+ <email>hack at devnull.twistedmatrix.com</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__exarkun__</member-uid>
+ <member-uid>__dreid__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
</directory>
"""
- )
+
+
+class BaseTest(object):
+ def _testService(self):
+ if not hasattr(self, "_service"):
+ filePath = FilePath(self.mktemp())
+ filePath.setContent(testXMLConfig)
self._service = DirectoryService(filePath)
return self._service
@@ -73,38 +146,87 @@
@inlineCallbacks
def test_recordWithUID(self):
service = self._testService()
- record = (yield service.recordWithUID("wsanchez"))
- self.assertEquals(record.uid, "wsanchez")
+ record = (yield service.recordWithUID("__wsanchez__"))
+ self.assertEquals(record.uid, "__wsanchez__")
@inlineCallbacks
def test_recordWithGUID(self):
service = self._testService()
- record = (yield service.recordWithGUID("wsanchez"))
+ record = (yield service.recordWithGUID("6C495FCD-7E78-4D5C-AA66-BC890AD04C9D"))
self.assertEquals(record, None)
@inlineCallbacks
def test_recordsWithRecordType(self):
service = self._testService()
+
records = (yield service.recordsWithRecordType(RecordType.user))
self.assertEquals(
set((record.uid for record in records)),
- set(("wsanchez", "glyph")),
+ set((
+ "__wsanchez__",
+ "__glyph__",
+ "__sagen__",
+ "__cdaboo__",
+ "__dre__",
+ "__exarkun__",
+ "__dreid__",
+ "__joe__",
+ )),
)
+ records = (yield service.recordsWithRecordType(RecordType.group))
+ self.assertEquals(
+ set((record.uid for record in records)),
+ set((
+ "__calendar-dev__",
+ "__twisted__",
+ ))
+ )
+
@inlineCallbacks
def test_recordWithShortName(self):
service = self._testService()
+
record = (yield service.recordWithShortName(RecordType.user, "wsanchez"))
- self.assertEquals(record.uid, "wsanchez")
+ self.assertEquals(record.uid, "__wsanchez__")
+ record = (yield service.recordWithShortName(RecordType.user, "wilfredo_sanchez"))
+ self.assertEquals(record.uid, "__wsanchez__")
+
@inlineCallbacks
def test_recordsWithEmailAddress(self):
service = self._testService()
- records = (yield service.recordsWithEmailAddress("wsanchez at example.com"))
+
+ records = (yield service.recordsWithEmailAddress("wsanchez at bitbucket.calendarserver.org"))
self.assertEquals(
set((record.uid for record in records)),
- set(("wsanchez",)),
+ set(("__wsanchez__",)),
)
+
+ records = (yield service.recordsWithEmailAddress("wsanchez at devnull.twistedmatrix.com"))
+ self.assertEquals(
+ set((record.uid for record in records)),
+ set(("__wsanchez__",)),
+ )
+
+ records = (yield service.recordsWithEmailAddress("shared at example.com"))
+ self.assertEquals(
+ set((record.uid for record in records)),
+ set(("__sagen__", "__dre__")),
+ )
+
+
+
+class DirectoryRecordTest(BaseTest, test_directory.DirectoryRecordTest):
+ @inlineCallbacks
+ def test_members(self):
+ service = self._testService()
+
+ wsanchez = (yield service.recordWithUID("__wsanchez__"))
+ members = (yield wsanchez.members())
+ self.assertEquals(set(members), set())
+
+ # FIXME: GROUP
Modified: CalendarServer/trunk/twext/who/xml.py
===================================================================
--- CalendarServer/trunk/twext/who/xml.py 2013-02-01 19:01:54 UTC (rev 10618)
+++ CalendarServer/trunk/twext/who/xml.py 2013-02-01 20:53:29 UTC (rev 10619)
@@ -28,22 +28,33 @@
from xml.etree.ElementTree import parse as parseXML
from xml.etree.ElementTree import ParseError as XMLParseError
-from twisted.python.constants import Values, ValueConstant
+from twisted.python.constants import Values, ValueConstant, NamedConstant
from twisted.internet.defer import succeed, inlineCallbacks, returnValue
from twext.who.idirectory import DirectoryServiceError
-from twext.who.idirectory import RecordType, FieldName
+from twext.who.idirectory import RecordType, FieldName as BaseFieldName
from twext.who.idirectory import MatchType
from twext.who.idirectory import DirectoryQueryMatchExpression
from twext.who.directory import DirectoryService as BaseDirectoryService
-from twext.who.directory import DirectoryRecord
+from twext.who.directory import DirectoryRecord as BaseDirectoryRecord
##
-# XML Constants
+# Data type extentions
##
+class FieldName (BaseFieldName):
+ memberUIDs = NamedConstant()
+ memberUIDs.description = "member UIDs"
+ memberUIDs.multiValue = True
+
+
+
+##
+# XML constants
+##
+
class Element(Values):
directory = ValueConstant("directory")
record = ValueConstant("record")
@@ -53,7 +64,7 @@
fullName = ValueConstant("full-name")
emailAddress = ValueConstant("email")
password = ValueConstant("password")
- member = ValueConstant("member-uid")
+ memberUID = ValueConstant("member-uid")
uid.fieldName = FieldName.uid
guid.fieldName = FieldName.guid
@@ -93,6 +104,8 @@
XML directory service.
"""
+ FieldNameClass = FieldName
+
ElementClass = Element
AttributeClass = Attribute
ValueClass = Value
@@ -193,7 +206,7 @@
recordType = self.ValueClass.lookupByValue(recordTypeAttribute).recordType
except (ValueError, AttributeError):
unknownRecordTypes.add(recordTypeAttribute)
- break
+ continue
fields = {}
fields[FieldName.recordType] = recordType
@@ -203,6 +216,7 @@
fieldName = self.ElementClass.lookupByValue(fieldNode.tag).fieldName
except (ValueError, AttributeError):
unknownFieldNames.add(fieldNode.tag)
+ continue
value = fieldNode.text.encode("utf-8")
@@ -262,3 +276,18 @@
else:
returnValue((yield BaseDirectoryService.recordsFromExpression(self, expression)))
+
+
+
+class DirectoryRecord(BaseDirectoryRecord):
+ """
+ XML directory record
+ """
+ def members(self):
+ if self.recordType != RecordType.group:
+ return succeed(())
+
+ return succeed((
+ self.service.recordForUID(uid)
+ for uid in self.memberUIDs
+ ))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130201/9a683917/attachment-0001.html>
More information about the calendarserver-changes
mailing list