[Zope] ownership fun and games.

Anthony Baxter anthony@interlink.com.au
Fri, 09 May 2003 14:57:49 +1000


So we had a couple of people who'd been working on zope here leave, and
their user objects got deleted. Stuff starts breaking _everywhere_, because
the permissions of a zope object are the intersection of the permissions of
the owner and the permissions of the user -- no owner means an intersection
with the null set. Oops. 

The following external method and python script will help you if something
similar ever happens to you. This Python Script will find objects owned
(explicitly) by non-existent users and set the ownership to the person 
running the script.

---------------8<------------------------8<-------------------
# Change these two. The first is where to start looking, the second is the
# acl_users folder to check.
top = container.ekorp
users = container.acl_users.getUserNames()

u={}
for i in users: u[i] = 1
isUser = u.has_key

todo = [top]
while 1:
    if not todo: break
    next,todo = todo[0], todo[1:]
    for id, obj in next.objectItems():
        try: owner = obj.owner_info()
        except: continue
        if owner['explicit']:
            user = owner['id']
            if not isUser(user):
                print "/".join(obj.getPhysicalPath()), owner['explicit'], user
                container.fixownership(obj)
        if hasattr(obj, 'objectItems') and obj.objectItems(): 
            todo.append(obj)
return printed
---------------8<------------------------8<-------------------

There's also an external method needed - install it as "fixownership" in
the same folder as the object pythonscript. (aside: This is only needed 
because of the idiotic checks on HTTP referrer in AccessControl/Owned.py
Owned.manage_takeOwnership(). Fine, you want more security. Almost nothing
else in Zope does this sort of checking - why this one method?? As it is,
the interface may as well not be there - it's unusable programmatically.)

---------------8<------------------------8<-------------------

def fixownership(object):
    from AccessControl import getSecurityManager
    user=getSecurityManager().getUser()
    object.changeOwnership(user)

---------------8<------------------------8<-------------------

Hopefully this will be of use to someone, somewhere.

Anthony