[Zope3-checkins] SVN: Zope3/branches/3.3/src/zope/app/undo/ Fix #529: Undo Principal Transactions doesn't work with non-root principals

Philipp von Weitershausen philikon at philikon.de
Sun Jul 2 06:18:06 EDT 2006


Log message for revision 68942:
  Fix #529:  Undo Principal Transactions doesn't work with non-root principals
  

Changed:
  U   Zope3/branches/3.3/src/zope/app/undo/__init__.py
  U   Zope3/branches/3.3/src/zope/app/undo/tests/test_zodbundomanager.py

-=-
Modified: Zope3/branches/3.3/src/zope/app/undo/__init__.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/undo/__init__.py	2006-07-02 10:17:39 UTC (rev 68941)
+++ Zope3/branches/3.3/src/zope/app/undo/__init__.py	2006-07-02 10:18:06 UTC (rev 68942)
@@ -23,8 +23,7 @@
 from zope.traversing.interfaces import IPhysicallyLocatable
 
 from zope.app.undo.interfaces import IUndoManager, UndoError
-from zope.app.security.principalregistry import principalRegistry
-from zope.app.security.interfaces import IPrincipal
+from zope.app.security.interfaces import IAuthentication, IPrincipal
 from zope.app.security.interfaces import PrincipalLookupError
 
 def undoSetup(event):
@@ -144,8 +143,9 @@
                     user_name = split[1]
             if user_name:
                 try:
-                    entry['principal'] = principalRegistry.getPrincipal(
-                        user_name)
+                    principal = zope.component.getUtility(
+                        IAuthentication).getPrincipal(user_name)
+                    entry['principal'] = principal
                 except PrincipalLookupError:
                     # principals might have passed away
                     pass
@@ -168,7 +168,8 @@
         txns = self._getUndoInfo(None, principal, first, -batch_size)
         while txns and left_overs:
             for info in txns:
-                if info['id'] in left_overs and info['principal'] is principal:
+                if (info['id'] in left_overs and
+                    info['principal'].id == principal.id):
                     left_overs.remove(info['id'])
             first += batch_size
             txns = self._getUndoInfo(None, principal, first, -batch_size)

Modified: Zope3/branches/3.3/src/zope/app/undo/tests/test_zodbundomanager.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/undo/tests/test_zodbundomanager.py	2006-07-02 10:17:39 UTC (rev 68941)
+++ Zope3/branches/3.3/src/zope/app/undo/tests/test_zodbundomanager.py	2006-07-02 10:18:06 UTC (rev 68942)
@@ -19,10 +19,23 @@
 from unittest import TestCase, main, makeSuite
 import transaction
 
-from zope.testing.cleanup import CleanUp 
-from zope.app.testing import ztapi
-from zope.app.testing.placelesssetup import PlacelessSetup
+import zope.component
+from zope.interface import implements
+from zope.testing.cleanup import CleanUp
+from zope.component import getUtility
+from zope.component.registry import Components
+from zope.component.testing import PlacelessSetup
+from zope.location import Location
+from zope.location.traversing import LocationPhysicallyLocatable
+from zope.security.interfaces import IPrincipal
 
+from zope.app.security.principalregistry import PrincipalRegistry
+from zope.app.component import queryNextUtility
+from zope.app.component.hooks import setSite, setHooks
+from zope.app.component.interfaces import ISite
+from zope.app.component.site import SiteManagerAdapter
+from zope.app.security.interfaces import IAuthentication, PrincipalLookupError
+
 from zope.app.undo import ZODBUndoManager
 from zope.app.undo.interfaces import UndoError
 
@@ -42,6 +55,8 @@
     dict(id='8', user_name='/ anthony', time=time(), description='des 8'),
     dict(id='9', user_name='/ jim', time=time(), description='des 9'),
     dict(id='10', user_name='/ jim', time=time(), description='des 10'),
+    dict(id='11', user_name='/ local.marco', time=time(),
+         description='des 11'),
     ]
 testdata.reverse()
 
@@ -77,23 +92,60 @@
     def undo(self, id):
         self.data = [d for d in self.data if d['id'] != id]
 
+
+class StubSite(Location):
+    implements(ISite)
+
+    def __init__(self):
+        self._sm = Components(bases=(zope.component.getGlobalSiteManager(),))
+
+    def getSiteManager(self):
+        return self._sm
+
+class StubPrincipal(object):
+    implements(IPrincipal)
+
+    def __init__(self, id, title=u'', description=u''):
+        self.id = id
+        self.title = title
+        self.description = description
+
+class LocalPrincipalRegistry(PrincipalRegistry, Location):
+
+    def getPrincipal(self, id):
+        try:
+            return super(LocalPrincipalRegistry, self).getPrincipal(id)
+        except PrincipalLookupError:
+            next = queryNextUtility(self, IAuthentication)
+            if next is not None:
+                return next.getPrincipal(id)
+            raise PrincipalLookupError(id)
+
 class Test(PlacelessSetup, TestCase):
 
     def setUp(self):
         super(Test, self).setUp()
+        zope.component.provideAdapter(LocationPhysicallyLocatable)
+        zope.component.provideAdapter(SiteManagerAdapter)
 
-        # provide location adapter
-        from zope.location.traversing import LocationPhysicallyLocatable
-        from zope.location.interfaces import ILocation
-        from zope.traversing.interfaces import IPhysicallyLocatable
-        ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
-                             LocationPhysicallyLocatable)
-
-        # define principals
+        # define global principals
         from zope.app.security.principalregistry import principalRegistry
         principalRegistry.definePrincipal('jim', 'Jim Fulton', login='jim')
         principalRegistry.definePrincipal('anthony', 'Anthony Baxter',
                                           login='anthony')
+        zope.component.provideUtility(principalRegistry, IAuthentication)
+
+        # make a local authentication utility in an active site
+        site = StubSite()
+        setSite(site)
+        setHooks()
+        localPrincipalRegistry = LocalPrincipalRegistry()
+        localPrincipalRegistry.definePrincipal('local.marco', 'Marco Mariani',
+                                               login=u'marco')
+        site.getSiteManager().registerUtility(localPrincipalRegistry,
+                                              IAuthentication)
+        localPrincipalRegistry.__parent__ = site
+
         self.undo = ZODBUndoManager(StubDB())
         self.data = list(testdata)
 
@@ -103,12 +155,17 @@
     def testGetPrincipalTransactions(self):
         self.assertRaises(TypeError, self.undo.getPrincipalTransactions, None)
 
-        from zope.app.security.principalregistry import principalRegistry
-        jim = principalRegistry.getPrincipal('jim')
-        expected = [dict for dict in self.data if dict['user_name'] == '/ jim']
+        jim = getUtility(IAuthentication).getPrincipal('jim')
+        expected = [d for d in self.data if d['user_name'] == '/ jim']
         self.assertEqual(list(self.undo.getPrincipalTransactions(jim)),
                          expected)
 
+        # now try with a "local" principal
+        marco = getUtility(IAuthentication).getPrincipal('local.marco')
+        expected = [d for d in self.data if d['user_name'] == '/ local.marco']
+        self.assertEqual(list(self.undo.getPrincipalTransactions(marco)),
+                         expected)
+
     def testGetTransactionsInLocation(self):
         from zope.interface import directlyProvides
         from zope.location import Location
@@ -126,8 +183,7 @@
         self.assertEqual(list(self.undo.getTransactions(spam)), expected)
 
         # now test this with getPrincipalTransactions()
-        from zope.app.security.principalregistry import principalRegistry
-        jim = principalRegistry.getPrincipal('jim')
+        jim = getUtility(IAuthentication).getPrincipal('jim')
         expected = [dict for dict in expected if dict['user_name'] == '/ jim']
         self.assertEqual(list(self.undo.getPrincipalTransactions(jim, spam)),
                          expected)
@@ -147,8 +203,7 @@
         self.assertRaises(TypeError, self.undo.undoPrincipalTransactions,
                           None, [])
         
-        from zope.app.security.principalregistry import principalRegistry
-        jim = principalRegistry.getPrincipal('jim')
+        jim = getUtility(IAuthentication).getPrincipal('jim')
         self.assertRaises(UndoError, self.undo.undoPrincipalTransactions,
                           jim, ('1','2','3'))
 
@@ -157,6 +212,25 @@
         expected = [d for d in testdata if (d['id'] not in ids)]
         self.assertEqual(list(self.undo.getTransactions()), expected)
 
+    def testUndoLocalPrincipalTransactions(self):
+        # try the same thing with a "local" principal
+        marco = getUtility(IAuthentication).getPrincipal('local.marco')
+        self.assertRaises(UndoError, self.undo.undoPrincipalTransactions,
+                          marco, ('10','11'))
+
+        ids = ('11',)
+        self.undo.undoPrincipalTransactions(marco, ids)
+        expected = [d for d in testdata if (d['id'] not in ids)]
+        self.assertEqual(list(self.undo.getTransactions()), expected)
+
+    def testUndoStubPrincipalTransactions(self):
+        # try it with a "made-up" principal
+        anthony = StubPrincipal('anthony')
+        ids = ('3', '5', '6', '8')
+        self.undo.undoPrincipalTransactions(anthony, ids)
+        expected = [d for d in testdata if (d['id'] not in ids)]
+        self.assertEqual(list(self.undo.getTransactions()), expected)
+
 def test_suite():
     return makeSuite(Test)
 



More information about the Zope3-Checkins mailing list