From: Coleman Watts Date: Mon, 1 Jul 2019 00:47:47 +0000 (-0400) Subject: Fix api_key handling from joins X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=3493febb3ee46489e1ff5705efe04311e68bf03c;p=civicrm-core.git Fix api_key handling from joins --- diff --git a/Civi/API/SelectQuery.php b/Civi/API/SelectQuery.php index 752159b3d7..95bd4ce093 100644 --- a/Civi/API/SelectQuery.php +++ b/Civi/API/SelectQuery.php @@ -233,6 +233,12 @@ abstract class SelectQuery { // Join doesn't exist - might be another param with a dot in it for some reason, we'll just ignore it. return NULL; } + + // Skip if we don't have permission to access this field + if ($this->checkPermissions && !empty($fieldInfo['permission']) && !\CRM_Core_Permission::check($fieldInfo['permission'])) { + return NULL; + } + $fkTable = \CRM_Core_DAO_AllCoreTables::getTableForClass($fkField['FKClassName']); $tableAlias = implode('_to_', $subStack) . "_to_$fkTable"; diff --git a/Civi/Test/Api3TestTrait.php b/Civi/Test/Api3TestTrait.php index bc8b0b9125..98f993936e 100644 --- a/Civi/Test/Api3TestTrait.php +++ b/Civi/Test/Api3TestTrait.php @@ -322,8 +322,7 @@ trait Api3TestTrait { $v4Params['language'] = $language; } $toRemove = ['option.', 'return', 'api.', 'format.']; - $chains = []; - $custom = []; + $chains = $joins = $custom = []; foreach ($v3Params as $key => $val) { foreach ($toRemove as $remove) { if (strpos($key, $remove) === 0) { @@ -412,6 +411,13 @@ trait Api3TestTrait { case 'get': if ($options['return'] && $v3Action !== 'getcount') { $v4Params['select'] = array_keys($options['return']); + // Convert join syntax + foreach ($v4Params['select'] as &$select) { + if (strstr($select, '_id.')) { + $joins[$select] = explode('.', str_replace('_id.', '.', $select)); + $select = str_replace('_id.', '.', $select); + } + } } if ($options['limit'] && $v4Entity != 'Setting') { $v4Params['limit'] = $options['limit']; @@ -577,6 +583,10 @@ trait Api3TestTrait { foreach ($chains as $key => $params) { $result[$index][$key] = $this->runApi4LegacyChain($key, $params, $v4Entity, $row, $sequential); } + // Convert join format + foreach ($joins as $api3Key => $api4Path) { + $result[$index][$api3Key] = \CRM_Utils_Array::pathGet($result[$index], $api4Path); + } // Resolve custom field names foreach ($custom as $group => $fields) { foreach ($fields as $field => $v3FieldName) { diff --git a/Civi/Test/ContactTestTrait.php b/Civi/Test/ContactTestTrait.php index 50e256177f..f3e85083d9 100644 --- a/Civi/Test/ContactTestTrait.php +++ b/Civi/Test/ContactTestTrait.php @@ -160,7 +160,7 @@ trait ContactTestTrait { * */ private function _contactCreate($params) { - $result = $this->callAPISuccess('contact', 'create', $params); + $result = civicrm_api3('contact', 'create', $params); if (!empty($result['is_error']) || empty($result['id'])) { throw new \CRM_Core_Exception('Could not create test contact, with message: ' . \CRM_Utils_Array::value('error_message', $result) . "\nBacktrace:" . \CRM_Utils_Array::value('trace', $result)); } diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index b807fbc6df..dfcf158e32 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -632,8 +632,16 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->assertEquals('B', $result['values'][$contactId]['last_name']); $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']); + // Should also be returned via join + $joinResult = $this->callAPISuccessGetSingle('Email', [ + 'check_permissions' => 1, + 'contact_id' => $contactId, + 'return' => 'contact_id.api_key', + ]); + $this->assertEquals('abcd1234', $joinResult['contact_id.api_key']); + // Restricted return -- because we don't have permission - $config->userPermissionClass->permissions = ['access CiviCRM', 'edit all contacts']; + $config->userPermissionClass->permissions = ['access CiviCRM', 'view all contacts', 'edit all contacts']; $result = $this->callAPISuccess('Contact', 'create', [ 'check_permissions' => 1, 'id' => $contactId, @@ -642,6 +650,14 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->assertEquals('A4', $result['values'][$contactId]['first_name']); $this->assertEquals('B', $result['values'][$contactId]['last_name']); $this->assertTrue(empty($result['values'][$contactId]['api_key'])); + + // Should also be restricted via join + $joinResult = $this->callAPISuccessGetSingle('Email', [ + 'check_permissions' => 1, + 'contact_id' => $contactId, + 'return' => ['email', 'contact_id.api_key'], + ]); + $this->assertTrue(empty($joinResult['contact_id.api_key'])); } /**