From 41556f6d969a7403f49724957413c80cec501147 Mon Sep 17 00:00:00 2001
From: Yoshinori Okuji <yo@nexedi.com>
Date: Tue, 3 Nov 2009 11:36:08 +0000
Subject: [PATCH] Correct the handling of checked_permission in
 _getSingleCategoryAcquiredMembershipList. This fixes two issues:

1. checked_permission was not propagated to recursive calls, so
   there were cases that checked_permission was ignored.
2. this method might try to get membership by acquisitions falsely,
   because _getSingleCategoryMembershipList filtered the result
   by checked_permission, so when the user was prevented from accessing
   a category directly specified by the context, the result was empty.

So the solution is to filter the result only right before returning
from this method, and stop having other methods to filter the result.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@30249 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/CMFCategory/CategoryTool.py | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/product/CMFCategory/CategoryTool.py b/product/CMFCategory/CategoryTool.py
index 99f0ecd8db..98f7853e7a 100644
--- a/product/CMFCategory/CategoryTool.py
+++ b/product/CMFCategory/CategoryTool.py
@@ -865,11 +865,30 @@ class CategoryTool( UniqueObject, Folder, Base ):
 
       return result
 
+    def _filterCategoryListByPermission(self, category_list, permission):
+      """This method returns a category list filtered by a permission.
+      If the permission is None, returns a passed list as it is.
+      """
+      if permission is None:
+        return category_list
+      checkPermission = self.portal_membership.checkPermission
+      resolveCategory = self.resolveCategory
+      new_category_list = []
+      append = new_category_list.append
+      for category in category_list:
+        try:
+          value = resolveCategory(category)
+          if checkPermission(permission, value):
+            append(category)
+        except Unauthorized:
+          pass
+      return new_category_list
 
     def _getSingleCategoryAcquiredMembershipList(self, context, base_category,
                                          base = 0, spec = (), filter = None,
                                          acquired_portal_type = (),
                                          acquired_object_dict = None,
+                                         checked_permission = None,
                                          **kw ):
       """
         Returns the acquired membership of the context for a single base category
@@ -955,7 +974,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
                 not base_category_value.getAcquisitionAppendValue() and \
                 result:
           # If acquisition masks and we do not append values, then we must return now
-          return result
+          return self._filterCategoryListByPermission(result, checked_permission)
         # First we look at local ids
         for object_id in base_category_value.getAcquisitionObjectIdList():
           try:
@@ -979,7 +998,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
               # If acquisition appends, then we must append to the result
               result.extend(new_result)
             elif new_result:
-              return new_result # Found enough information to return
+              return self._filterCategoryListByPermission(new_result, checked_permission) # Found enough information to return
         # Next we look at references
         #LOG("Get Acquired BC", 0, base_category_value.getAcquisitionBaseCategoryList())
         acquisition_base_category_list = base_category_value.getAcquisitionBaseCategoryList()
@@ -1056,7 +1075,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
                       self.setCategoryMembership( context, base_category, new_result,
                                     spec=spec, filter=filter, portal_type=portal_type, base=base )
                     # We found it, we can return
-                    return new_result
+                    return self._filterCategoryListByPermission(new_result, checked_permission)
 
 
           if (getattr(base_category_value, 'acquisition_copy_value', False) or \
@@ -1096,7 +1115,7 @@ class CategoryTool( UniqueObject, Folder, Base ):
                   result.append(category_value.getRelativeUrl())
       # WE MUST IMPLEMENT HERE THE REST OF THE SEMANTICS
       #LOG("Get Acquired Category Result ",0,str(result))
-      return result
+      return self._filterCategoryListByPermission(result, checked_permission)
 
     security.declareProtected( Permissions.AccessContentsInformation,
                                                'getAcquiredCategoryMembershipList' )
-- 
2.30.9