Vocabulary lookup not allowed

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

_permissions['my.package.vocabulary.ParkingUnits'] = 'View'

but this does not work since factory_name evaluation uses an "and" operator and INavigationRoot.providedBy(context) returns false

I would appreciate ideas on a workaround.

I just came up with this issue, but on Plone 5. Did you find a solution?

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.

    read_permission(field_name='cmf.AddPortalContent')
    write_permission(field_name='cmf.AddPortalContent')

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()