diff --git a/api/v3/Contact.php b/api/v3/Contact.php index 8b2711cd1ede..2d1da21a38d1 100644 --- a/api/v3/Contact.php +++ b/api/v3/Contact.php @@ -129,6 +129,8 @@ function civicrm_api3_contact_create($params) { _civicrm_api3_object_to_array_unique_fields($contact, $values[$contact->id]); } + $values = _civicrm_api3_contact_formatResult($params, $values); + return civicrm_api3_create_success($values, $params, 'Contact', 'create'); } @@ -168,9 +170,39 @@ function civicrm_api3_contact_get($params) { $options = array(); _civicrm_api3_contact_get_supportanomalies($params, $options); $contacts = _civicrm_api3_get_using_query_object('Contact', $params, $options); + $contacts = _civicrm_api3_contact_formatResult($params, $contacts); return civicrm_api3_create_success($contacts, $params, 'Contact'); } +/** + * Filter the result. + * + * @param array $result + * + * @return array + * @throws \CRM_Core_Exception + */ +function _civicrm_api3_contact_formatResult($params, $result) { + $apiKeyPerms = array('edit api keys', 'administer CiviCRM'); + $allowApiKey = empty($params['check_permissions']) || CRM_Core_Permission::check(array($apiKeyPerms)); + if (!$allowApiKey) { + if (is_array($result)) { + // Single-value $result + if (isset($result['api_key'])) { + unset($result['api_key']); + } + + // Multi-value $result + foreach ($result as $key => $row) { + if (is_array($row)) { + unset($result[$key]['api_key']); + } + } + } + } + return $result; +} + /** * Get number of contacts matching the supplied criteria. * diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index 59936149f4c8..961d0e0a5bb8 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -452,6 +452,75 @@ public function testCreateNoNameOrganization() { $this->callAPIFailure('contact', 'create', $params); } + /** + * Check that permissions on API key are restricted (CRM-18112). + */ + public function testCreateApiKey() { + $config = CRM_Core_Config::singleton(); + $contactId = $this->individualCreate(array( + 'first_name' => 'A', + 'last_name' => 'B', + )); + + // Allow edit -- because permissions aren't being checked + $config->userPermissionClass->permissions = array(); + $result = $this->callAPISuccess('Contact', 'create', array( + 'id' => $contactId, + 'api_key' => 'original', + )); + $this->assertEquals('original', $result['values'][$contactId]['api_key']); + + // Allow edit -- because we have adequate permission + $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys'); + $result = $this->callAPISuccess('Contact', 'create', array( + 'check_permissions' => 1, + 'id' => $contactId, + 'api_key' => 'abcd1234', + )); + $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']); + + // Disallow edit -- because we don't have permission + $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts'); + $result = $this->callAPIFailure('Contact', 'create', array( + 'check_permissions' => 1, + 'id' => $contactId, + 'api_key' => 'defg4321', + )); + $this->assertRegExp(';Permission denied to modify api key;', $result['error_message']); + + // Return everything -- because permissions are not being checked + $config->userPermissionClass->permissions = array(); + $result = $this->callAPISuccess('Contact', 'create', array( + 'id' => $contactId, + 'first_name' => 'A2', + )); + $this->assertEquals('A2', $result['values'][$contactId]['first_name']); + $this->assertEquals('B', $result['values'][$contactId]['last_name']); + $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']); + + // Return everything -- because we have adequate permission + $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys'); + $result = $this->callAPISuccess('Contact', 'create', array( + 'check_permissions' => 1, + 'id' => $contactId, + 'first_name' => 'A3', + )); + $this->assertEquals('A3', $result['values'][$contactId]['first_name']); + $this->assertEquals('B', $result['values'][$contactId]['last_name']); + $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']); + + // Restricted return -- because we don't have permission + $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts'); + $result = $this->callAPISuccess('Contact', 'create', array( + 'check_permissions' => 1, + 'id' => $contactId, + 'first_name' => 'A4', + )); + $this->assertEquals('A4', $result['values'][$contactId]['first_name']); + $this->assertEquals('B', $result['values'][$contactId]['last_name']); + $this->assertTrue(empty($result['values'][$contactId]['api_key'])); + } + /** * Check with complete array + custom field. *