[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