[CalendarServer-changes] [491] CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/ directory

source_changes at macosforge.org source_changes at macosforge.org
Thu Nov 16 13:30:47 PST 2006


Revision: 491
          http://trac.macosforge.org/projects/calendarserver/changeset/491
Author:   cdaboo at apple.com
Date:     2006-11-16 13:30:47 -0800 (Thu, 16 Nov 2006)

Log Message:
-----------
Refactor XML accounts parser into a separate module so that it can be used by other directory services.

Modified Paths:
--------------
    CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlfile.py

Added Paths:
-----------
    CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlaccountsparser.py

Added: CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlaccountsparser.py	                        (rev 0)
+++ CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlaccountsparser.py	2006-11-16 21:30:47 UTC (rev 491)
@@ -0,0 +1,186 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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: Cyrus Daboo, cdaboo at apple.com
+##
+
+
+"""
+XML based user/group/resource configuration file handling.
+"""
+
+__all__ = [
+    "XMLAccountsParser",
+]
+
+import xml.dom.minidom
+
+from twisted.python.filepath import FilePath
+
+from twistedcaldav.resource import CalDAVResource
+
+ELEMENT_ACCOUNTS    = "accounts"
+ELEMENT_USER        = "user"
+ELEMENT_GROUP       = "group"
+ELEMENT_RESOURCE    = "resource"
+
+ELEMENT_USERID      = "uid"
+ELEMENT_PASSWORD    = "pswd"
+ELEMENT_NAME        = "name"
+ELEMENT_MEMBERS     = "members"
+ELEMENT_CUADDR      = "cuaddr"
+ELEMENT_CANPROXY    = "canproxy"
+
+ATTRIBUTE_REPEAT    = "repeat"
+
+class XMLAccountsParser(object):
+    """
+    XML account configuration file parser.
+    """
+    def __repr__(self):
+        return "<%s %r>" % (self.__class__.__name__, self.xmlFile)
+
+    def __init__(self, xmlFile):
+        if type(xmlFile) is str:
+            xmlFile = FilePath(xmlFile)
+
+        self.xmlFile = xmlFile
+        self.items = {}
+
+        # Read in XML
+        fd = open(self.xmlFile.path, "r")
+        doc = xml.dom.minidom.parse( fd )
+        fd.close()
+
+        # Verify that top-level element is correct
+        accounts_node = doc._get_documentElement()
+        if accounts_node._get_localName() != ELEMENT_ACCOUNTS:
+            self.log("Ignoring file %r because it is not a repository builder file" % (self.xmlFile,))
+            return
+        self._parseXML(accounts_node)
+        
+    def _parseXML(self, node):
+        """
+        Parse the XML root node from the accounts configuration document.
+        @param node: the L{Node} to parse.
+        """
+        for child in node._get_childNodes():
+            if child._get_localName() in (ELEMENT_USER, ELEMENT_GROUP, ELEMENT_RESOURCE):
+                if child.hasAttribute( ATTRIBUTE_REPEAT ):
+                    repeat = int(child.getAttribute( ATTRIBUTE_REPEAT ))
+                else:
+                    repeat = 1
+
+                recordType = {
+                    ELEMENT_USER:    "user",
+                    ELEMENT_GROUP:   "group",
+                    ELEMENT_RESOURCE:"resource",}[child._get_localName()]
+                
+                principal = XMLAccountRecord(recordType)
+                principal.parseXML( child )
+                if repeat > 1:
+                    for ctr in range(repeat):
+                        newprincipal = principal.repeat(ctr + 1)
+                        self.items[newprincipal.uid] = newprincipal
+                        if recordType == "group":
+                            self._updateMembership(newprincipal)
+                else:
+                    self.items[principal.uid] = principal
+                    if recordType == "group":
+                        self._updateMembership(principal)
+
+    def _updateMembership(self, group):
+        # Update group membership
+        for member in group.members:
+            if self.items.has_key(member):
+                self.items[member].groups.append(group.uid)
+        
+class XMLAccountRecord (object):
+    """
+    Contains provision information for one user.
+    """
+    def __init__(self, recordType):
+        """
+        @param recordType:    record type for directory entry.
+        """
+        
+        self.recordType = recordType
+        self.uid = None
+        self.pswd = None
+        self.name = None
+        self.members = []
+        self.groups = []
+        self.cuaddrs = []
+
+    def repeat(self, ctr):
+        """
+        Create another object like this but with all text items having % substitution
+        done on them with the numeric value provided.
+        @param ctr: an integer to substitute into text.
+        """
+        
+        if self.uid.find("%") != -1:
+            uid = self.uid % ctr
+        else:
+            uid = self.uid
+        if self.pswd.find("%") != -1:
+            pswd = self.pswd % ctr
+        else:
+            pswd = self.pswd
+        if self.name.find("%") != -1:
+            name = self.name % ctr
+        else:
+            name = self.name
+        cuaddrs = []
+        for cuaddr in self.cuaddrs:
+            if cuaddr.find("%") != -1:
+                cuaddrs.append(cuaddr % ctr)
+            else:
+                cuaddrs.append(cuaddr)
+        
+        result = XMLAccountRecord(self.recordType)
+        result.uid = uid
+        result.pswd = pswd
+        result.name = name
+        result.members = self.members
+        result.cuaddrs = cuaddrs
+        return result
+
+    def parseXML( self, node ):
+
+        for child in node._get_childNodes():
+            if child._get_localName() == ELEMENT_USERID:
+                if child.firstChild is not None:
+                   self.uid = child.firstChild.data.encode("utf-8")
+            elif child._get_localName() == ELEMENT_PASSWORD:
+                if child.firstChild is not None:
+                    self.pswd = child.firstChild.data.encode("utf-8")
+            elif child._get_localName() == ELEMENT_NAME:
+                if child.firstChild is not None:
+                   self.name = child.firstChild.data.encode("utf-8")
+            elif child._get_localName() == ELEMENT_MEMBERS:
+                self._parseMembers(child)
+            elif child._get_localName() == ELEMENT_CUADDR:
+                if child.firstChild is not None:
+                   self.cuaddrs.append(child.firstChild.data.encode("utf-8"))
+            elif child._get_localName() == ELEMENT_CANPROXY:
+                CalDAVResource.proxyUsers.add(self.uid)
+
+    def _parseMembers( self, node ):
+
+        for child in node._get_childNodes():
+            if child._get_localName() == ELEMENT_USERID:
+                if child.firstChild is not None:
+                   self.members.append(child.firstChild.data.encode("utf-8"))

Modified: CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlfile.py
===================================================================
--- CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlfile.py	2006-11-16 21:08:33 UTC (rev 490)
+++ CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/xmlfile.py	2006-11-16 21:30:47 UTC (rev 491)
@@ -15,6 +15,7 @@
 #
 # DRI: Cyrus Daboo, cdaboo at apple.com
 ##
+from twistedcaldav.directory.xmlaccountsparser import XMLAccountsParser
 
 
 """
@@ -26,29 +27,11 @@
     "XMLFileRecord",
 ]
 
-import xml.dom.minidom
-
 from twisted.cred.credentials import UsernamePassword
 from twisted.python.filepath import FilePath
 
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
-from twistedcaldav.resource import CalDAVResource
 
-ELEMENT_ACCOUNTS    = "accounts"
-ELEMENT_USER        = "user"
-ELEMENT_GROUP       = "group"
-ELEMENT_RESOURCE    = "resource"
-
-ELEMENT_USERID      = "uid"
-ELEMENT_PASSWORD    = "pswd"
-ELEMENT_NAME        = "name"
-ELEMENT_MEMBERS     = "members"
-ELEMENT_CUADDR      = "cuaddr"
-ELEMENT_CALENDAR    = "calendar"
-ELEMENT_CANPROXY    = "canproxy"
-
-ATTRIBUTE_REPEAT    = "repeat"
-
 class XMLFileService(DirectoryService):
     """
     XML based implementation of L{IDirectoryService}.
@@ -60,21 +43,8 @@
         if type(xmlFile) is str:
             xmlFile = FilePath(xmlFile)
 
-        self.xmlFile = xmlFile
-        self.items = {}
+        self.xmlAccounts = XMLAccountsParser(xmlFile)
 
-        # Read in XML
-        fd = open(self.xmlFile.path, "r")
-        doc = xml.dom.minidom.parse( fd )
-        fd.close()
-
-        # Verify that top-level element is correct
-        accounts_node = doc._get_documentElement()
-        if accounts_node._get_localName() != ELEMENT_ACCOUNTS:
-            self.log("Ignoring file %r because it is not a repository builder file" % (self.xmlFile,))
-            return
-        self._parseXML(accounts_node)
-
     def recordTypes(self):
         recordTypes = ("user", "group", "resource")
         return recordTypes
@@ -99,129 +69,10 @@
         raise NotImplementedError()
 
     def _entriesForRecordType(self, recordType):
-        for entry in self.items.itervalues():
+        for entry in self.xmlAccounts.items.itervalues():
             if entry.recordType == recordType:
                  yield entry.uid, entry
 
-    def _parseXML(self, node):
-        """
-        Parse the XML root node from the accounts configuration document.
-        @param node: the L{Node} to parse.
-        """
-        for child in node._get_childNodes():
-            if child._get_localName() in (ELEMENT_USER, ELEMENT_GROUP, ELEMENT_RESOURCE):
-                if child.hasAttribute( ATTRIBUTE_REPEAT ):
-                    repeat = int(child.getAttribute( ATTRIBUTE_REPEAT ))
-                else:
-                    repeat = 1
-
-                recordType = {
-                    ELEMENT_USER:    "user",
-                    ELEMENT_GROUP:   "group",
-                    ELEMENT_RESOURCE:"resource",}[child._get_localName()]
-                
-                principal = XMLPrincipal(recordType)
-                principal.parseXML( child )
-                if repeat > 1:
-                    for ctr in range(repeat):
-                        newprincipal = principal.repeat(ctr + 1)
-                        self.items[newprincipal.uid] = newprincipal
-                        if recordType == "group":
-                            self._updateMembership(newprincipal)
-                else:
-                    self.items[principal.uid] = principal
-                    if recordType == "group":
-                        self._updateMembership(principal)
-
-    def _updateMembership(self, group):
-        # Update group membership
-        for member in group.members:
-            if self.items.has_key(member):
-                self.items[member].groups.append(group.uid)
-        
-class XMLPrincipal (object):
-    """
-    Contains provision information for one user.
-    """
-    def __init__(self, recordType):
-        """
-        @param recordType:    record type for directory entry.
-        """
-        
-        self.recordType = recordType
-        self.uid = None
-        self.pswd = None
-        self.name = None
-        self.members = []
-        self.groups = []
-        self.cuaddrs = []
-        self.calendars = []
-
-    def repeat(self, ctr):
-        """
-        Create another object like this but with all text items having % substitution
-        done on them with the numeric value provided.
-        @param ctr: an integer to substitute into text.
-        """
-        
-        if self.uid.find("%") != -1:
-            uid = self.uid % ctr
-        else:
-            uid = self.uid
-        if self.pswd.find("%") != -1:
-            pswd = self.pswd % ctr
-        else:
-            pswd = self.pswd
-        if self.name.find("%") != -1:
-            name = self.name % ctr
-        else:
-            name = self.name
-        cuaddrs = []
-        for cuaddr in self.cuaddrs:
-            if cuaddr.find("%") != -1:
-                cuaddrs.append(cuaddr % ctr)
-            else:
-                cuaddrs.append(cuaddr)
-        
-        result = XMLPrincipal(self.recordType)
-        result.uid = uid
-        result.pswd = pswd
-        result.name = name
-        result.members = self.members
-        result.cuaddrs = cuaddrs
-        result.calendars = self.calendars
-        return result
-
-    def parseXML( self, node ):
-
-        for child in node._get_childNodes():
-            if child._get_localName() == ELEMENT_USERID:
-                if child.firstChild is not None:
-                   self.uid = child.firstChild.data.encode("utf-8")
-            elif child._get_localName() == ELEMENT_PASSWORD:
-                if child.firstChild is not None:
-                    self.pswd = child.firstChild.data.encode("utf-8")
-            elif child._get_localName() == ELEMENT_NAME:
-                if child.firstChild is not None:
-                   self.name = child.firstChild.data.encode("utf-8")
-            elif child._get_localName() == ELEMENT_MEMBERS:
-                self._parseMembers(child)
-            elif child._get_localName() == ELEMENT_CUADDR:
-                if child.firstChild is not None:
-                   self.cuaddrs.append(child.firstChild.data.encode("utf-8"))
-            elif child._get_localName() == ELEMENT_CALENDAR:
-                if child.firstChild is not None:
-                   self.calendars.append(child.firstChild.data.encode("utf-8"))
-            elif child._get_localName() == ELEMENT_CANPROXY:
-                CalDAVResource.proxyUsers.add(self.uid)
-
-    def _parseMembers( self, node ):
-
-        for child in node._get_childNodes():
-            if child._get_localName() == ELEMENT_USERID:
-                if child.firstChild is not None:
-                   self.members.append(child.firstChild.data.encode("utf-8"))
-
 class XMLFileRecord(DirectoryRecord):
     """
     XML based implementation implementation of L{IDirectoryRecord}.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061116/028b0149/attachment.html


More information about the calendarserver-changes mailing list