From d45e570ee8bb671fced7f575c193d8656930da49 Mon Sep 17 00:00:00 2001
From: Alexandre Boeglin <alex@nexedi.com>
Date: Mon, 6 Nov 2006 09:10:54 +0000
Subject: [PATCH] ERP5Catalog queries now handle proxy roles correctly (test
 included)

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@11099 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Catalog/CatalogTool.py           | 13 ++++-
 product/ERP5Catalog/tests/testERP5Catalog.py | 57 ++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/product/ERP5Catalog/CatalogTool.py b/product/ERP5Catalog/CatalogTool.py
index f10cdb67b2..992bca2afa 100644
--- a/product/ERP5Catalog/CatalogTool.py
+++ b/product/ERP5Catalog/CatalogTool.py
@@ -291,7 +291,18 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
       security_product = getSecurityProduct(self.acl_users)
       if security_product == SECURITY_USING_PAS:
         # We use ERP5Security PAS based authentication
-        result = list( user.getRoles() )
+        try:
+          # check for proxy role in stack
+          eo = getSecurityManager()._context.stack[-1]
+          proxy_roles = getattr(eo,'_proxy_roles',None)
+        except IndexError:
+          proxy_roles = None
+        if proxy_roles:
+          # apply proxy roles
+          user = eo.getOwner()
+          result = list( proxy_roles )
+        else:
+          result = list( user.getRoles() )
         result.append( 'Anonymous' )
         result.append( 'user:%s' % user.getId() )
         # deal with groups
diff --git a/product/ERP5Catalog/tests/testERP5Catalog.py b/product/ERP5Catalog/tests/testERP5Catalog.py
index d07c0ec1bd..ad1be4b88b 100644
--- a/product/ERP5Catalog/tests/testERP5Catalog.py
+++ b/product/ERP5Catalog/tests/testERP5Catalog.py
@@ -36,10 +36,13 @@ os.environ['EVENT_LOG_SEVERITY'] = '-300'
 
 from Testing import ZopeTestCase
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+from AccessControl import getSecurityManager
 from AccessControl.SecurityManagement import newSecurityManager
 from zLOG import LOG
 from DateTime import DateTime
 from Products.CMFCore.tests.base.testcase import LogInterceptor
+from Testing.ZopeTestCase.PortalTestCase import PortalTestCase
+from Products.ERP5Type.tests.utils import createZODBPythonScript
 
 try:
   from transaction import get as get_transaction
@@ -1044,3 +1047,57 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor):
     get_transaction().commit()
     self.tic()
     self.assertEquals(0, len(folder.searchFolder()))
+
+  def test_ProxyRolesInRestrictedPython(self, quiet=quiet, run=run_all_test):
+    """test that proxy roles apply to catalog queries within python scripts
+    """
+    if not run: return
+    login = PortalTestCase.login
+    perm = 'View'
+
+    uf = self.getPortal().acl_users
+    uf._doAddUser('alice', '', ['Member', 'Manager', 'Assignor'], [])
+    uf._doAddUser('bob', '', ['Member'], [])
+    # create restricted object
+    login(self, 'alice')
+    folder = self.getOrganisationModule()
+    ob = folder.newContent()
+    # make sure permissions are correctly set
+    folder.manage_permission('Access contents information', ['Member'], 1)
+    folder.manage_permission(perm, ['Member'], 1)
+    ob.manage_permission('Access contents information', ['Member'], 1)
+    ob.manage_permission(perm, ['Manager'], 0)
+    get_transaction().commit()
+    self.tic()
+    # check access
+    self.assertEquals(1, getSecurityManager().checkPermission(perm, folder))
+    self.assertEquals(1, getSecurityManager().checkPermission(perm, ob))
+    login(self, 'bob')
+    self.assertEquals(1, getSecurityManager().checkPermission(perm, folder))
+    self.assertEquals(None, getSecurityManager().checkPermission(perm, ob))
+    # add a script that calls a catalog method
+    login(self, 'alice')
+    script = createZODBPythonScript(self.getPortal().portal_skins.custom,
+        'catalog_test_script', '', "return len(context.searchFolder())")
+
+    # test without proxy role
+    self.assertEquals(1, folder.catalog_test_script())
+    login(self, 'bob')
+    self.assertEquals(0, folder.catalog_test_script())
+
+    # test with proxy role and correct role
+    login(self, 'alice')
+    script.manage_proxy(['Manager'])
+    self.assertEquals(1, folder.catalog_test_script())
+    login(self, 'bob')
+    self.assertEquals(1, folder.catalog_test_script())
+
+    # test with proxy role and wrong role
+    login(self, 'alice')
+    script.manage_proxy(['Assignor'])
+    # proxy roles must overwrite the user's roles, even if he is the owner
+    # of the script
+    self.assertEquals(0, folder.catalog_test_script())
+    login(self, 'bob')
+    self.assertEquals(0, folder.catalog_test_script())
+
-- 
2.30.9