[Zope-CVS] CVS: Products/RecentItemsIndex - README.txt:1.2 index.py:1.2 test.py:1.2

Casey Duncan casey at zope.com
Mon Jul 19 17:17:26 EDT 2004


Update of /cvs-repository/Products/RecentItemsIndex
In directory cvs.zope.org:/tmp/cvs-serv15367

Modified Files:
	README.txt index.py test.py 
Log Message:
Add role/permission guard functionality to pre-filter index objects


=== Products/RecentItemsIndex/README.txt 1.1.1.1 => 1.2 ===
--- Products/RecentItemsIndex/README.txt:1.1.1.1	Mon Jul 19 13:46:21 2004
+++ Products/RecentItemsIndex/README.txt	Mon Jul 19 17:16:56 2004
@@ -12,5 +12,10 @@
   The index also has a custom query interface so that applications
   may query it directly for greatest efficiency since it handles both
   the result selection and sorting simultaneously.
+  
+  At the moment the index is not searchable through the standard ZCatalog
+  'searchResults()' API. This is because the catalog does not yet support
+  indexes that can do searching and sorting simultaneously as this one
+  does.
 
   


=== Products/RecentItemsIndex/index.py 1.1.1.1 => 1.2 ===
--- Products/RecentItemsIndex/index.py:1.1.1.1	Mon Jul 19 13:46:21 2004
+++ Products/RecentItemsIndex/index.py	Mon Jul 19 17:16:56 2004
@@ -24,6 +24,7 @@
     import PluggableIndexInterface
 from Products.ZCatalog.Lazy import LazyMap
 from AccessControl import Permissions
+from AccessControl.PermissionRole import rolesForPermissionOn
 from AccessControl.SecurityInfo import ClassSecurityInfo
 from BTrees.OOBTree import OOBTree
 from BTrees.IOBTree import IOBTree
@@ -61,7 +62,7 @@
     
     def __init__(
         self, id, field_name=None, date_name=None, max_length=None, 
-        extra=None, caller=None):
+        guard_roles=None, guard_permission=None, extra=None, caller=None):
         """Recent items index constructor
         
         id -- Zope id for index in
@@ -72,6 +73,16 @@
         date_name -- Name of attribute containing a date which specifies the
         object's age.
         
+        max_length -- Maximum length of each recent items list.
+        
+        guard_roles -- A list of one or more roles that must be granted the
+        guard permission in order for an object to be indexed. Ignored if
+        no guard_permission value is given.
+        
+        guard_permission -- The permission that must be granted to the
+        guard roles for an object in order for it to be indexed. Ignored if
+        not guard_roles value is given.
+        
         extra and caller are used by the wonderous ZCatalog addIndex 
         machinery. You can ignore them, unfortunately I can't 8^/
         """
@@ -80,6 +91,15 @@
         self.date_name = date_name or extra.date_name
         self.max_length = max_length or extra.max_length
         assert self.max_length > 0, 'Max item length value must be 1 or greater'
+        if guard_roles is None:
+            guard_roles = getattr(extra, 'guard_roles', None)
+        if guard_permission is None:
+            guard_permission = getattr(extra, 'guard_permission', None)
+        if guard_permission is not None and guard_roles:
+            self.guard_permission = guard_permission
+            self.guard_roles = tuple(guard_roles)
+        else:
+            self.guard_permission = self.guard_roles = None
         self.clear()
     
     ## Index specific methods ##
@@ -127,6 +147,16 @@
     
     def index_object(self, docid, obj, theshold=None):
         """Add document to index"""
+        if self.guard_permission is not None and self.guard_roles:
+            allowed_roles = rolesForPermissionOn(self.guard_permission, obj)
+            for role in allowed_roles:
+                if role in self.guard_roles:
+                    break
+            else:
+                # Object does not have proper permission grant
+                # to be in the index
+                self.unindex_object(docid)
+                return 0
         try:
             fieldvalue = _getSourceValue(obj, self.field_name)
             datevalue = _getSourceValue(obj, self.date_name)


=== Products/RecentItemsIndex/test.py 1.1.1.1 => 1.2 ===
--- Products/RecentItemsIndex/test.py:1.1.1.1	Mon Jul 19 13:46:21 2004
+++ Products/RecentItemsIndex/test.py	Mon Jul 19 17:16:56 2004
@@ -35,6 +35,16 @@
     def __getitem__(self, item):
         return self.docs[item]
 
+class Viewable(SimpleItem):
+    
+    date = DateTime('2/21/2004')
+    type = 'Viewable'
+    
+    def __init__(self, role=None):
+        self._addRole(role)
+        if role is not None:
+            self.manage_permission('View', [role])
+
 class RecentItemsIndexTest(TestCase):
 
     def setUp(self):
@@ -50,11 +60,15 @@
             field_name = 'bruford'
             date_name = 'wakeman'
             max_length = 25
+            guard_roles = ['Anonymous']
+            guard_permission = 'View'
         index = RecentItemsIndex('extra', extra=extra)
         self.assertEqual(index.getId(), 'extra')
         self.assertEqual(index.field_name, 'bruford')
         self.assertEqual(index.date_name, 'wakeman')
         self.assertEqual(index.max_length, 25)
+        self.assertEqual(tuple(index.guard_roles), ('Anonymous',))
+        self.assertEqual(index.guard_permission, 'View')
     
     def test_construct_with_bogus_max_length(self):
         from Products.RecentItemsIndex.index import RecentItemsIndex
@@ -302,9 +316,32 @@
         
     def test_clear(self):
         self.test_index_many()
+        self.failUnless(self.index.numObjects())
         self.index.clear()
         self.assertEqual(self.index.numObjects(), 0)
-
+    
+    def test_role_permission_guard(self):
+        from Products.RecentItemsIndex.index import RecentItemsIndex
+        index = RecentItemsIndex(
+            'test', 'type', 'date', 5, ['NerfHerder', 'Bloke'], 'View')
+        viewable = Viewable('NerfHerder')
+        index.index_object(0, viewable)
+        self.assertEqual(index.numObjects(), 1)
+        notviewable = Viewable()
+        index.index_object(1, notviewable)
+        self.assertEqual(index.numObjects(), 1)
+        bloke = Viewable('Bloke')
+        index.index_object(2, bloke)
+        self.assertEqual(index.numObjects(), 2)
+        bloke.manage_permission('View', [])
+        index.index_object(2, bloke)
+        self.assertEqual(index.numObjects(), 1)
+        dummy = Viewable('Dummy')
+        index.index_object(3, dummy)
+        self.assertEqual(index.numObjects(), 1)        
+        viewable.manage_permission('View', [])
+        index.index_object(0, viewable)
+        self.assertEqual(index.numObjects(), 0)
         
 def test_suite():
     return TestSuite((makeSuite(RecentItemsIndexTest),))



More information about the Zope-CVS mailing list