[CalendarServer-changes] [1826] CalendarServer/branches/users/cdaboo/recursive-groups-1824/ twistedcaldav/directory

source_changes at macosforge.org source_changes at macosforge.org
Sat Aug 25 14:25:06 PDT 2007


Revision: 1826
          http://trac.macosforge.org/projects/calendarserver/changeset/1826
Author:   cdaboo at apple.com
Date:     2007-08-25 14:25:06 -0700 (Sat, 25 Aug 2007)

Log Message:
-----------
Proxy group members should be recursively expanded.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/calendaruserproxy.py
    CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/accounts.xml
    CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_xmlfile.py
    CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/xmlaccountsparser.py

Added Paths:
-----------
    CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_proxyprincipalmembers.py

Modified: CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/calendaruserproxy.py	2007-08-25 15:25:15 UTC (rev 1825)
+++ CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/calendaruserproxy.py	2007-08-25 21:25:06 UTC (rev 1826)
@@ -288,7 +288,29 @@
     def principalCollections(self):
         return self.parent.principalCollections()
 
-    def groupMembers(self):
+    def _expandMemberUIDs(self, uid=None, relatives=None, uids=None):
+        if uid is None:
+            uid = self.principalUID()
+        if relatives is None:
+            relatives = set()
+        if uids is None:
+            uids = set()
+
+        if uid not in uids:
+            from twistedcaldav.directory.principal import DirectoryPrincipalResource
+            uids.add(uid)
+            principal = self.parent.parent.principalForUID(uid)
+            if isinstance(principal, CalendarUserProxyPrincipalResource):
+                for member in self._directGroupMembers():
+                    if member.principalUID() not in uids:
+                        relatives.add(member)
+                        self._expandMemberUIDs(member.principalUID(), relatives, uids)
+            elif isinstance(principal, DirectoryPrincipalResource):
+                relatives.update(principal.groupMembers())
+
+        return relatives
+
+    def _directGroupMembers(self):
         if self.hasEditableMembership():
             # Get member UIDs from database and map to principal resources
             members = self._index().getMembers(self.uid)
@@ -300,6 +322,10 @@
             else:
                 return ()
 
+
+    def groupMembers(self):
+        return self._expandMemberUIDs()
+
     def groupMemberships(self):
         # Get membership UIDs and map to principal resources
         memberships = self._index().getMemberships(self.uid)

Modified: CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/accounts.xml
===================================================================
--- CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/accounts.xml	2007-08-25 15:25:15 UTC (rev 1825)
+++ CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/accounts.xml	2007-08-25 21:25:06 UTC (rev 1826)
@@ -111,11 +111,32 @@
       <member type="groups">left_coast</member>
     </members>
   </group>
+  <group>
+    <uid>recursive1_coasts</uid>
+    <password>recursive1_coasts</password>
+    <name>Recursive1 Coasts</name>
+    <members>
+      <member type="groups">recursive2_coasts</member>
+      <member>wsanchez</member>
+    </members>
+  </group>
+  <group>
+    <uid>recursive2_coasts</uid>
+    <password>recursive2_coasts</password>
+    <name>Recursive2 Coasts</name>
+    <members>
+      <member type="groups">recursive1_coasts</member>
+      <member>cdaboo</member>
+    </members>
+  </group>
   <location>
     <uid>mercury</uid>
     <password>mercury</password>
     <name>Mecury Seven</name>
     <cuaddr>mailto:mercury at example.com</cuaddr>
+    <proxies>
+      <member type="groups">left_coast</member>
+    </proxies>
   </location>
   <location>
     <uid>gemini</uid>
@@ -132,6 +153,9 @@
     <password>apollo</password>
     <name>Apollo Eleven</name>
     <cuaddr>mailto:apollo at example.com</cuaddr>
+    <proxies>
+      <member type="groups">both_coasts</member>
+    </proxies>
   </location>
   <resource>
     <uid>transporter</uid>

Added: CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_proxyprincipalmembers.py
===================================================================
--- CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_proxyprincipalmembers.py	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_proxyprincipalmembers.py	2007-08-25 21:25:06 UTC (rev 1826)
@@ -0,0 +1,106 @@
+##
+# Copyright (c) 2005-2007 Apple 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: Wilfredo Sanchez, wsanchez at apple.com
+##
+
+import os
+
+from twisted.web2.dav.fileop import rmdir
+
+from twistedcaldav.directory.directory import DirectoryService
+from twistedcaldav.directory.xmlfile import XMLDirectoryService
+from twistedcaldav.directory.test.test_xmlfile import xmlFile
+from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+
+import twistedcaldav.test.util
+
+directoryService = XMLDirectoryService(xmlFile)
+
+class ProxyPrincipals (twistedcaldav.test.util.TestCase):
+    """
+    Directory service provisioned principals.
+    """
+    def setUp(self):
+        super(ProxyPrincipals, self).setUp()
+        
+        # Set up a principals hierarchy for each service we're testing with
+        self.principalRootResources = {}
+        name = directoryService.__class__.__name__
+        url = "/" + name + "/"
+        path = os.path.join(self.docroot, url[1:])
+
+        if os.path.exists(path):
+            rmdir(path)
+        os.mkdir(path)
+
+        provisioningResource = DirectoryPrincipalProvisioningResource(path, url, directoryService)
+
+        self.site.resource.putChild(name, provisioningResource)
+
+        self.principalRootResources[directoryService.__class__.__name__] = provisioningResource
+
+    def test_groupMembersRegular(self):
+        """
+        DirectoryPrincipalResource.groupMembers()
+        """
+        members = self._getRecordByShortName(DirectoryService.recordType_groups, "both_coasts").groupMembers()
+        members = set([p.displayName() for p in members])
+        self.assertEquals(members, set(('Chris Lecroy', 'David Reid', 'Wilfredo Sanchez', 'West Coast', 'East Coast', 'Cyrus Daboo',)))
+
+    def test_groupMembersRecursive(self):
+        """
+        DirectoryPrincipalResource.groupMembers()
+        """
+        members = self._getRecordByShortName(DirectoryService.recordType_groups, "recursive1_coasts").groupMembers()
+        members = set([p.displayName() for p in members])
+        self.assertEquals(members, set(('Wilfredo Sanchez', 'Recursive2 Coasts', 'Cyrus Daboo',)))
+
+    def test_groupMembersProxySingleUser(self):
+        """
+        DirectoryPrincipalResource.groupMembers()
+        """
+        members = self._getRecordByShortName(DirectoryService.recordType_locations, "gemini").getChild("calendar-proxy-write").groupMembers()
+        members = set([p.displayName() for p in members])
+        self.assertEquals(members, set(('Wilfredo Sanchez',)))
+
+    def test_groupMembersProxySingleGroup(self):
+        """
+        DirectoryPrincipalResource.groupMembers()
+        """
+        members = self._getRecordByShortName(DirectoryService.recordType_locations, "mercury").getChild("calendar-proxy-write").groupMembers()
+        members = set([p.displayName() for p in members])
+        self.assertEquals(members, set(('Chris Lecroy', 'David Reid', 'Wilfredo Sanchez', 'West Coast',)))
+
+    def test_groupMembersProxySingleGroupWithNestedGroups(self):
+        """
+        DirectoryPrincipalResource.groupMembers()
+        """
+        members = self._getRecordByShortName(DirectoryService.recordType_locations, "apollo").getChild("calendar-proxy-write").groupMembers()
+        members = set([p.displayName() for p in members])
+        self.assertEquals(members, set(('Chris Lecroy', 'David Reid', 'Wilfredo Sanchez', 'West Coast', 'East Coast', 'Cyrus Daboo', 'Both Coasts',)))
+
+    def _getRecordByShortName(self, type, name):
+        """
+        @return: an iterable of tuples
+            C{(provisioningResource, recordType, recordResource, record)}, where
+            C{provisioningResource} is the root provisioning resource,
+            C{recordType} is the record type,
+            C{recordResource} is the principal resource and
+            C{record} is the directory service record
+            for each record in each directory in C{directoryServices}.
+        """
+        provisioningResource = self.principalRootResources[directoryService.__class__.__name__]
+        return provisioningResource.principalForShortName(type, name)

Modified: CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_xmlfile.py
===================================================================
--- CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_xmlfile.py	2007-08-25 15:25:15 UTC (rev 1825)
+++ CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/test/test_xmlfile.py	2007-08-25 21:25:06 UTC (rev 1826)
@@ -58,6 +58,10 @@
                                                                                                (DirectoryService.recordType_users , "lecroy")) },
         "both_coasts": { "password": "both_coasts", "guid": None, "addresses": (), "members": ((DirectoryService.recordType_groups, "right_coast"),
                                                                                                (DirectoryService.recordType_groups, "left_coast"))           },
+        "recursive1_coasts": { "password": "recursive1_coasts", "guid": None, "addresses": (), "members": ((DirectoryService.recordType_groups, "recursive2_coasts"),
+                                                                                               (DirectoryService.recordType_users, "wsanchez"))           },
+        "recursive2_coasts": { "password": "recursive2_coasts", "guid": None, "addresses": (), "members": ((DirectoryService.recordType_groups, "recursive1_coasts"),
+                                                                                               (DirectoryService.recordType_users, "cdaboo"))           },
     }
 
     locations = {

Modified: CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/xmlaccountsparser.py	2007-08-25 15:25:15 UTC (rev 1825)
+++ CalendarServer/branches/users/cdaboo/recursive-groups-1824/twistedcaldav/directory/xmlaccountsparser.py	2007-08-25 21:25:06 UTC (rev 1826)
@@ -131,13 +131,15 @@
                 for i in xrange(1, repeat+1):
                     newprincipal = principal.repeat(i)
                     self.items[recordType][newprincipal.shortName] = newprincipal
-                    updateMembership(newprincipal)
-                    updateProxyFor(newprincipal)
             else:
                 self.items[recordType][principal.shortName] = principal
+
+        # Do reverse membership mapping only after all records have been read in
+        for records in self.items.itervalues():
+            for principal in records.itervalues():
                 updateMembership(principal)
                 updateProxyFor(principal)
-
+                
 class XMLAccountRecord (object):
     """
     Contains provision information for one user.

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


More information about the calendarserver-changes mailing list