I ran into an issue in 5.2 that seems to be because of Zope owner of a "Script (Python)" object used by a workflow. getSecurityManager().checkPermission (via plone.api) was failing on permissions that they quite obviously should have. If I went into debug mode and checked permissions on the portal root or any object directly, it even said that this user did indeed have the permission.
A deeper dive into checkPermission revealed that it would also go through the context stack to check for an executable https://github.com/zopefoundation/AccessControl/blob/4.0/src/AccessControl/ImplPython.py#L493. This is where it was failing for me, and for a very bizarre problem. The end of the stack is this "notify_reviewers" workflow script that is really just a wrapper to call a proper BrowserView. This is an object in Zope so it has an owner, let's say 'admin_foo'. Here's the problem - in this new test environment I did indeed have an admin_foo user, but didn't assign any roles. So essentially this script was owned by an account that didn't have any permissions not also granted to Anonymous, which is why that permission check was failing. Adding the intended manager role to that admin account resolves the issue, but it isn't a great solution.
I think there are two concerns here for which I could use some clarification.
Last I checked I can't call a browser view directly from a workflow transition, I have to call a Script (Python) object within that workflow. Should I give up trying to do this in the workflow and use event listeners instead?
In Zope 2 you can take ownership from accounts that might no longer be around. Zope 4's ZMI does not appear to have an Ownership tab. You can go to /manage_owner anyway but there's no option to take ownership. If I had needed to delete admin_foo, how would I make sure this Script (Python) can actually get an owner with Manager role?
Two problems with this. The ZMI does not allow it, script (after/before) are tags populated with Script (Python) objects in that workflow. Generic Setup will let you put in @@view but this results in a KeyError - it is not traversing from that object, it is literally just looking in the scripts assigned to that workflow.
I think listening for an AfterTransitionEvent event is probably what I want to do instead, it is just unfortunate that this can't be expressed as a part of the workflow for documentation/debugging purposes.
This seems like a big bug. Without that the security model is hampered. Please raise a ticket for this.
Note not only do you need to change owner but you need the proxy role setting which is more important. Otherwise the script runs with the roles of the end user.
You could also write a python script that did return context.restrictedTraverse("@@view...")() as long as the view was public.
Sure, I can do that but I don't know the appropriate place to post an issue? To be honest it does not seem like a security hole to me - it is very conservative security.
That is literally what my Script (Python) object in the workflow is currently. It's just a wrapper to call a more modern browser view that can do the heavy lifting, but I like that examining the workflow will show me that this code is going to run.