After a user has filled out a (ploneformgen) form , I would like to use a custom script adapter to call a python script to change the user’s local role so that they can’t see the form anymore. In other words, I want to prevent the user from filling out (or viewing) the form twice.
I figured that one way to do this is to call the script permission_changer.py which is located in the form folder. The code I have in that script is this:
container.manage_delLocalRoles((‘bob',))
container.reindexObjectSecurity()
Where ‘bob’ is just an example user, who has only the global role FormFiller (which I created under the Security tab of the ZMI) and the local role “Reader” for the form folder.
When I fill out the form (which has a "private" state) as a system admin, the script is called successfully and bob loses his “Reader” local role (which is all he had to begin with), and he can’t see the form anymore. However, when bob fills out the form, a “You do not have sufficient privileges to view this page.” error is displayed, and bob’s local role is not removed. I can’t work out why –– and I’ve tried many different things:
I’ve changed the proxy for the permission_changer.py by clicking on “Proxy” tab for the script in ZMI. I changed it to “Manager”, "System Administrator”, and “Owner”, but that didn’t solve the problem (nor did any combination of those).
I tried changing the proxy by creating a file permission_changer.py.metdadata in the form folder and including this:
[default]
proxy = Manager
but that didn’t work either.
Strangely, when I change bob’s global role to Manager, or System Administrator, or even Viewer, or Editor, the problem goes away and the script runs just fine (I can also change the script so that it adds and removes arbitrary other local roles). (These options are not solutions for me because bob will still be able to see the form because of his global role.)
Also, I tried giving the role FormFiller role every possible permission under the Security tab, but didn’t work.
So, I’m guessing that the problem has to do with the proxy settings, but I can’t work out what I’m doing wrong. I've searched around a lot, and I can't find anyone discussing a similar problem.
Any help would be much appreciated!
Ugly ugly way to handle this may be to access to the data saver field's download method and parse its output to find data to check. For example, if username is the second pfg field added into form, a custom script adapter that prevents furthers fillings by a user may be
alreadyInDB = False
savedData = ploneformgen.savefield.getSavedFormInputForEdit()
username = request.AUTHENTICATED_USER.getId()
usersInDB = [x.split(',')[1] for x in savedData.split('\r\n') if len(x)>0]
if username in usersInDB:
alreadyInDB = True
if alreadyInDB:
return {'username': 'No way man!'}
I worked out what was going on, but I'm not sure how to describe it precisely. Basically, I found that by calling the script as a Custom Success Action (form > edit > overrides), I don't get the problem. So I think that by calling the script as custom script adapter I was trying to change the user's permission while they were still engaged with the form and that is impossible, even with the Manager proxy role.
I hope that helps. And if anyone has a more precise description of the problem, that would be appreciated.
For granting and revoking the permissions to submit a form, you could:
- Create a group (e.g. with the ID "Submitters") and assign the chosen users to it
- Make sure the form-folder has the state 'private' and grant View-permissions via the sharing-tab of the form-folder to the group
- Add a content-item of type 'Page' in the form-folder's parent (e.g. with the ID 'submitted') and set its state to 'public'
- Add a content-item of type 'Custom Script Adapter', select 'Manager' in the field 'Proxy role', and insert the lines below into the field 'Script body':
# Remove current user of group and redirect to [FORM_PARENT_URL]/landing_page_id'.
# If user is not in group, fail silently and continue.
# Fail if landing_page_id does not exist in form-folder, or one of its parents.
#
# Assumes a page with the ID as declared in `landing_page_id` lives in the
# form-folder's parent (or one of its grand-parents, first found wins),
# and holds the state 'public', so users can view it regardless of their
# group-memberships.
#
# Ment to be used after submission of a PloneFormGen-form with private-state and
# a locally assigned Reader-role for the group, so only group-members can view and
# submit the form.
from Products.CMFCore.utils import getToolByName
group_id = 'Submitters' # change as needed
landing_page_id = 'submitted' # change as needed
portal_groups = getToolByName(ploneformgen, 'portal_groups')
user_id = ploneformgen.memberId()
parent_url = '/'.join(ploneformgen.absolute_url().split('/')[:-1])
redirect_to_url = parent_url + '/' + landing_page_id
# Revoke current user's group-membership:
portal_groups.removePrincipalFromGroup(user_id, group_id)
# Let user land in userland:
request.response.redirect(redirect_to_url)
Tested with Plone-4.3.11 and Products.PloneFormGen-1.7.25
来源:https://stackoverflow.com/questions/20923149/python-script-to-hide-ploneformgen-form-after-user-has-filled-it-out-for-plone