fixed bug in the original function
[civicrm-core.git] / tests / phpunit / CRM / ACL / ListTest.php
CommitLineData
ea8011f6 1<?php
2
3/**
4 * Class CRM_ACL_Test
5 *
6 * This test focuses on testing the (new) ID list-based functions:
7 * CRM_Contact_BAO_Contact_Permission::allowList()
8 * CRM_Contact_BAO_Contact_Permission::relationshipList()
9 * @group headless
10 */
11class CRM_ACL_ListTest extends CiviUnitTestCase {
12
13 /**
14 * Set up function.
15 */
16 public function setUp() {
17 parent::setUp();
18 $this->useTransaction(TRUE);
c1ebd31f 19 $this->allowedContactsACL = array();
ea8011f6 20 }
21
22 /**
23 * general test for the 'view all contacts' permission
24 */
25 public function testViewAllPermission() {
26 // create test contacts
134b2b64 27 $contacts = $this->createScenarioPlain();
ea8011f6 28
134b2b64 29 // test WITH all permissions
30 CRM_Core_Config::singleton()->userPermissionClass->permissions = NULL;
ea8011f6 31 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts);
134b2b64 32 sort($result);
33 $this->assertEquals($result, $contacts, "Contacts should be viewable when 'view all contacts'");
ea8011f6 34
35
36 // test WITH explicit permission
37 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('view all contacts');
38 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts, CRM_Core_Permission::VIEW);
134b2b64 39 sort($result);
40 $this->assertEquals($result, $contacts, "Contacts should be viewable when 'view all contacts'");
ea8011f6 41
42
43 // test WITHOUT permission
44 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
45 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts);
134b2b64 46 sort($result);
ea8011f6 47 $this->assertEmpty($result, "Contacts should NOT be viewable when 'view all contacts' is not set");
48 }
49
50
51 /**
52 * general test for the 'view all contacts' permission
53 */
54 public function testEditAllPermission() {
55 // create test contacts
134b2b64 56 $contacts = $this->createScenarioPlain();
ea8011f6 57
58 // test WITH explicit permission
59 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('edit all contacts');
60 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts, CRM_Core_Permission::EDIT);
134b2b64 61 sort($result);
62 $this->assertEquals($result, $contacts, "Contacts should be viewable when 'edit all contacts'");
ea8011f6 63
64
65 // test WITHOUT permission
66 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
67 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts);
134b2b64 68 sort($result);
ea8011f6 69 $this->assertEmpty($result, "Contacts should NOT be viewable when 'edit all contacts' is not set");
70 }
71
72
73 /**
134b2b64 74 * Test access related to the 'access deleted contact' permission
ea8011f6 75 */
76 public function testViewEditDeleted() {
134b2b64 77 // create test contacts
78 $contacts = $this->createScenarioPlain();
79
80 // delete one contact
81 $deleted_contact_id = $contacts[2];
82 $this->callAPISuccess('Contact', 'create', array('id' => $deleted_contact_id, 'contact_is_deleted' => 1));
83 $deleted_contact = $this->callAPISuccess('Contact', 'getsingle', array('id' => $deleted_contact_id));
84 $this->assertEquals($deleted_contact['contact_is_deleted'], 1, "Contact should've been deleted");
85
86 // test WITH explicit permission
ea8011f6 87 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('edit all contacts', 'view all contacts');
134b2b64 88 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts, CRM_Core_Permission::EDIT);
89 sort($result);
90 $this->assertNotContains($deleted_contact_id, $result, "Deleted contacts should be excluded");
91 $this->assertEquals(count($result), count($contacts)-1, "Only deleted contacts should be excluded");
92
93 }
94
ea8011f6 95
134b2b64 96 /**
c1ebd31f 97 * Test access based on relations
134b2b64 98 *
99 * There should be the following permission-relationship
100 * contact[0] -> contact[1] -> contact[2]
101 */
102 public function testPermissionByRelation() {
103 // create test scenario
c1ebd31f 104 $contacts = $this->createScenarioRelations();
134b2b64 105
106 // remove all permissions
107 $config = CRM_Core_Config::singleton();
108 $config->userPermissionClass->permissions = array();
109 $permissions_to_check = array(CRM_Core_Permission::VIEW => 'View', CRM_Core_Permission::EDIT => 'Edit');
110
111 // run this for SIMPLE relations
112 $config->secondDegRelPermissions = FALSE;
113 $this->assertFalse($config->secondDegRelPermissions);
114 foreach ($permissions_to_check as $permission => $permission_label) {
115 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts, $permission);
116 sort($result);
117
118
c1ebd31f 119 $this->assertNotContains($contacts[0], $result, "User[0] should NOT have $permission_label permission on contact[0].");
120 $this->assertContains( $contacts[1], $result, "User[0] should have $permission_label permission on contact[1].");
121 $this->assertNotContains($contacts[2], $result, "User[0] should NOT have $permission_label permission on contact[2].");
122 $this->assertNotContains($contacts[3], $result, "User[0] should NOT have $permission_label permission on contact[3].");
123 $this->assertNotContains($contacts[4], $result, "User[0] should NOT have $permission_label permission on contact[4].");
134b2b64 124 }
ea8011f6 125
134b2b64 126 // run this for SECOND DEGREE relations
127 $config->secondDegRelPermissions = TRUE;
128 $this->assertTrue($config->secondDegRelPermissions);
129 foreach ($permissions_to_check as $permission => $permission_label) {
130 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts, $permission);
131 sort($result);
132
c1ebd31f 133 $this->assertNotContains($contacts[0], $result, "User[0] should NOT have $permission_label permission on contact[0].");
134 $this->assertContains( $contacts[1], $result, "User[0] should have $permission_label permission on contact[1].");
135 $this->assertContains( $contacts[2], $result, "User[0] should have second degree $permission_label permission on contact[2].");
136 $this->assertNotContains($contacts[3], $result, "User[0] should NOT have $permission_label permission on contact[3].");
137 $this->assertNotContains($contacts[4], $result, "User[0] should NOT have $permission_label permission on contact[4].");
134b2b64 138 }
ea8011f6 139 }
140
141
134b2b64 142 /**
c1ebd31f 143 * Test access based on ACL
134b2b64 144 */
c1ebd31f 145 public function testPermissionByACL() {
146 $contacts = $this->createScenarioPlain();
147
148 // set custom hook
149 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'hook_civicrm_aclWhereClause'));
150
151 // run simple test
152 $permissions_to_check = array(CRM_Core_Permission::VIEW => 'View', CRM_Core_Permission::EDIT => 'Edit');
153
154 $this->allowedContactsACL = array($contacts[0], $contacts[1], $contacts[4]);
155 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
156 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts);
157 sort($result);
158
159 $this->assertContains( $contacts[0], $result, "User[0] should NOT have an ACL permission on contact[0].");
160 $this->assertContains( $contacts[1], $result, "User[0] should have an ACL permission on contact[1].");
161 $this->assertNotContains($contacts[2], $result, "User[0] should NOT have an ACL permission on contact[2].");
162 $this->assertNotContains($contacts[3], $result, "User[0] should NOT have an RELATION permission on contact[3].");
163 $this->assertContains( $contacts[4], $result, "User[0] should NOT have an ACL permission on contact[4].");
134b2b64 164 }
ea8011f6 165
c1ebd31f 166
134b2b64 167 /**
c1ebd31f 168 * Test access with a mix of ACL and relationship
134b2b64 169 */
c1ebd31f 170 public function testPermissionACLvsRelationship() {
171 $contacts = $this->createScenarioRelations();
172
173 // set custom hook
174 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'hook_civicrm_aclWhereClause'));
175
176 $config = CRM_Core_Config::singleton();
177 $config->userPermissionClass->permissions = array();
178 $config->secondDegRelPermissions = TRUE;
179
180 $this->allowedContactsACL = array($contacts[0], $contacts[1], $contacts[4]);
181 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
182 $result = CRM_Contact_BAO_Contact_Permission::allowList($contacts);
183 sort($result);
184
185 $this->assertContains( $contacts[0], $result, "User[0] should have an ACL permission on contact[0].");
186 $this->assertContains( $contacts[1], $result, "User[0] should have an ACL permission on contact[1].");
187 $this->assertContains( $contacts[2], $result, "User[0] should have second degree an relation permission on contact[2].");
188 $this->assertNotContains($contacts[3], $result, "User[0] should NOT have an ACL permission on contact[3].");
189 $this->assertContains( $contacts[4], $result, "User[0] should have an ACL permission on contact[4].");
134b2b64 190 }
ea8011f6 191
134b2b64 192 /**
193 * Test access related to the 'access deleted contact' permission
194 */
195 public function _testPermissionCompare() {
196 // CRM_Core_Config::singleton()->userPermissionClass->permissions = array('edit all contacts', 'view all contacts');
197 // $contacts = $this->createScenarioPlain();
198 }
ea8011f6 199
200
134b2b64 201 /****************************************************
202 * Scenario Builders *
203 ***************************************************/
ea8011f6 204
205 /**
134b2b64 206 * create plain test scenario, no relationships/ACLs
ea8011f6 207 */
134b2b64 208 protected function createScenarioPlain() {
ea8011f6 209 // get logged in user
210 $user_id = $this->createLoggedInUser();
211 $this->assertNotEmpty($user_id);
212
213 // create test contacts
214 $bush_sr_id = $this->individualCreate(array('first_name' => 'George', 'middle_name' => 'W.', 'last_name' => 'Bush'));
215 $bush_jr_id = $this->individualCreate(array('first_name' => 'George', 'middle_name' => 'H. W.', 'last_name' => 'Bush'));
216 $bush_laura_id = $this->individualCreate(array('first_name' => 'Laura Lane', 'last_name' => 'Bush'));
217 $bush_brbra_id = $this->individualCreate(array('first_name' => 'Barbara', 'last_name' => 'Bush'));
218
134b2b64 219 $contacts = array($user_id, $bush_sr_id, $bush_jr_id, $bush_laura_id, $bush_brbra_id);
220 sort($contacts);
221 return $contacts;
222 }
223
224 /**
225 * create plain test scenario, no relationships/ACLs
226 */
c1ebd31f 227 protected function createScenarioRelations() {
134b2b64 228 $contacts = $this->createScenarioPlain();
229
ea8011f6 230 // create some relationships
231 $this->callAPISuccess('Relationship', 'create', array(
232 'relationship_type_id' => 1, // CHILD OF
134b2b64 233 'contact_id_a' => $contacts[1],
234 'contact_id_b' => $contacts[0],
235 'is_permission_b_a' => 1,
236 'is_active' => 1,
ea8011f6 237 ));
238
239 $this->callAPISuccess('Relationship', 'create', array(
240 'relationship_type_id' => 1, // CHILD OF
134b2b64 241 'contact_id_a' => $contacts[2],
242 'contact_id_b' => $contacts[1],
243 'is_permission_b_a' => 1,
244 'is_active' => 1,
ea8011f6 245 ));
246
247 // create some relationships
248 $this->callAPISuccess('Relationship', 'create', array(
249 'relationship_type_id' => 1, // CHILD OF
134b2b64 250 'contact_id_a' => $contacts[4],
251 'contact_id_b' => $contacts[2],
252 'is_permission_b_a' => 1,
253 'is_active' => 1,
ea8011f6 254 ));
255
134b2b64 256 return $contacts;
ea8011f6 257 }
c1ebd31f 258
259 /**
260 * ACL HOOK implementation for various tests
261 */
262 public function hook_civicrm_aclWhereClause($type, &$tables, &$whereTables, &$contactID, &$where ) {
263 if (!empty($this->allowedContactsACL)) {
264 $contact_id_list = implode(',', $this->allowedContactsACL);
265 $where = " contact_a.id IN ($contact_id_list)";
266 }
267 }
ea8011f6 268}