Details
-
Type: Bug
-
Status: Done/Fixed
-
Priority: Major
-
Resolution: Won't Fix
-
Affects Version/s: 4.0.7, 4.0.8
-
Fix Version/s: 4.1.0
-
Component/s: Core CiviCRM
-
Labels:None
Description
In summary: if a user can view all contacts but can only edit a specific group through ACL permissions they are given a reduced set of actions to perform on search results. I have users who are able to view all contacts but only able to edit their own group. I need these users to be able to have the full list of task available to them when they search within their own group. I am trying to modify the search code to check if the user is searching within their own group to give them these action but I am having issues.
If a user has 'Edit all contacts' permission (Drupal) and Civi ACL of 'View all contacts', they have the ability to perform the full list of actions on the results.
If a user does not have 'Edit all contacts' permission (Drupal), Civi ACL of 'View' all contacts and a Civi ACL of 'Edit' for a particular group, they are given a significantly reduced list of action to perform on the results.
I have been trying to modify the code in CRM/Contact/Form/Search.php buildQuickForm() to return the full length of tasks if the user has specified the group they have the 'edit' permission.
The point where the tasks are returned is $tasks += CRM_Contact_Task::permissionedTaskTitles( $permission, CRM_Utils_Array::value( 'deleted_contacts', $this->_formValues ) );
The result is dependent on whether the $permission is CRM_Core_Permission::EDIT or not. This $permission is determined from $permission = CRM_Core_Permission::getPermission(); which I have not totally followed through but seems to only return CRM_Core_Permission::EDIT if you have Drupal 'Edit all contacts'.
So I looked into adding some extra code if $permission != CRM_Core_Permission::EDIT to check if the user has specified a group in their search and if they have EDIT permissions on it. If they do the $permission can be set to CRM_Core_Permission::EDIT and all the tasks will be available to them:
Replace:
$permission = CRM_Core_Permission::getPermission();
With:
$edit_all_contact = CRM_Core_Permission::check('edit all contacts');
$permission = CRM_Core_Permission::VIEW;
//If user does not have access to edit all users check that user has access to edit this group
if($edit_all_contact) {
$permission = CRM_Core_Permission::EDIT;
} else if($this->_formValues['group'] != '') {
$groups = $this->_formValues['group'];
$group_permission = true;
foreach($groups as $groupID => $value) {
$check_permission = CRM_Contact_BAO_Group::checkPermission( $groupID, '' );
if(!in_array(CRM_Core_Permission::EDIT, $check_permission))
}
if($group_permission)
}
This didn't work though as CRM_Contact_BAO_Group::checkPermission did not give the results I expected. I traced the problem down to CRM/ACL/BAO/ACL.php group(). If I am trying to check if a user has EDIT permission on a group this function breaks prematurely because it detects I have VIEW all contacts permission. By adding "AND a.operation = %2" to the query where %2 = $type we can avoid the function mixing 'EDIT" and 'VIEW'. The problem in doing this is it mucks up CRM_Core_Permission::getPermission() as it now assumes I have CRM_Core_Permission::EDIT since I have Edit permissions on a single group.
So at this point I decided I didn't know what I was doing and needed to check if I was going down the wrong path or if there is actually a problem here. I also need to know if it is a good idea to give the user all the actions if they are editing a group they have EDIT access to. Is the a different or better way I have missed?