[Zope-PTK] DISCUSS: Searching based on role
Mike Pelletier
mike@metamike.net
Tue, 18 Jan 2000 10:12:57 -0500 (EST)
On Sat, 15 Jan 2000, Paul Everitt wrote:
> Member authors Document, changes security to only let "Collaborators", a
> role she defined, see the document.
Problem... How do I point at a unique role object to say "this
Collaborators" as opposed to any Role named "Collaborators"?
> A Collaborator goes to the URL and sees the document. The Collaborator
> then does a search of the site using a word in the document and sees the
> document in the results. Same for a Topic. However, a regular Member
> gets unauthorized when going to the URL, and can't search for the
> document or see it in a topic.
>
> Is this so, grasshopper?
No, it's somewhat simpler than that. I just wrote (then erased) a
descrption of the PortalCatalog class (which implements half this
question) and it took up more space than the actual class. In the
interest of stomping out irony wherever possible, here is the class,
slighty edited for readability:
class PortalCatalog(ZCatalog):
"A catalog which filters searchResults based on user's permission."
def searchResults(self, REQUEST=None, used=None, query_map={...}, **kw):
"""
Wrapper around ZCatalog.searchResults, inserts criteria to ensure
nobody sees anything they are not allowed to.
"""
# This method extends one on ZCatalog
if REQUEST is not None:
user = REQUEST.AUTHENTICATED_USER # Who's asking?
if not user.has_permission('View private objects', self):
# 'kw' contains a dict of the keys to find
# Insert one to hide anything not 'published'
kw['review_state'] = 'published'
return apply(ZCatalog.searchResults, (self,REQUEST,used,query_map), kw)
So, it only looks at the permission 'View private objects' and an
index of the 'review_state' property. (It should also be finding only
objects who's Date property is older than now.) The problem is, we can't
find out if the user has the permission on the specific object in
question-- we don't want to wake every object every time someone submits a
query!
The solution I've used is to check the permission against the catalog.
One setting applies to all objects and all members. You describe a
catalog which allows you to make this decision per object and per member.
We could add some flexibility by indexing a method which returns a
list of the Roles which should be allowed to view that object.
searchResults would insert keys for Date and this method. This allows per
Role tuning, but not quite per Member tuning. I think there would be
problems if we allowed Members to add roles and make objects visible to
those invented roles.
It would give Members a false sense of security. Role names would
have to be treated as passwords, because that's basically how they'd work.
Only the name of the Role is in the index, so if you have a Role of the
same name that maybe _you_ invented, you can see things other people think
are safe. Remember, we can't ask if the user has a Role on the specific
object, just if they have the Role at all.
Additionally, it neatly bypasses any abuse-control measures we've
built into this reviewing scheme. If you can designate arbitrary Members
as able to view your *unapproved* content, you are even better off than
when anyone could view them, from an abuser's point of view.
I hope I'm not sacrificing a cool feature for overly paranoid
reasons. What do you think?
> Also, Mike does your new reviewing machinery handle the case for the
> "Owner" role? That is, can a Member see their own documents and search
> for their own documents?
It does not presently take that into account. I don't think I can do
this with a single query. I'd need to be able to say "(my_roles in
allowed_roles OR my_name in owners) AND all the user-provided keys". I
don't see a great need to find your own unpublished items. Tell me if you
disagree.
> --Paul
--
Mike Pelletier email: mike@digicool.com
Mild mannered software developer icq: 7127228
by day, super villain by night. phone: 519-884-2434