[Zope-dev] ZCatalog - hiding query results
abel deuring
a.deuring@satzbau-gmbh.de
Sat, 10 Nov 2001 22:33:09 +0100
Igor Stroh wrote:
>
> Hi all,
>
> I don't know if it's the right list to post to, but I have the following
> problem:
> I have several objects (documents, folders etc) that are accessible only
> by a certain user role, this objects are cataloged. Now if I query the
> catalog the brains of these objects are returned correctly, but to _all_
> users that issue a query. That means, users that don't have the permission
> to "View" or "Access Content Information" can see the brains as well...
> I tried to filter the result set by converting the brains into real
> objects (brain.getObject) in an external method (I thought, this way I
> should be able to exclude unauthorized users by adding the
> "skip_unauthorized" to the dtml-in), but that doesn't work
> since there are "brains" that are actually NoBrainer instances...
>
> Does anyone have an idea of how I could solve this problem?
> Actually I thought this kind of "information hiding" is supported by basic
> ZCatalog machinery, but now it looks like I'll have to hack a
> workaround...
>
> Any help greatly appreciated.
Igor,
I had exactly the same problem and solved it this way:
1. define a method 'catalog_permission' in the classes of the objects
that will be indexed:
from AccessControl.PermissionRole import rolesForPermissionOn
class someClass(Folder):
def catalog_permission(self):
""" return: Liste der roles, die die permissions 'View',
'Access Content Information" sowie "view archivDoc" haben
"""
l1 = rolesForPermissionOn('View', self)
if type(l1) == type(''):
l1 = [l1, ]
l2 = rolesForPermissionOn('Access contents information', self)
if type(l2) == type(''):
l2 = [l2, ]
res = []
for x in l1:
if x in l2:
res.append(x)
return res
2. define a new Catalog class, with a newly defined method
searchResults:
from Products.ZCatalog.ZCatalog import ZCatalog
from AccessControl import getSecurityManager
class ACatalog(ZCatalog):
def searchResults(self, REQUEST=None, used=None, **kw):
""" """
roles = getSecurityManager().getUser().getRoles()
if REQUEST is not None:
REQUEST['catalog_permission'] = roles
elif kw != {}:
kw['catalog_permission'] = roles
else:
self.REQUEST['catalog_permission'] = roles
return ZCatalog.searchResults(self, REQUEST, used, **kw)
3. Add a keyword index 'catalog_permission' to the ACatalog instance.
(Ok, that could be done automatically in ACatalog.__init__ , but I was
too lazy to write that...)
A more reliable implemetation should make sure that only those objects
are indexed, which define a method catalog_permission. Or
Catalog.catalogObject could be overloaded to automatically build the
information to be thrown into the catalog_permission index.
Abel