I need to add an entityRef lookup field to a public facing profile form so that users can search and select organization contacts. I patterned it after the current employer lookup in the contact record with slight changes (you can't create a new contact):

If I access the form anonymously, the lookup fails with a permission error. If I grant the public user "access AJAX API" it does not fail, but does not return any records (because the public user isn't permissioned to view all contacts). You'll see that I attempted to modify the API with check_permissions, but it has no impact.

With "access AJAX API" enabled for the public user, the alterAPIPermissions hook is hit -- so I could modify the perms and avoid granting the public user "view all contacts" permission.

My question is:
What are the consequences of giving the public user access AJAX API permission? Is there some way to avoid having to do that? Is the above the right way to implement this -- to grant that permission and them modify the actual permissions with the hook?

EDIT:
Actually, I don't seem to be able to grant sufficient permissions with alterAPIPermissions. I've tried:

FYI The reason changing $params['check_permissions'] to false doesn't work is because these params are then sent to the server from the javascript widget, and for good reasons, the server will not trust rest requests attempting to disable permission checks.
– ColemanDec 22 '15 at 16:55

2 Answers
2

The Access AJAX API permission was added in CRM-8840 to get around the firewall of sorts that surrounds the API unless you have Access CiviCRM. If you don't have either, you'll get blocked trying any Javascript call to the API, regardless of your other permissions (whether granted via hook, ACLs, or CMS).

As best I know (and I just did a quick test on a dummy site), all of the APIs require Access CiviCRM or Administer CiviCRM even beside the blanket requirement for Access CiviCRM or Access AJAX API. While adding Access AJAX API will get your foot in the proverbial door, you won't have the ability to do anything. You'll want to write a hook to change the permissions in the specific cases that you need to run an API call.

So yes, you're on the right track, and no, there shouldn't be any immediate negative consequences of adding Access AJAX API. However, since it removes the outer layer of security against the API, you'll just need to be sure everything's configured tightly.

Yeah, that could be a number of things. When using that hook, I generally have to experiment a bit with it. You might break down your problem by using straight API calls through the Firebug console like CRM.api3('Contact', 'get'); and see what returns. Once you have that working to your liking, you can see if the problem is in your API permissions or something specific to the entityRef.
– Andrew HuntDec 21 '15 at 22:01

I wonder if a better pattern to start with would be custom fields of type "ContactReference" - these go through a different ajax callback which by default does not check permissions (for better or worse).

Just seems like a shame to have to build a workaround like that. In this case, I simply want the current employer field to be a searchable/lookup list for anonymous users. Because the form process already looks for the employer_id field, you simply need to add the field to the form -- no postProcess work required. But if I have to create a custom field, I then need to process that against the native field. It just seems like we should be able to modify the permissions more easily than this.
– lcdservicesDec 21 '15 at 21:30