From f404486e33df702cd4f4962d20cf9de9b789dcd8 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Sat, 22 Apr 2017 09:22:46 +1000 Subject: [PATCH] CRM-20441 Fix issue where multiple activity Ids were not supported when check permissions was used --- api/v3/Activity.php | 22 ++++++-- tests/phpunit/api/v3/ACLPermissionTest.php | 59 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/api/v3/Activity.php b/api/v3/Activity.php index a501b66ab5..99df306c97 100644 --- a/api/v3/Activity.php +++ b/api/v3/Activity.php @@ -304,11 +304,23 @@ function civicrm_api3_activity_get($params) { "Cannot access activities. Required permission: 'view all activities''" ); } - - if (!CRM_Activity_BAO_Activity::checkPermission($params['id'], CRM_Core_Action::VIEW)) { - throw new \Civi\API\Exception\UnauthorizedException( - 'You do not have permission to view this activity' - ); + $ids = array(); + if (is_array($params['id'])) { + foreach ($params['id'] as $operator => $values) { + if (in_array($operator, CRM_Core_DAO::acceptedSQLOperators())) { + $ids = $values; + } + } + } + else { + $ids = array($params['id']); + } + foreach ($ids as $id) { + if (!CRM_Activity_BAO_Activity::checkPermission($id, CRM_Core_Action::VIEW)) { + throw new \Civi\API\Exception\UnauthorizedException( + 'You do not have permission to view this activity' + ); + } } } diff --git a/tests/phpunit/api/v3/ACLPermissionTest.php b/tests/phpunit/api/v3/ACLPermissionTest.php index 2bc56747a4..cf8551bb18 100644 --- a/tests/phpunit/api/v3/ACLPermissionTest.php +++ b/tests/phpunit/api/v3/ACLPermissionTest.php @@ -37,6 +37,7 @@ class api_v3_ACLPermissionTest extends CiviUnitTestCase { public $DBResetRequired = FALSE; protected $_entity; protected $allowedContactId = 0; + protected $allowedContacts = array(); public function setUp() { parent::setUp(); @@ -468,6 +469,19 @@ class api_v3_ACLPermissionTest extends CiviUnitTestCase { $where = " contact_a.id = " . $this->allowedContactId; } + /** + * Only specified contact returned. + * @implements CRM_Utils_Hook::aclWhereClause + * @param $type + * @param $tables + * @param $whereTables + * @param $contactID + * @param $where + */ + public function aclWhereMultipleContacts($type, &$tables, &$whereTables, &$contactID, &$where) { + $where = " contact_a.id IN (" . implode(', ', $this->allowedContacts) . ")"; + } + /** * Basic check that an unpermissioned call keeps working and permissioned call fails. */ @@ -559,6 +573,51 @@ class api_v3_ACLPermissionTest extends CiviUnitTestCase { $this->callAPISuccess('Activity', 'getsingle', array('check_permissions' => 1, 'id' => $activity['id'])); } + /** + * Test get activities multiple ids with check permissions + * CRM-20441 + */ + public function testActivitiesGetMultipleIdsCheckPermissions() { + $this->createLoggedInUser(); + $activity = $this->activityCreate(); + $activity2 = $this->activityCreate(); + $this->setPermissions(array('access CiviCRM')); + $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); + // Get activities associated with contact $this->_contactID. + $params = array( + 'id' => array('IN' => array($activity['id'], $activity2['id'])), + 'check_permissions' => TRUE, + ); + $result = $this->callAPISuccess('activity', 'get', $params); + $this->assertEquals(2, $result['count']); + } + + /** + * Test get activities multiple ids with check permissions + * Limit access to One contact + * CRM-20441 + */ + public function testActivitiesGetMultipleIdsCheckPermissionsLimitedACL() { + $this->createLoggedInUser(); + $activity = $this->activityCreate(); + $contacts = $this->getActivityContacts($activity); + $this->setPermissions(array('access CiviCRM')); + foreach ($contacts as $contact_id) { + $this->allowedContacts[] = $contact_id; + } + $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereMultipleContacts')); + $contact2 = $this->individualCreate(); + $activity2 = $this->activityCreate(array('source_contact_id' => $contact2)); + // Get activities associated with contact $this->_contactID. + $params = array( + 'id' => array('IN' => array($activity['id'])), + 'check_permissions' => TRUE, + ); + $result = $this->callAPISuccess('activity', 'get', $params); + $this->assertEquals(1, $result['count']); + $this->callAPIFailure('activity', 'get', array_merge($params, array('id' => array('IN', array($activity2['id']))))); + } + /** * Get the contacts for the activity. * -- 2.25.1