createTestObject('CRM_Pledge_BAO_Pledge', array(), 1, 0); $baoObj->createTestObject('CRM_Core_BAO_Phone', array(), 1, 0); $this->hookClass = CRM_Utils_Hook::singleton(); $config = CRM_Core_Config::singleton(); $config->userPermissionClass->permissions = array(); } /** * (non-PHPdoc) * @see CiviUnitTestCase::tearDown() */ function tearDown() { CRM_Utils_Hook::singleton()->reset(); $tablesToTruncate = array( 'civicrm_contact', 'civicrm_group_contact', 'civicrm_group', 'civicrm_acl', 'civicrm_acl_cache', 'civicrm_acl_entity_role', 'civicrm_acl_contact_cache', 'civicrm_contribution', 'civicrm_participant', ); $this->quickCleanup($tablesToTruncate); $config = CRM_Core_Config::singleton(); unset($config->userPermissionClass->permissions); } /** * Function tests that an empty where hook returns no results */ function testContactGetNoResultsHook() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults')); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => 'display_name', )); $this->assertEquals(0, $result['count']); } /** * Function tests all results are returned */ function testContactGetAllResultsHook() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => 'display_name', )); $this->assertEquals(2, $result['count']); } /** * Function tests that deleted contacts are not returned */ function testContactGetPermissionHookNoDeleted() { $this->callAPISuccess('contact', 'create', array('id' => 2, 'is_deleted' => 1)); $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => 'display_name', )); $this->assertEquals(1, $result['count']); } /** * test permissions limited by hook */ function testContactGetHookLimitingHook() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond')); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => 'display_name', )); $this->assertEquals(1, $result['count']); } /** * confirm that without check permissions we still get 2 contacts returned */ function testContactGetHookLimitingHookDontCheck() { // $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 0, 'return' => 'display_name', )); $this->assertEquals(2, $result['count']); } /** * Check that id works as a filter */ function testContactGetIDFilter() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); $result = $this->callAPISuccess('contact', 'get', array( 'sequential' => 1, 'id' => 2, 'check_permissions' => 1, )); $this->assertEquals(1, $result['count']); $this->assertEquals(2, $result['id']); } /** * Check that address IS returned */ function testContactGetAddressReturned() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond')); $fullresult = $this->callAPISuccess('contact', 'get', array( 'sequential' => 1, )); //return doesn't work for all keys - can't fix that here so let's skip ... //prefix & suffix are inconsistent due to CRM-7929 // unsure about others but return doesn't work on them $elementsReturnDoesntSupport = array( 'prefix', 'suffix', 'gender', 'current_employer', 'phone_id', 'phone_type_id', 'phone', 'worldregion_id', 'world_region' ); $expectedReturnElements = array_diff(array_keys($fullresult['values'][0]), $elementsReturnDoesntSupport); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => $expectedReturnElements, 'sequential' => 1, )); $this->assertEquals(1, $result['count']); foreach ($expectedReturnElements as $element) { $this->assertArrayHasKey($element, $result['values'][0]); } } /** * Check that pledge IS not returned */ function testContactGetPledgeIDNotReturned() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); $this->callAPISuccess('contact', 'get', array( 'sequential' => 1, )); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'return' => 'pledge_id', 'sequential' => 1, )); $this->assertArrayNotHasKey('pledge_id', $result['values'][0]); } /** * Check that pledge IS not an allowable filter */ function testContactGetPledgeIDNotFiltered() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults')); $this->callAPISuccess('contact', 'get', array( 'sequential' => 1, )); $result = $this->callAPISuccess('contact', 'get', array( 'check_permissions' => 1, 'pledge_id' => 1, 'sequential' => 1, )); $this->assertEquals(2, $result['count']); } /** * Check that chaining doesn't bypass permissions */ function testContactGetPledgeNotChainable() { $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond')); $this->callAPISuccess('contact', 'get', array( 'sequential' => 1, )); $this->callAPIFailure('contact', 'get', array( 'check_permissions' => 1, 'api.pledge.get' => 1, 'sequential' => 1, ), 'Error in call to pledge_get : API permission check failed for pledge/get call; missing permission: access CiviCRM.' ); } function setupCoreACL() { $this->createLoggedInUser(); $this->_permissionedDisabledGroup = $this->groupCreate(array('title' => 'pick-me-disabled', 'is_active' => 0, 'name' => 'pick-me-disabled')); $this->_permissionedGroup = $this->groupCreate(array('title' => 'pick-me-active', 'is_active' => 1, 'name' => 'pick-me-active')); $this->setupACL(); } /** * @dataProvider entities * confirm that without check permissions we still get 2 contacts returned */ function testEntitiesGetHookLimitingHookNoCheck($entity) { CRM_Core_Config::singleton()->userPermissionClass->permissions = array(); $this->setUpEntities($entity); $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults')); $result = $this->callAPISuccess($entity, 'get', array( 'check_permissions' => 0, 'return' => 'contact_id', )); $this->assertEquals(2, $result['count']); } /** * @dataProvider entities * confirm that without check permissions we still get 2 entities returned */ function testEntitiesGetCoreACLLimitingHookNoCheck($entity) { $this->setupCoreACL(); //CRM_Core_Config::singleton()->userPermissionClass->permissions = array(); $this->setUpEntities($entity); $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults')); $result = $this->callAPISuccess($entity, 'get', array( 'check_permissions' => 0, 'return' => 'contact_id', )); $this->assertEquals(2, $result['count']); } /** * @dataProvider entities * confirm that with check permissions we don't get entities */ function testEntitiesGetCoreACLLimitingCheck($entity) { $this->markTestIncomplete('this does not work in 4.4 but can be enabled in 4.5 or a security release of 4.4 including the important security fix CRM-14877'); $this->setupCoreACL(); $this->setUpEntities($entity); $result = $this->callAPISuccess($entity, 'get', array( 'check_permissions' => 1, 'return' => 'contact_id', )); $this->assertEquals(0, $result['count']); } /** * @dataProvider entities * Function tests that an empty where hook returns no results */ function testEntityGetNoResultsHook($entity) { $this->markTestIncomplete('hook acls only work with contacts so far'); CRM_Core_Config::singleton()->userPermissionClass->permissions = array(); $this->setUpEntities($entity); $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults')); $result = $this->callAPISuccess($entity, 'get', array( 'check_permission' => 1, )); $this->assertEquals(0, $result['count']); } /** * @return array */ public static function entities() { return array(array('contribution'), array('participant'),);// @todo array('pledge' => 'pledge') } /** * Create 2 entities */ public function setUpEntities($entity) { $baoObj = new CRM_Core_DAO(); $baoObj->createTestObject( _civicrm_api3_get_BAO($entity), array(), 2, 0); CRM_Core_Config::singleton()->userPermissionClass->permissions = array( 'access CiviCRM', 'access CiviContribute', 'access CiviEvent', 'view event participants', ); } /** * no results returned */ function aclWhereHookNoResults($type, &$tables, &$whereTables, &$contactID, &$where) { } /** * all results returned * @implements CRM_Utils_Hook::aclWhereClause */ function aclWhereHookAllResults($type, &$tables, &$whereTables, &$contactID, &$where) { $where = " (1) "; } /** * full results returned * @implements CRM_Utils_Hook::aclWhereClause */ function aclWhereOnlySecond($type, &$tables, &$whereTables, &$contactID, &$where) { $where = " contact_a.id > 1"; } }