Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
6a488035 TO |
2 | /* |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
7d61e75f TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
6a488035 TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
5e327f37 CW |
12 | use Civi\Api4\Contact; |
13 | use Civi\Api4\CustomField; | |
14 | use Civi\Api4\CustomGroup; | |
15 | use Civi\Api4\CustomValue; | |
16 | ||
6a488035 TO |
17 | /** |
18 | * This class is intended to test ACL permission using the multisite module | |
19 | * | |
7884d958 | 20 | * @package CiviCRM_APIv3 |
21 | * @subpackage API_Contact | |
acb109b7 | 22 | * @group headless |
6a488035 | 23 | */ |
6a488035 | 24 | class api_v3_ACLPermissionTest extends CiviUnitTestCase { |
2af6f0c0 | 25 | |
57a4d21c | 26 | use Civi\Test\ACLPermissionTrait; |
2af6f0c0 | 27 | |
4e420887 | 28 | public $DBResetRequired = FALSE; |
430ae6dd TO |
29 | protected $_entity; |
30 | ||
7ef12efc | 31 | public function setUp(): void { |
6a488035 | 32 | parent::setUp(); |
82fd72da | 33 | CRM_Core_DAO::createTestObject('CRM_Pledge_BAO_Pledge', [], 1, 0); |
b19b754f | 34 | $this->callAPISuccess('Phone', 'create', ['id' => $this->individualCreate(['email' => '']), 'phone' => '911', 'location_type_id' => 'Home']); |
5e8daa54 | 35 | $this->prepareForACLs(); |
6a488035 | 36 | } |
7884d958 | 37 | |
38 | /** | |
39 | * (non-PHPdoc) | |
40 | * @see CiviUnitTestCase::tearDown() | |
41 | */ | |
11ba3ace | 42 | public function tearDown(): void { |
5e8daa54 | 43 | $this->cleanUpAfterACLs(); |
ff3833b0 | 44 | $tablesToTruncate = [ |
7884d958 | 45 | 'civicrm_contact', |
aa06ad4a | 46 | 'civicrm_address', |
ae4bb4c9 EM |
47 | 'civicrm_group_contact', |
48 | 'civicrm_group', | |
49 | 'civicrm_acl', | |
50 | 'civicrm_acl_cache', | |
51 | 'civicrm_acl_entity_role', | |
52 | 'civicrm_acl_contact_cache', | |
53 | 'civicrm_contribution', | |
62e432ac | 54 | 'civicrm_line_item', |
ae4bb4c9 | 55 | 'civicrm_participant', |
225d474b | 56 | 'civicrm_uf_match', |
bbd2743b | 57 | 'civicrm_activity', |
58 | 'civicrm_activity_contact', | |
c6835264 CW |
59 | 'civicrm_note', |
60 | 'civicrm_entity_tag', | |
61 | 'civicrm_tag', | |
ff3833b0 | 62 | ]; |
6a488035 | 63 | $this->quickCleanup($tablesToTruncate); |
6a488035 | 64 | } |
7884d958 | 65 | |
66 | /** | |
eceb18cc | 67 | * Function tests that an empty where hook returns no results. |
82fd72da | 68 | * |
2d932085 | 69 | * @param int $version |
82fd72da | 70 | * |
2d932085 | 71 | * @dataProvider versionThreeAndFour |
82fd72da | 72 | * @throws \CRM_Core_Exception |
7884d958 | 73 | */ |
2d932085 CW |
74 | public function testContactGetNoResultsHook($version) { |
75 | $this->_apiversion = $version; | |
ff3833b0 | 76 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
77 | $this, | |
78 | 'aclWhereHookNoResults', | |
79 | ]); | |
80 | $result = $this->callAPISuccess('contact', 'get', [ | |
6a488035 TO |
81 | 'check_permissions' => 1, |
82 | 'return' => 'display_name', | |
ff3833b0 | 83 | ]); |
6a488035 TO |
84 | $this->assertEquals(0, $result['count']); |
85 | } | |
86 | ||
1028f75e | 87 | /** |
1a4651ba | 88 | * Function tests that an empty where hook returns exactly 1 result with "view my contact". |
1028f75e | 89 | * |
90 | * CRM-16512 caused contacts with Edit my contact to be able to view all records. | |
82fd72da | 91 | * |
2d932085 | 92 | * @param int $version |
82fd72da | 93 | * |
2d932085 | 94 | * @dataProvider versionThreeAndFour |
82fd72da | 95 | * @throws \CRM_Core_Exception |
1028f75e | 96 | */ |
2d932085 CW |
97 | public function testContactGetOneResultHookWithViewMyContact($version) { |
98 | $this->_apiversion = $version; | |
1028f75e | 99 | $this->createLoggedInUser(); |
ff3833b0 | 100 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
101 | $this, | |
102 | 'aclWhereHookNoResults', | |
103 | ]); | |
104 | CRM_Core_Config::singleton()->userPermissionClass->permissions = [ | |
105 | 'access CiviCRM', | |
106 | 'view my contact', | |
107 | ]; | |
108 | $result = $this->callAPISuccess('contact', 'get', [ | |
1028f75e | 109 | 'check_permissions' => 1, |
110 | 'return' => 'display_name', | |
ff3833b0 | 111 | ]); |
1a4651ba CW |
112 | $this->assertEquals(1, $result['count']); |
113 | } | |
114 | ||
115 | /** | |
116 | * Function tests that a user with "edit my contact" can edit themselves. | |
82fd72da | 117 | * |
2d932085 | 118 | * @param int $version |
82fd72da | 119 | * |
2d932085 | 120 | * @dataProvider versionThreeAndFour |
82fd72da | 121 | * @throws \CRM_Core_Exception |
1a4651ba | 122 | */ |
2d932085 CW |
123 | public function testContactEditHookWithEditMyContact($version) { |
124 | $this->_apiversion = $version; | |
1a4651ba | 125 | $cid = $this->createLoggedInUser(); |
ff3833b0 | 126 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
127 | $this, | |
128 | 'aclWhereHookNoResults', | |
129 | ]); | |
130 | CRM_Core_Config::singleton()->userPermissionClass->permissions = [ | |
131 | 'access CiviCRM', | |
132 | 'edit my contact', | |
133 | ]; | |
134 | $this->callAPISuccess('contact', 'create', [ | |
1a4651ba CW |
135 | 'check_permissions' => 1, |
136 | 'id' => $cid, | |
2d932085 | 137 | 'first_name' => 'NewName', |
ff3833b0 | 138 | ]); |
1028f75e | 139 | } |
140 | ||
52ed95a8 | 141 | /** |
142 | * Ensure contact permissions do not block contact-less location entities. | |
82fd72da | 143 | * |
2d932085 | 144 | * @param int $version |
82fd72da | 145 | * |
2d932085 | 146 | * @dataProvider versionThreeAndFour |
82fd72da | 147 | * @throws \CRM_Core_Exception |
52ed95a8 | 148 | */ |
2d932085 CW |
149 | public function testAddressWithoutContactIDAccess($version) { |
150 | $this->_apiversion = $version; | |
52ed95a8 | 151 | $ownID = $this->createLoggedInUser(); |
ff3833b0 | 152 | CRM_Core_Config::singleton()->userPermissionClass->permissions = [ |
153 | 'access CiviCRM', | |
154 | 'view all contacts', | |
155 | ]; | |
156 | $this->callAPISuccess('Address', 'create', [ | |
52ed95a8 | 157 | 'city' => 'Mouseville', |
158 | 'location_type_id' => 'Main', | |
159 | 'api.LocBlock.create' => 1, | |
160 | 'contact_id' => $ownID, | |
ff3833b0 | 161 | ]); |
162 | $this->callAPISuccessGetSingle('Address', [ | |
163 | 'city' => 'Mouseville', | |
164 | 'check_permissions' => 1, | |
165 | ]); | |
166 | CRM_Core_DAO::executeQuery('UPDATE civicrm_address SET contact_id = NULL WHERE contact_id = %1', [ | |
167 | 1 => [ | |
168 | $ownID, | |
169 | 'Integer', | |
170 | ], | |
171 | ]); | |
172 | $this->callAPISuccessGetSingle('Address', [ | |
173 | 'city' => 'Mouseville', | |
174 | 'check_permissions' => 1, | |
175 | ]); | |
52ed95a8 | 176 | } |
177 | ||
c16ed19b CW |
178 | /** |
179 | * Ensure contact permissions extend to related entities like email | |
82fd72da | 180 | * |
2d932085 | 181 | * @param int $version |
82fd72da | 182 | * |
183 | * @throws \CRM_Core_Exception | |
184 | * @throws \CiviCRM_API3_Exception | |
2d932085 CW |
185 | * @dataProvider versionThreeAndFour |
186 | * FIXME: Finish api4 part | |
c16ed19b | 187 | */ |
2d932085 CW |
188 | public function testRelatedEntityPermissions($version) { |
189 | $this->_apiversion = $version; | |
0a61b6e2 | 190 | $this->createLoggedInUser(); |
ff3833b0 | 191 | $disallowedContact = $this->individualCreate([], 0); |
192 | $this->allowedContactId = $this->individualCreate([], 1); | |
193 | $this->hookClass->setHook('civicrm_aclWhereClause', [ | |
194 | $this, | |
195 | 'aclWhereOnlyOne', | |
196 | ]); | |
197 | CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM']; | |
198 | $testEntities = [ | |
199 | 'Email' => ['email' => 'null@nothing', 'location_type_id' => 1], | |
200 | 'Phone' => ['phone' => '123456', 'location_type_id' => 1], | |
201 | 'IM' => ['name' => 'hello', 'location_type_id' => 1], | |
202 | 'Website' => ['url' => 'http://test'], | |
203 | 'Address' => [ | |
204 | 'street_address' => '123 Sesame St.', | |
205 | 'location_type_id' => 1, | |
206 | ], | |
207 | ]; | |
c16ed19b | 208 | foreach ($testEntities as $entity => $params) { |
ff3833b0 | 209 | $params += [ |
c16ed19b CW |
210 | 'contact_id' => $disallowedContact, |
211 | 'check_permissions' => 1, | |
ff3833b0 | 212 | ]; |
c16ed19b CW |
213 | // We should be prevented from getting or creating entities for a contact we don't have permission for |
214 | $this->callAPIFailure($entity, 'create', $params); | |
ff3833b0 | 215 | $this->callAPISuccess($entity, 'create', ['check_permissions' => 0] + $params); |
216 | $results = $this->callAPISuccess($entity, 'get', [ | |
217 | 'contact_id' => $disallowedContact, | |
218 | 'check_permissions' => 1, | |
219 | ]); | |
c16ed19b CW |
220 | $this->assertEquals(0, $results['count']); |
221 | ||
222 | // We should be allowed to create and get for contacts we do have permission on | |
223 | $params['contact_id'] = $this->allowedContactId; | |
224 | $this->callAPISuccess($entity, 'create', $params); | |
ff3833b0 | 225 | $results = $this->callAPISuccess($entity, 'get', [ |
226 | 'contact_id' => $this->allowedContactId, | |
227 | 'check_permissions' => 1, | |
228 | ]); | |
c16ed19b CW |
229 | $this->assertGreaterThan(0, $results['count']); |
230 | } | |
ff3833b0 | 231 | $newTag = civicrm_api3('Tag', 'create', [ |
c6835264 | 232 | 'name' => 'Foo123', |
ff3833b0 | 233 | ]); |
234 | $relatedEntities = [ | |
235 | 'Note' => ['note' => 'abc'], | |
236 | 'EntityTag' => ['tag_id' => $newTag['id']], | |
237 | ]; | |
c6835264 | 238 | foreach ($relatedEntities as $entity => $params) { |
ff3833b0 | 239 | $params += [ |
c6835264 CW |
240 | 'entity_id' => $disallowedContact, |
241 | 'entity_table' => 'civicrm_contact', | |
242 | 'check_permissions' => 1, | |
ff3833b0 | 243 | ]; |
c6835264 CW |
244 | // We should be prevented from getting or creating entities for a contact we don't have permission for |
245 | $this->callAPIFailure($entity, 'create', $params); | |
ff3833b0 | 246 | $this->callAPISuccess($entity, 'create', ['check_permissions' => 0] + $params); |
247 | $results = $this->callAPISuccess($entity, 'get', [ | |
248 | 'entity_id' => $disallowedContact, | |
249 | 'entity_table' => 'civicrm_contact', | |
250 | 'check_permissions' => 1, | |
251 | ]); | |
c6835264 CW |
252 | $this->assertEquals(0, $results['count']); |
253 | ||
254 | // We should be allowed to create and get for entities we do have permission on | |
255 | $params['entity_id'] = $this->allowedContactId; | |
256 | $this->callAPISuccess($entity, 'create', $params); | |
ff3833b0 | 257 | $results = $this->callAPISuccess($entity, 'get', [ |
258 | 'entity_id' => $this->allowedContactId, | |
259 | 'entity_table' => 'civicrm_contact', | |
260 | 'check_permissions' => 1, | |
261 | ]); | |
c6835264 CW |
262 | $this->assertGreaterThan(0, $results['count']); |
263 | } | |
c16ed19b CW |
264 | } |
265 | ||
6a488035 | 266 | /** |
eceb18cc | 267 | * Function tests all results are returned. |
82fd72da | 268 | * |
2d932085 | 269 | * @param int $version |
82fd72da | 270 | * |
2d932085 | 271 | * @dataProvider versionThreeAndFour |
82fd72da | 272 | * @throws \CRM_Core_Exception |
7884d958 | 273 | */ |
2d932085 CW |
274 | public function testContactGetAllResultsHook($version) { |
275 | $this->_apiversion = $version; | |
ff3833b0 | 276 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
277 | $this, | |
278 | 'aclWhereHookAllResults', | |
279 | ]); | |
280 | $result = $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 281 | 'check_permissions' => 1, |
282 | 'return' => 'display_name', | |
ff3833b0 | 283 | ]); |
6a488035 | 284 | |
6a488035 TO |
285 | $this->assertEquals(2, $result['count']); |
286 | } | |
7884d958 | 287 | |
6a488035 | 288 | /** |
eceb18cc | 289 | * Function tests that deleted contacts are not returned. |
82fd72da | 290 | * |
2d932085 | 291 | * @param int $version |
82fd72da | 292 | * |
2d932085 | 293 | * @dataProvider versionThreeAndFour |
82fd72da | 294 | * @throws \CRM_Core_Exception |
7884d958 | 295 | */ |
2d932085 CW |
296 | public function testContactGetPermissionHookNoDeleted($version) { |
297 | $this->_apiversion = $version; | |
ff3833b0 | 298 | $this->callAPISuccess('contact', 'create', ['id' => 2, 'is_deleted' => 1]); |
299 | $this->hookClass->setHook('civicrm_aclWhereClause', [ | |
300 | $this, | |
301 | 'aclWhereHookAllResults', | |
302 | ]); | |
303 | $result = $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 304 | 'check_permissions' => 1, |
305 | 'return' => 'display_name', | |
ff3833b0 | 306 | ]); |
6a488035 TO |
307 | $this->assertEquals(1, $result['count']); |
308 | } | |
309 | ||
310 | /** | |
eceb18cc | 311 | * Test permissions limited by hook. |
82fd72da | 312 | * |
2d932085 | 313 | * @param int $version |
82fd72da | 314 | * |
2d932085 | 315 | * @dataProvider versionThreeAndFour |
82fd72da | 316 | * @throws \CRM_Core_Exception |
6a488035 | 317 | */ |
2d932085 CW |
318 | public function testContactGetHookLimitingHook($version) { |
319 | $this->_apiversion = $version; | |
ff3833b0 | 320 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
321 | $this, | |
322 | 'aclWhereOnlySecond', | |
323 | ]); | |
6a488035 | 324 | |
ff3833b0 | 325 | $result = $this->callAPISuccess('contact', 'get', [ |
6a488035 TO |
326 | 'check_permissions' => 1, |
327 | 'return' => 'display_name', | |
ff3833b0 | 328 | ]); |
6a488035 TO |
329 | $this->assertEquals(1, $result['count']); |
330 | } | |
331 | ||
7884d958 | 332 | /** |
1028f75e | 333 | * Confirm that without check permissions we still get 2 contacts returned. |
82fd72da | 334 | * |
2d932085 | 335 | * @param int $version |
82fd72da | 336 | * |
2d932085 | 337 | * @dataProvider versionThreeAndFour |
82fd72da | 338 | * @throws \CRM_Core_Exception |
7884d958 | 339 | */ |
2d932085 CW |
340 | public function testContactGetHookLimitingHookDontCheck($version) { |
341 | $this->_apiversion = $version; | |
ff3833b0 | 342 | $result = $this->callAPISuccess('contact', 'get', [ |
4e420887 | 343 | 'check_permissions' => 0, |
344 | 'return' => 'display_name', | |
ff3833b0 | 345 | ]); |
6a488035 TO |
346 | $this->assertEquals(2, $result['count']); |
347 | } | |
7884d958 | 348 | |
6a488035 | 349 | /** |
eceb18cc | 350 | * Check that id works as a filter. |
2d932085 CW |
351 | * @param int $version |
352 | * @dataProvider versionThreeAndFour | |
6a488035 | 353 | */ |
2d932085 CW |
354 | public function testContactGetIDFilter($version) { |
355 | $this->_apiversion = $version; | |
ff3833b0 | 356 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
357 | $this, | |
358 | 'aclWhereHookAllResults', | |
359 | ]); | |
360 | $result = $this->callAPISuccess('contact', 'get', [ | |
6a488035 TO |
361 | 'sequential' => 1, |
362 | 'id' => 2, | |
363 | 'check_permissions' => 1, | |
ff3833b0 | 364 | ]); |
6a488035 | 365 | |
6a488035 TO |
366 | $this->assertEquals(1, $result['count']); |
367 | $this->assertEquals(2, $result['id']); | |
368 | } | |
369 | ||
7884d958 | 370 | /** |
eceb18cc | 371 | * Check that address IS returned. |
7884d958 | 372 | */ |
00be9182 | 373 | public function testContactGetAddressReturned() { |
ff3833b0 | 374 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
375 | $this, | |
376 | 'aclWhereOnlySecond', | |
377 | ]); | |
378 | $fullresult = $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 379 | 'sequential' => 1, |
ff3833b0 | 380 | ]); |
7884d958 | 381 | //return doesn't work for all keys - can't fix that here so let's skip ... |
382 | //prefix & suffix are inconsistent due to CRM-7929 | |
383 | // unsure about others but return doesn't work on them | |
ff3833b0 | 384 | $elementsReturnDoesntSupport = [ |
7884d958 | 385 | 'prefix', |
7884d958 | 386 | 'suffix', |
7884d958 | 387 | 'gender', |
388 | 'current_employer', | |
389 | 'phone_id', | |
390 | 'phone_type_id', | |
391 | 'phone', | |
392 | 'worldregion_id', | |
21dfd5f5 | 393 | 'world_region', |
ff3833b0 | 394 | ]; |
7884d958 | 395 | $expectedReturnElements = array_diff(array_keys($fullresult['values'][0]), $elementsReturnDoesntSupport); |
ff3833b0 | 396 | $result = $this->callAPISuccess('contact', 'get', [ |
7884d958 | 397 | 'check_permissions' => 1, |
398 | 'return' => $expectedReturnElements, | |
399 | 'sequential' => 1, | |
ff3833b0 | 400 | ]); |
7884d958 | 401 | $this->assertEquals(1, $result['count']); |
402 | foreach ($expectedReturnElements as $element) { | |
403 | $this->assertArrayHasKey($element, $result['values'][0]); | |
6a488035 | 404 | } |
7884d958 | 405 | } |
406 | ||
407 | /** | |
eceb18cc | 408 | * Check that pledge IS not returned. |
2d932085 CW |
409 | * @param int $version |
410 | * @dataProvider versionThreeAndFour | |
7884d958 | 411 | */ |
2d932085 CW |
412 | public function testContactGetPledgeIDNotReturned($version) { |
413 | $this->_apiversion = $version; | |
ff3833b0 | 414 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
415 | $this, | |
416 | 'aclWhereHookAllResults', | |
417 | ]); | |
418 | $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 419 | 'sequential' => 1, |
ff3833b0 | 420 | ]); |
421 | $result = $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 422 | 'check_permissions' => 1, |
423 | 'return' => 'pledge_id', | |
424 | 'sequential' => 1, | |
ff3833b0 | 425 | ]); |
7884d958 | 426 | $this->assertArrayNotHasKey('pledge_id', $result['values'][0]); |
427 | } | |
6a488035 | 428 | |
7884d958 | 429 | /** |
eceb18cc | 430 | * Check that pledge IS not an allowable filter. |
7884d958 | 431 | */ |
00be9182 | 432 | public function testContactGetPledgeIDNotFiltered() { |
ff3833b0 | 433 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
434 | $this, | |
435 | 'aclWhereHookAllResults', | |
436 | ]); | |
437 | $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 438 | 'sequential' => 1, |
ff3833b0 | 439 | ]); |
440 | $result = $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 441 | 'check_permissions' => 1, |
442 | 'pledge_id' => 1, | |
443 | 'sequential' => 1, | |
ff3833b0 | 444 | ]); |
7884d958 | 445 | $this->assertEquals(2, $result['count']); |
446 | } | |
447 | ||
448 | /** | |
449 | * Check that chaining doesn't bypass permissions | |
82fd72da | 450 | * |
2d932085 | 451 | * @param int $version |
82fd72da | 452 | * |
2d932085 | 453 | * @dataProvider versionThreeAndFour |
82fd72da | 454 | * @throws \CRM_Core_Exception |
7884d958 | 455 | */ |
7c86e53f | 456 | public function testContactGetPledgeNotChainable(int $version): void { |
2d932085 | 457 | $this->_apiversion = $version; |
ff3833b0 | 458 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
459 | $this, | |
460 | 'aclWhereOnlySecond', | |
461 | ]); | |
462 | $this->callAPISuccess('contact', 'get', [ | |
7884d958 | 463 | 'sequential' => 1, |
ff3833b0 | 464 | ]); |
465 | $this->callAPIFailure('contact', 'get', [ | |
466 | 'check_permissions' => 1, | |
467 | 'api.pledge.get' => 1, | |
468 | 'sequential' => 1, | |
469 | ], | |
d235daf6 | 470 | 'Error in call to Pledge_get : API permission check failed for Pledge/get call; insufficient permission: require access CiviCRM and access CiviPledge' |
7884d958 | 471 | ); |
472 | } | |
6a488035 | 473 | |
00be9182 | 474 | public function setupCoreACL() { |
ae4bb4c9 | 475 | $this->createLoggedInUser(); |
ff3833b0 | 476 | $this->_permissionedDisabledGroup = $this->groupCreate([ |
92915c55 TO |
477 | 'title' => 'pick-me-disabled', |
478 | 'is_active' => 0, | |
479 | 'name' => 'pick-me-disabled', | |
ff3833b0 | 480 | ]); |
481 | $this->_permissionedGroup = $this->groupCreate([ | |
92915c55 TO |
482 | 'title' => 'pick-me-active', |
483 | 'is_active' => 1, | |
484 | 'name' => 'pick-me-active', | |
ff3833b0 | 485 | ]); |
ae4bb4c9 EM |
486 | $this->setupACL(); |
487 | } | |
5896d037 | 488 | |
ae4bb4c9 EM |
489 | /** |
490 | * @dataProvider entities | |
491 | * confirm that without check permissions we still get 2 contacts returned | |
82fd72da | 492 | * |
493 | * @param string $entity | |
494 | * | |
495 | * @throws \CRM_Core_Exception | |
ae4bb4c9 | 496 | */ |
00be9182 | 497 | public function testEntitiesGetHookLimitingHookNoCheck($entity) { |
ff3833b0 | 498 | CRM_Core_Config::singleton()->userPermissionClass->permissions = []; |
ae4bb4c9 | 499 | $this->setUpEntities($entity); |
ff3833b0 | 500 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
501 | $this, | |
502 | 'aclWhereHookNoResults', | |
503 | ]); | |
504 | $result = $this->callAPISuccess($entity, 'get', [ | |
ae4bb4c9 EM |
505 | 'check_permissions' => 0, |
506 | 'return' => 'contact_id', | |
ff3833b0 | 507 | ]); |
ae4bb4c9 EM |
508 | $this->assertEquals(2, $result['count']); |
509 | } | |
510 | ||
511 | /** | |
512 | * @dataProvider entities | |
513 | * confirm that without check permissions we still get 2 entities returned | |
1e1fdcf6 | 514 | * @param $entity |
ae4bb4c9 | 515 | */ |
00be9182 | 516 | public function testEntitiesGetCoreACLLimitingHookNoCheck($entity) { |
ae4bb4c9 EM |
517 | $this->setupCoreACL(); |
518 | //CRM_Core_Config::singleton()->userPermissionClass->permissions = array(); | |
519 | $this->setUpEntities($entity); | |
ff3833b0 | 520 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
521 | $this, | |
522 | 'aclWhereHookNoResults', | |
523 | ]); | |
524 | $result = $this->callAPISuccess($entity, 'get', [ | |
ae4bb4c9 EM |
525 | 'check_permissions' => 0, |
526 | 'return' => 'contact_id', | |
ff3833b0 | 527 | ]); |
ae4bb4c9 EM |
528 | $this->assertEquals(2, $result['count']); |
529 | } | |
5896d037 | 530 | |
ae4bb4c9 EM |
531 | /** |
532 | * @dataProvider entities | |
533 | * confirm that with check permissions we don't get entities | |
82fd72da | 534 | * |
1e1fdcf6 | 535 | * @param $entity |
82fd72da | 536 | * |
a6439b6a | 537 | * @throws \PHPUnit\Framework\IncompleteTestError |
82fd72da | 538 | * @throws \CRM_Core_Exception |
ae4bb4c9 | 539 | */ |
00be9182 | 540 | public function testEntitiesGetCoreACLLimitingCheck($entity) { |
ae4bb4c9 EM |
541 | $this->setupCoreACL(); |
542 | $this->setUpEntities($entity); | |
ff3833b0 | 543 | $result = $this->callAPISuccess($entity, 'get', [ |
ae4bb4c9 EM |
544 | 'check_permissions' => 1, |
545 | 'return' => 'contact_id', | |
ff3833b0 | 546 | ]); |
ae4bb4c9 EM |
547 | $this->assertEquals(0, $result['count']); |
548 | } | |
549 | ||
ae4bb4c9 EM |
550 | /** |
551 | * @dataProvider entities | |
552 | * Function tests that an empty where hook returns no results | |
82fd72da | 553 | * |
1028f75e | 554 | * @param string $entity |
82fd72da | 555 | * |
a6439b6a | 556 | * @throws \PHPUnit\Framework\IncompleteTestError |
82fd72da | 557 | * @throws \CRM_Core_Exception |
ae4bb4c9 | 558 | */ |
00be9182 | 559 | public function testEntityGetNoResultsHook($entity) { |
ae4bb4c9 | 560 | $this->markTestIncomplete('hook acls only work with contacts so far'); |
ff3833b0 | 561 | CRM_Core_Config::singleton()->userPermissionClass->permissions = []; |
ae4bb4c9 | 562 | $this->setUpEntities($entity); |
ff3833b0 | 563 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
564 | $this, | |
565 | 'aclWhereHookNoResults', | |
566 | ]); | |
567 | $result = $this->callAPISuccess($entity, 'get', [ | |
ae4bb4c9 | 568 | 'check_permission' => 1, |
ff3833b0 | 569 | ]); |
ae4bb4c9 EM |
570 | $this->assertEquals(0, $result['count']); |
571 | } | |
572 | ||
573 | /** | |
574 | * @return array | |
575 | */ | |
576 | public static function entities() { | |
ff3833b0 | 577 | return [ |
578 | ['contribution'], | |
579 | ['participant'], | |
39b959db SL |
580 | // @todo array('pledge' => 'pledge') |
581 | ]; | |
ae4bb4c9 EM |
582 | } |
583 | ||
584 | /** | |
82fd72da | 585 | * Create 2 entities. |
586 | * | |
587 | * @param string $entity | |
ae4bb4c9 EM |
588 | */ |
589 | public function setUpEntities($entity) { | |
82fd72da | 590 | CRM_Core_DAO::createTestObject(_civicrm_api3_get_BAO($entity), [], 2, 0); |
ff3833b0 | 591 | CRM_Core_Config::singleton()->userPermissionClass->permissions = [ |
ae4bb4c9 EM |
592 | 'access CiviCRM', |
593 | 'access CiviContribute', | |
594 | 'access CiviEvent', | |
595 | 'view event participants', | |
ff3833b0 | 596 | ]; |
ae4bb4c9 EM |
597 | } |
598 | ||
bbd2743b | 599 | /** |
82fd72da | 600 | * Basic check that an un-permissioned call keeps working and permissioned call fails. |
601 | * | |
2d932085 | 602 | * @param int $version |
82fd72da | 603 | * |
2d932085 | 604 | * @dataProvider versionThreeAndFour |
82fd72da | 605 | * @throws \CRM_Core_Exception |
bbd2743b | 606 | */ |
2d932085 CW |
607 | public function testGetActivityNoPermissions($version) { |
608 | $this->_apiversion = $version; | |
ff3833b0 | 609 | $this->setPermissions([]); |
82fd72da | 610 | $this->callAPISuccess('Activity', 'get'); |
ff3833b0 | 611 | $this->callAPIFailure('Activity', 'get', ['check_permissions' => 1]); |
bbd2743b | 612 | } |
613 | ||
614 | /** | |
615 | * View all activities is enough regardless of contact ACLs. | |
82fd72da | 616 | * |
2d932085 | 617 | * @param int $version |
82fd72da | 618 | * |
619 | * @throws \CRM_Core_Exception | |
620 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 621 | * @dataProvider versionThreeAndFour |
bbd2743b | 622 | */ |
2d932085 CW |
623 | public function testGetActivityViewAllActivitiesDoesntCutItAnymore($version) { |
624 | $this->_apiversion = $version; | |
bbd2743b | 625 | $activity = $this->activityCreate(); |
ff3833b0 | 626 | $this->setPermissions(['view all activities', 'access CiviCRM']); |
627 | $this->callAPISuccessGetCount('Activity', [ | |
628 | 'check_permissions' => 1, | |
629 | 'id' => $activity['id'], | |
630 | ], 0); | |
bbd2743b | 631 | } |
632 | ||
633 | /** | |
634 | * View all activities is required unless id is passed in. | |
82fd72da | 635 | * |
2d932085 | 636 | * @param int $version |
82fd72da | 637 | * |
2d932085 | 638 | * @dataProvider versionThreeAndFour |
82fd72da | 639 | * @throws \CRM_Core_Exception |
bbd2743b | 640 | */ |
2d932085 CW |
641 | public function testGetActivityViewAllContactsEnoughWithoutID($version) { |
642 | $this->_apiversion = $version; | |
ff3833b0 | 643 | $this->setPermissions(['view all contacts', 'access CiviCRM']); |
644 | $this->callAPISuccess('Activity', 'get', ['check_permissions' => 1]); | |
bbd2743b | 645 | } |
646 | ||
647 | /** | |
3af8de9f | 648 | * Without view all activities contact level acls are used. |
82fd72da | 649 | * |
2d932085 | 650 | * @param int $version |
82fd72da | 651 | * |
652 | * @throws \CRM_Core_Exception | |
653 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 654 | * @dataProvider versionThreeAndFour |
bbd2743b | 655 | */ |
2d932085 CW |
656 | public function testGetActivityViewAllContactsEnoughWIthID($version) { |
657 | $this->_apiversion = $version; | |
bbd2743b | 658 | $activity = $this->activityCreate(); |
ff3833b0 | 659 | $this->setPermissions(['view all contacts', 'access CiviCRM']); |
660 | $this->callAPISuccess('Activity', 'getsingle', [ | |
661 | 'check_permissions' => 1, | |
662 | 'id' => $activity['id'], | |
663 | ]); | |
bbd2743b | 664 | } |
665 | ||
666 | /** | |
00e2484d | 667 | * Check the error message is not a permission error. |
82fd72da | 668 | * |
2d932085 | 669 | * @param int $version |
82fd72da | 670 | * |
671 | * @throws \CRM_Core_Exception | |
672 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 673 | * @dataProvider versionThreeAndFour |
bbd2743b | 674 | */ |
2d932085 CW |
675 | public function testGetActivityAccessCiviCRMEnough($version) { |
676 | $this->_apiversion = $version; | |
bbd2743b | 677 | $activity = $this->activityCreate(); |
ff3833b0 | 678 | $this->setPermissions(['access CiviCRM']); |
679 | $this->callAPIFailure('Activity', 'getsingle', [ | |
680 | 'check_permissions' => 1, | |
681 | 'id' => $activity['id'], | |
00e2484d | 682 | ], 'Expected one Activity but found 0'); |
683 | $this->callAPISuccessGetCount('Activity', [ | |
684 | 'check_permissions' => 1, | |
685 | 'id' => $activity['id'], | |
686 | ], 0); | |
bbd2743b | 687 | } |
688 | ||
3af8de9f | 689 | /** |
690 | * Check that component related activity filtering. | |
691 | * | |
692 | * If the contact does NOT have permission to 'view all contacts' but they DO have permission | |
693 | * to view the contact in question they will only see the activities of components they have access too. | |
694 | * | |
695 | * (logically the same component limit should apply when they have access to view all too but.... | |
696 | * adding test for 'how it is at the moment.) | |
82fd72da | 697 | * |
2d932085 | 698 | * @param int $version |
82fd72da | 699 | * |
700 | * @throws \CRM_Core_Exception | |
701 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 702 | * @dataProvider versionThreeAndFour |
3af8de9f | 703 | */ |
2d932085 CW |
704 | public function testGetActivityCheckPermissionsByComponent($version) { |
705 | $this->_apiversion = $version; | |
3af8de9f | 706 | $activity = $this->activityCreate(['activity_type_id' => 'Contribution']); |
707 | $activity2 = $this->activityCreate(['activity_type_id' => 'Pledge Reminder']); | |
ff3833b0 | 708 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
709 | $this, | |
710 | 'aclWhereHookAllResults', | |
711 | ]); | |
3af8de9f | 712 | $this->setPermissions(['access CiviCRM', 'access CiviContribute']); |
ff3833b0 | 713 | $this->callAPISuccessGetSingle('Activity', [ |
714 | 'check_permissions' => 1, | |
715 | 'id' => ['IN' => [$activity['id'], $activity2['id']]], | |
716 | ]); | |
717 | $this->callAPISuccessGetCount('Activity', [ | |
718 | 'check_permissions' => 1, | |
719 | 'id' => ['IN' => [$activity['id'], $activity2['id']]], | |
720 | ], 1); | |
ff2a3553 | 721 | |
3af8de9f | 722 | } |
723 | ||
c4937fe9 | 724 | /** |
725 | * Check that component related activity filtering works for CiviCase. | |
82fd72da | 726 | * |
2d932085 | 727 | * @param int $version |
82fd72da | 728 | * |
729 | * @throws \CRM_Core_Exception | |
730 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 731 | * @dataProvider versionThreeAndFour |
c4937fe9 | 732 | */ |
2d932085 CW |
733 | public function testGetActivityCheckPermissionsByCaseComponent($version) { |
734 | $this->_apiversion = $version; | |
c4937fe9 | 735 | CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase'); |
736 | $activity = $this->activityCreate(['activity_type_id' => 'Open Case']); | |
737 | $activity2 = $this->activityCreate(['activity_type_id' => 'Pledge Reminder']); | |
ff3833b0 | 738 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
739 | $this, | |
740 | 'aclWhereHookAllResults', | |
741 | ]); | |
742 | $this->setPermissions([ | |
743 | 'access CiviCRM', | |
744 | 'access CiviContribute', | |
745 | 'access all cases and activities', | |
746 | ]); | |
747 | $this->callAPISuccessGetSingle('Activity', [ | |
748 | 'check_permissions' => 1, | |
749 | 'id' => ['IN' => [$activity['id'], $activity2['id']]], | |
750 | ]); | |
751 | $this->callAPISuccessGetCount('Activity', [ | |
752 | 'check_permissions' => 1, | |
753 | 'id' => ['IN' => [$activity['id'], $activity2['id']]], | |
754 | ], 1); | |
c4937fe9 | 755 | } |
756 | ||
bbd2743b | 757 | /** |
758 | * Check that activities can be retrieved by ACL. | |
759 | * | |
760 | * The activities api applies ACLs in a very limited circumstance, if id is passed in. | |
761 | * Otherwise it sticks with the blunt original permissions. | |
82fd72da | 762 | * |
2d932085 | 763 | * @param int $version |
82fd72da | 764 | * |
765 | * @throws \CRM_Core_Exception | |
766 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 767 | * @dataProvider versionThreeAndFour |
bbd2743b | 768 | */ |
2d932085 CW |
769 | public function testGetActivityByACL($version) { |
770 | $this->_apiversion = $version; | |
ff3833b0 | 771 | $this->setPermissions(['access CiviCRM']); |
bbd2743b | 772 | $activity = $this->activityCreate(); |
773 | ||
ff3833b0 | 774 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
775 | $this, | |
776 | 'aclWhereHookAllResults', | |
777 | ]); | |
778 | $this->callAPISuccessGetSingle('Activity', [ | |
779 | 'check_permissions' => 1, | |
780 | 'id' => $activity['id'], | |
781 | ]); | |
782 | $this->callAPISuccessGetCount('Activity', [ | |
783 | 'check_permissions' => 1, | |
784 | 'id' => $activity['id'], | |
785 | ]); | |
bbd2743b | 786 | } |
787 | ||
788 | /** | |
cdacd6ab | 789 | * To leverage ACL permission to view an activity you must be able to see any of the contacts. |
2d932085 | 790 | * FIXME: Api4 |
bbd2743b | 791 | */ |
792 | public function testGetActivityByAclCannotViewAllContacts() { | |
cdacd6ab | 793 | $activity = $this->activityCreate(['assignee_contact_id' => $this->individualCreate()]); |
794 | $contacts = $this->getActivityContacts($activity); | |
795 | $this->setPermissions(['access CiviCRM']); | |
796 | ||
797 | foreach ($contacts as $role => $contact_id) { | |
798 | $this->allowedContactId = $contact_id; | |
ff3833b0 | 799 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
800 | $this, | |
801 | 'aclWhereOnlyOne', | |
802 | ]); | |
cdacd6ab | 803 | $this->cleanupCachedPermissions(); |
804 | $result = $this->callAPISuccessGetSingle('Activity', [ | |
805 | 'check_permissions' => 1, | |
806 | 'id' => $activity['id'], | |
ff3833b0 | 807 | 'return' => [ |
808 | 'source_contact_id', | |
809 | 'target_contact_id', | |
810 | 'assignee_contact_id', | |
811 | ], | |
cdacd6ab | 812 | ]); |
ff3833b0 | 813 | foreach ([ |
39b959db SL |
814 | 'source_contact', |
815 | 'target_contact', | |
816 | 'assignee_contact', | |
817 | ] as $roleName) { | |
cdacd6ab | 818 | $roleKey = $roleName . '_id'; |
819 | if ($role !== $roleKey) { | |
820 | $this->assertTrue(empty($result[$roleKey]), "Only contact in $role is permissioned to be returned, not $roleKey"); | |
821 | } | |
822 | else { | |
823 | $this->assertEquals([$contact_id], (array) $result[$roleKey]); | |
82fd72da | 824 | $this->assertNotEmpty($result[$roleName . '_name']); |
cdacd6ab | 825 | } |
826 | } | |
827 | } | |
828 | } | |
829 | ||
830 | /** | |
831 | * To leverage ACL permission to view an activity you must be able to see any of the contacts. | |
82fd72da | 832 | * |
2d932085 | 833 | * @param int $version |
82fd72da | 834 | * |
835 | * @throws \CRM_Core_Exception | |
836 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 837 | * @dataProvider versionThreeAndFour |
cdacd6ab | 838 | */ |
2d932085 CW |
839 | public function testGetActivityByAclCannotViewAnyContacts($version) { |
840 | $this->_apiversion = $version; | |
bbd2743b | 841 | $activity = $this->activityCreate(); |
842 | $contacts = $this->getActivityContacts($activity); | |
ff3833b0 | 843 | $this->setPermissions(['access CiviCRM']); |
bbd2743b | 844 | |
845 | foreach ($contacts as $contact_id) { | |
ff3833b0 | 846 | $this->callAPIFailure('Activity', 'getsingle', [ |
847 | 'check_permissions' => 1, | |
848 | 'id' => $activity['id'], | |
849 | ]); | |
bbd2743b | 850 | } |
851 | } | |
852 | ||
853 | /** | |
854 | * Check that if the source contact is deleted but we can view the others we can see the activity. | |
855 | * | |
856 | * CRM-18409. | |
857 | * | |
2d932085 | 858 | * @param int $version |
82fd72da | 859 | * |
2d932085 | 860 | * @dataProvider versionThreeAndFour |
82fd72da | 861 | * @throws \CiviCRM_API3_Exception |
862 | * @throws \CRM_Core_Exception | |
bbd2743b | 863 | */ |
2d932085 CW |
864 | public function testGetActivityACLSourceContactDeleted($version) { |
865 | $this->_apiversion = $version; | |
ff3833b0 | 866 | $this->setPermissions(['access CiviCRM', 'delete contacts']); |
bbd2743b | 867 | $activity = $this->activityCreate(); |
868 | $contacts = $this->getActivityContacts($activity); | |
869 | ||
ff3833b0 | 870 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
871 | $this, | |
872 | 'aclWhereHookAllResults', | |
873 | ]); | |
bbd2743b | 874 | $this->contactDelete($contacts['source_contact_id']); |
ff3833b0 | 875 | $this->callAPISuccess('Activity', 'getsingle', [ |
876 | 'check_permissions' => 1, | |
877 | 'id' => $activity['id'], | |
878 | ]); | |
bbd2743b | 879 | } |
880 | ||
f404486e SL |
881 | /** |
882 | * Test get activities multiple ids with check permissions | |
82fd72da | 883 | * |
0e480632 | 884 | * @see https://issues.civicrm.org/jira/browse/CRM-20441 |
82fd72da | 885 | * |
2d932085 | 886 | * @param int $version |
82fd72da | 887 | * |
888 | * @throws \CRM_Core_Exception | |
889 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 890 | * @dataProvider versionThreeAndFour |
f404486e | 891 | */ |
2d932085 CW |
892 | public function testActivitiesGetMultipleIdsCheckPermissions($version) { |
893 | $this->_apiversion = $version; | |
f404486e SL |
894 | $this->createLoggedInUser(); |
895 | $activity = $this->activityCreate(); | |
896 | $activity2 = $this->activityCreate(); | |
ff3833b0 | 897 | $this->setPermissions(['access CiviCRM']); |
898 | $this->hookClass->setHook('civicrm_aclWhereClause', [ | |
899 | $this, | |
900 | 'aclWhereHookAllResults', | |
901 | ]); | |
f404486e | 902 | // Get activities associated with contact $this->_contactID. |
ff3833b0 | 903 | $params = [ |
904 | 'id' => ['IN' => [$activity['id'], $activity2['id']]], | |
f404486e | 905 | 'check_permissions' => TRUE, |
ff3833b0 | 906 | ]; |
f404486e SL |
907 | $result = $this->callAPISuccess('activity', 'get', $params); |
908 | $this->assertEquals(2, $result['count']); | |
909 | } | |
910 | ||
911 | /** | |
912 | * Test get activities multiple ids with check permissions | |
913 | * Limit access to One contact | |
82fd72da | 914 | * |
0e480632 | 915 | * @see https://issues.civicrm.org/jira/browse/CRM-20441 |
82fd72da | 916 | * |
2d932085 | 917 | * @param int $version |
82fd72da | 918 | * |
919 | * @throws \CRM_Core_Exception | |
920 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 921 | * @dataProvider versionThreeAndFour |
f404486e | 922 | */ |
2d932085 CW |
923 | public function testActivitiesGetMultipleIdsCheckPermissionsLimitedACL($version) { |
924 | $this->_apiversion = $version; | |
f404486e SL |
925 | $this->createLoggedInUser(); |
926 | $activity = $this->activityCreate(); | |
927 | $contacts = $this->getActivityContacts($activity); | |
ff3833b0 | 928 | $this->setPermissions(['access CiviCRM']); |
f404486e SL |
929 | foreach ($contacts as $contact_id) { |
930 | $this->allowedContacts[] = $contact_id; | |
931 | } | |
ff3833b0 | 932 | $this->hookClass->setHook('civicrm_aclWhereClause', [ |
933 | $this, | |
934 | 'aclWhereMultipleContacts', | |
935 | ]); | |
f404486e | 936 | $contact2 = $this->individualCreate(); |
ff3833b0 | 937 | $activity2 = $this->activityCreate(['source_contact_id' => $contact2]); |
f404486e | 938 | // Get activities associated with contact $this->_contactID. |
ff3833b0 | 939 | $params = [ |
940 | 'id' => ['IN' => [$activity['id']]], | |
f404486e | 941 | 'check_permissions' => TRUE, |
ff3833b0 | 942 | ]; |
f404486e SL |
943 | $result = $this->callAPISuccess('activity', 'get', $params); |
944 | $this->assertEquals(1, $result['count']); | |
2d932085 | 945 | $this->callAPIFailure('activity', 'getsingle', array_merge($params, [ |
ff3833b0 | 946 | 'id' => [ |
118ce7f5 | 947 | 'IN' => [$activity2['id']], |
ff3833b0 | 948 | ], |
949 | ])); | |
f404486e SL |
950 | } |
951 | ||
dfe0e2e1 SL |
952 | /** |
953 | * Test get activities multiple ids with check permissions | |
82fd72da | 954 | * |
0e480632 | 955 | * @see https://issues.civicrm.org/jira/browse/CRM-20441 |
82fd72da | 956 | * |
2d932085 | 957 | * @param int $version |
82fd72da | 958 | * |
959 | * @throws \CRM_Core_Exception | |
960 | * @throws \CiviCRM_API3_Exception | |
2d932085 | 961 | * @dataProvider versionThreeAndFour |
dfe0e2e1 | 962 | */ |
2d932085 CW |
963 | public function testActivitiesGetMultipleIdsCheckPermissionsNotIN($version) { |
964 | $this->_apiversion = $version; | |
dfe0e2e1 SL |
965 | $this->createLoggedInUser(); |
966 | $activity = $this->activityCreate(); | |
967 | $activity2 = $this->activityCreate(); | |
ff3833b0 | 968 | $this->setPermissions(['access CiviCRM']); |
969 | $this->hookClass->setHook('civicrm_aclWhereClause', [ | |
970 | $this, | |
971 | 'aclWhereHookAllResults', | |
972 | ]); | |
dfe0e2e1 | 973 | // Get activities associated with contact $this->_contactID. |
ff3833b0 | 974 | $params = [ |
975 | 'id' => ['NOT IN' => [$activity['id'], $activity2['id']]], | |
dfe0e2e1 | 976 | 'check_permissions' => TRUE, |
ff3833b0 | 977 | ]; |
3c9d67b0 | 978 | $result = $this->callAPISuccess('activity', 'get', $params); |
979 | $this->assertEquals(0, $result['count']); | |
dfe0e2e1 SL |
980 | } |
981 | ||
bbd2743b | 982 | /** |
983 | * Get the contacts for the activity. | |
984 | * | |
985 | * @param $activity | |
986 | * | |
987 | * @return array | |
988 | * @throws \CRM_Core_Exception | |
989 | */ | |
990 | protected function getActivityContacts($activity) { | |
ff3833b0 | 991 | $contacts = []; |
bbd2743b | 992 | |
ff3833b0 | 993 | $activityContacts = $this->callAPISuccess('ActivityContact', 'get', [ |
39b959db SL |
994 | 'activity_id' => $activity['id'], |
995 | ]); | |
bbd2743b | 996 | |
ff3833b0 | 997 | $activityRecordTypes = $this->callAPISuccess('ActivityContact', 'getoptions', ['field' => 'record_type_id']); |
bbd2743b | 998 | foreach ($activityContacts['values'] as $activityContact) { |
999 | $type = $activityRecordTypes['values'][$activityContact['record_type_id']]; | |
1000 | switch ($type) { | |
1001 | case 'Activity Source': | |
1002 | $contacts['source_contact_id'] = $activityContact['contact_id']; | |
1003 | break; | |
1004 | ||
1005 | case 'Activity Targets': | |
1006 | $contacts['target_contact_id'] = $activityContact['contact_id']; | |
1007 | break; | |
1008 | ||
1009 | case 'Activity Assignees': | |
1010 | $contacts['assignee_contact_id'] = $activityContact['contact_id']; | |
1011 | break; | |
1012 | ||
1013 | } | |
1014 | } | |
1015 | return $contacts; | |
1016 | } | |
1017 | ||
8e12938a | 1018 | /** |
1019 | * Test that the 'everyone' group can be given access to a contact. | |
2d932085 | 1020 | * FIXME: Api4 |
8e12938a | 1021 | */ |
1022 | public function testGetACLEveryonePermittedEntity() { | |
1023 | $this->setupScenarioCoreACLEveryonePermittedToGroup(); | |
1bcdee33 | 1024 | $this->callAPISuccessGetCount('Contact', [ |
8e12938a | 1025 | 'id' => $this->scenarioIDs['Contact']['permitted_contact'], |
1026 | 'check_permissions' => 1, | |
1bcdee33 | 1027 | ], 1); |
1028 | ||
1029 | $this->callAPISuccessGetCount('Contact', [ | |
1030 | 'id' => $this->scenarioIDs['Contact']['non_permitted_contact'], | |
1031 | 'check_permissions' => 1, | |
1032 | ], 0); | |
1876e376 | 1033 | |
1034 | // Also check that we can access ACLs through a path that uses the acl_contact_cache table. | |
1035 | // historically this has caused errors due to the key_constraint on that table. | |
1036 | // This is a bit of an artificial check as we have to amp up permissions to access this api. | |
1037 | // However, the lower level function is more directly accessed through the Contribution & Event & Profile | |
1038 | $dupes = $this->callAPISuccess('Contact', 'duplicatecheck', [ | |
1039 | 'match' => [ | |
1040 | 'first_name' => 'Anthony', | |
1041 | 'last_name' => 'Anderson', | |
1042 | 'contact_type' => 'Individual', | |
1043 | 'email' => 'anthony_anderson@civicrm.org', | |
1044 | ], | |
1045 | 'check_permissions' => 0, | |
1046 | ]); | |
a99b82c5 | 1047 | $this->assertEquals(2, $dupes['count']); |
678bd58a | 1048 | CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM']; |
1876e376 | 1049 | |
1050 | $dupes = $this->callAPISuccess('Contact', 'duplicatecheck', [ | |
1051 | 'match' => [ | |
1052 | 'first_name' => 'Anthony', | |
1053 | 'last_name' => 'Anderson', | |
1054 | 'contact_type' => 'Individual', | |
1055 | 'email' => 'anthony_anderson@civicrm.org', | |
1056 | ], | |
1057 | 'check_permissions' => 1, | |
1058 | ]); | |
1059 | $this->assertEquals(1, $dupes['count']); | |
1060 | ||
8e12938a | 1061 | } |
1062 | ||
77fdabbf CW |
1063 | /** |
1064 | * @param int $version | |
82fd72da | 1065 | * |
77fdabbf | 1066 | * @dataProvider versionThreeAndFour |
82fd72da | 1067 | * @throws \CRM_Core_Exception |
77fdabbf CW |
1068 | */ |
1069 | public function testContactGetViaJoin($version) { | |
1070 | $this->_apiversion = $version; | |
1071 | $this->createLoggedInUser(); | |
1072 | $main = $this->individualCreate(['first_name' => 'Main']); | |
1073 | $other = $this->individualCreate(['first_name' => 'Other'], 1); | |
1074 | $tag1 = $this->tagCreate(['name' => uniqid('created'), 'created_id' => $main])['id']; | |
1075 | $tag2 = $this->tagCreate(['name' => uniqid('other'), 'created_id' => $other])['id']; | |
1076 | $this->setPermissions(['access CiviCRM']); | |
1077 | $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereHookAllResults']); | |
82fd72da | 1078 | $createdFirstName = $version === 4 ? 'created.first_name' : 'created_id.first_name'; |
77fdabbf CW |
1079 | $result = $this->callAPISuccess('Tag', 'get', [ |
1080 | 'check_permissions' => 1, | |
1081 | 'return' => ['id', $createdFirstName], | |
1082 | 'id' => ['IN' => [$tag1, $tag2]], | |
1083 | ]); | |
1084 | $this->assertEquals('Main', $result['values'][$tag1][$createdFirstName]); | |
1085 | $this->assertEquals('Other', $result['values'][$tag2][$createdFirstName]); | |
1086 | $this->allowedContactId = $main; | |
1087 | $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereOnlyOne']); | |
1088 | $this->cleanupCachedPermissions(); | |
1089 | $result = $this->callAPISuccess('Tag', 'get', [ | |
1090 | 'check_permissions' => 1, | |
1091 | 'return' => ['id', $createdFirstName], | |
1092 | 'id' => ['IN' => [$tag1, $tag2]], | |
1093 | ]); | |
1094 | $this->assertEquals('Main', $result['values'][$tag1][$createdFirstName]); | |
1095 | $this->assertEquals($tag2, $result['values'][$tag2]['id']); | |
1096 | $this->assertFalse(isset($result['values'][$tag2][$createdFirstName])); | |
1097 | } | |
1098 | ||
5e327f37 CW |
1099 | public function testApi4CustomEntityACL() { |
1100 | $group = uniqid('mg'); | |
1101 | $textField = uniqid('tx'); | |
1102 | ||
fe806431 | 1103 | CustomGroup::create(FALSE) |
5e327f37 CW |
1104 | ->addValue('name', $group) |
1105 | ->addValue('extends', 'Contact') | |
1106 | ->addValue('is_multiple', TRUE) | |
1107 | ->addChain('field', CustomField::create() | |
1108 | ->addValue('label', $textField) | |
1109 | ->addValue('custom_group_id', '$id') | |
1110 | ->addValue('html_type', 'Text') | |
1111 | ->addValue('data_type', 'String') | |
1112 | ) | |
1113 | ->execute(); | |
1114 | ||
1115 | $this->createLoggedInUser(); | |
1116 | $c1 = $this->individualCreate(['first_name' => 'C1']); | |
1117 | $c2 = $this->individualCreate(['first_name' => 'C2', 'is_deleted' => 1], 1); | |
1118 | ||
1119 | CustomValue::save($group)->setCheckPermissions(FALSE) | |
1120 | ->addRecord(['entity_id' => $c1, $textField => '1']) | |
1121 | ->addRecord(['entity_id' => $c2, $textField => '2']) | |
1122 | ->execute(); | |
1123 | ||
1124 | $this->setPermissions(['access CiviCRM', 'view debug output']); | |
1125 | $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereHookAllResults']); | |
1126 | ||
1127 | // Without "access deleted contacts" we won't see C2 | |
1128 | $vals = CustomValue::get($group)->setDebug(TRUE)->execute(); | |
1129 | $this->assertCount(1, $vals); | |
1130 | $this->assertEquals($c1, $vals[0]['entity_id']); | |
1131 | ||
1132 | $this->setPermissions(['access CiviCRM', 'access deleted contacts', 'view debug output']); | |
1133 | $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereHookAllResults']); | |
1134 | $this->cleanupCachedPermissions(); | |
1135 | ||
1136 | $vals = CustomValue::get($group)->execute(); | |
1137 | $this->assertCount(2, $vals); | |
1138 | ||
1139 | $this->allowedContactId = $c2; | |
1140 | $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereOnlyOne']); | |
1141 | $this->cleanupCachedPermissions(); | |
1142 | ||
1143 | $vals = CustomValue::get($group)->addSelect('*', 'contact.first_name')->execute(); | |
1144 | $this->assertCount(1, $vals); | |
1145 | $this->assertEquals($c2, $vals[0]['entity_id']); | |
1146 | $this->assertEquals('C2', $vals[0]['contact.first_name']); | |
1147 | ||
1148 | $vals = Contact::get() | |
1149 | ->addJoin('Custom_' . $group . ' AS cf') | |
1150 | ->addSelect('first_name', 'cf.' . $textField) | |
1151 | ->addWhere('is_deleted', '=', TRUE) | |
1152 | ->execute(); | |
1153 | $this->assertCount(1, $vals); | |
1154 | $this->assertEquals('C2', $vals[0]['first_name']); | |
1155 | $this->assertEquals('2', $vals[0]['cf.' . $textField]); | |
1156 | } | |
1157 | ||
6a488035 | 1158 | } |