Cannot remove contact from group from Groups tab UI within ACL environment
Have a staff user, Pebbles, in an ACL, with access to a contact, Wilma.
When Pebbles views the Groups tab of Wilma's record, they are able to add Wilma to a group via the UI, but should they click remove or delete next to a group, an error shows:
API permission check failed for GroupContact/delete call; insufficient permission: require access CiviCRM and edit all contacts
I don't think this is a security/permissions thing.
Pebbles is able to remove Wilma from the group by simply clicking Edit to get to the hideous edit-flippin-everything form, and then removing the group from the select2 element in the Groups accordion.
Suggested fix (v1)
I think it's useful for ACL-ed staffers to be able to use groups; it's such a core feature of Civi. And it's fairly weird that they can add a contact to a group, but not remove one - or not by the main UI.
I implemented this as follows in a custom extension, but I'm sure there's a better way to do it upstream.
/**
* @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterAPIPermissions/
*/
function myextension_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions) {
if ($entity === 'group_contact' && $action == 'delete' && !empty($params['id'])) {
$gc = \Civi\Api4\GroupContact::get(FALSE)
->addWhere('id', '=', $params['id'])
->addSelect('contact_id', 'group_id.group_type:name')
->execute()->single();
$mayEditContact = \Civi\Api4\Contact::checkAccess()
->setAction('update')
->addValue('id', $gc['contact_id'])
->execute()->first()['access'] ?? FALSE;
$groupIsNotAcl = !in_array('Access Control', $gc['group_id.group_type:name'] ?? []);
if ($mayEditContact && $groupIsNotAcl) {
// Reduce the access permissions for this call.
$permissions['group_contact']['delete'] = 'access CiviCRM';
}
}
}