I am using p.a.widgets 1.9.1 on Plone 4.3.12 and I get a "Vocabulary lookup not allowed" error on a field that uses AjaxSelectWidget. The field works for admin but not for regular user. The p.a.widgets module checks for vocabulary permissions and field permissions. This is set in
p/a/w/browser/vocabulary.py in the VocabularyView class
if factory_name in _permissions\
and INavigationRoot.providedBy(context):
# Short circuit if permission is in global registry
authorized = sm.checkPermission(
_permissions[factory_name], context
)
elif field_name:
# Check field specific permission
permission_checker = queryAdapter(
context, IFieldPermissionChecker
)
if permission_checker is not None:
authorized = permission_checker.validate(
field_name, factory_name
)
The permission check in the factory_name section returns false and the field_name validate method returns the default permission 'Modify portal content'. Since the error occurs on an Add Form, I need to set the modify permission on the container for my user. I really do not want to do this since this would also make the container editable by the user. Is there another way other than creating a custom permission and using it for the field's write permission?
BTW, my vocabulary already has a custom permission
My solution was to create a custom permission and provide the permission for my contributors on the container. My issue is specific to p.a.widgets 1.x since its browser/vocabulary.py is what takes on the Ajax requests. I think in P5, its already the vocabulary view provided by p.a.contenttypes which receives such requests. The permission checks are processed differently. I think you will need to check the package versions installed in your Plone instance.
Thanks. In my case I ended up being able to use the following on the field because the user's role had this permission on the parent. I did not initially realize it would work because I thought this only affected the read/write of the field itself but it did permit access to the vocabulary used by the AjaxSelectFieldWidget on the field.
I have this issue today in my Plone 5 with an extended User Registration Form and an AjaxSelectFieldWidget. My Solution:
The Adapter Registration:
<!-- Adapter Permission Checker for Vocabulary in Registration Form -->
<adapter
for=".interfaces.ICustomRegistrationForm"
provides="plone.app.widgets.interfaces.IFieldPermissionChecker"
factory=.userdata.UserDataFieldPermissionChecker" />
# interfaces.py
# -*- coding: utf-8 -*-
from zope.interface import Interface
class ICustomRegistrationForm(Interface):
"""Marker interface for Custom User Registration Form."""
The Form and the Provider Definition for the Adapter
# userdata.py
# -*- coding: utf-8 -*-
from zope.interface import implements
from plone.app.z3cform.widget import AjaxSelectFieldWidget
from plone.app.users.browser.register import RegistrationForm
from plone.app.dexterity.permissions import GenericFormFieldPermissionChecker
from interfaces import ICustomRegistrationForm
class UserDataFieldPermissionChecker(GenericFormFieldPermissionChecker):
def validate(self, field_name, vocabulary_name=None):
""" return True for allow or False if denied """
return (vocabulary_name and vocabulary_name == 'my.addon.vocabularies.IndicationSections')
class CustomRegistrationForm(RegistrationForm):
implements(ICustomRegistrationForm)
def render(self):
return super(RegistrationForm, self).render()
def updateFields(self):
super(RegistrationForm, self).updateFields()
self.fields["section"].widgetFactory = AjaxSelectFieldWidget
def updateWidgets(self):
super(RegistrationForm, self).updateWidgets()