Merge pull request #14922 from civicrm/5.16
[civicrm-core.git] / tests / phpunit / api / v3 / EntityTagACLTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * Test APIv3 civicrm_entity_tag_* functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Core
33 */
34
35 /**
36 * Class api_v3_EntityTagTest.
37 *
38 * This test class was introduced to ensure that the fix for CRM-17350 (reducing the required permission
39 * from edit all contacts to has right to edit this contact) would not result in inappropriate permission opening on
40 * other entities. Other entities are still too restricted but that is a larger job.
41 * @group headless
42 */
43 class api_v3_EntityTagACLTest extends CiviUnitTestCase {
44
45 use CRMTraits_ACL_PermissionTrait;
46
47 /**
48 * API Version in use.
49 *
50 * @var int
51 */
52 protected $_apiversion = 3;
53
54 /**
55 * Entity being tested.
56 *
57 * @var string
58 */
59 protected $_entity = 'entity_tag';
60
61 /**
62 * Set up permissions for test.
63 */
64 public function setUp() {
65 $this->useTransaction(TRUE);
66 parent::setUp();
67 $individualID = $this->individualCreate();
68 $daoObj = new CRM_Core_DAO();
69 $this->callAPISuccess('Attachment', 'create', [
70 'entity_table' => 'civicrm_contact',
71 'entity_id' => $individualID,
72 'mime_type' => 'k',
73 'name' => 'p',
74 'content' => 'l',
75 ]);
76 $daoObj->createTestObject('CRM_Activity_BAO_Activity', [], 1, 0);
77 $daoObj->createTestObject('CRM_Case_BAO_Case', [], 1, 0);
78 $entities = $this->getTagOptions();
79 foreach ($entities as $key => $entity) {
80 $this->callAPISuccess('Tag', 'create', [
81 'used_for' => $key,
82 'name' => $entity,
83 'description' => $entity,
84 ]);
85 }
86 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM'];
87 }
88
89 /**
90 * Get the options for the used_for fields.
91 *
92 * @return array
93 */
94 public function getTagOptions() {
95 $options = $this->callAPISuccess('Tag', 'getoptions', ['field' => 'used_for']);
96 return $options['values'];
97 }
98
99 /**
100 * Get the entity table for a tag label.
101 *
102 * @param string $entity
103 *
104 * @return string
105 */
106 protected function getTableForTag($entity) {
107 $options = $this->getTagOptions();
108 return array_search($entity, $options);
109 }
110
111 /**
112 * Get entities which can be tagged in data provider format.
113 */
114 public function taggableEntities() {
115 $return = [];
116 foreach ($this->getTagOptions() as $entity) {
117 $return[] = [$entity];
118 }
119 return $return;
120 }
121
122 /**
123 * This test checks that users with edit all contacts can edit all tags.
124 *
125 * @dataProvider taggableEntities
126 *
127 * We are looking to see that a contact with edit all contacts can still add all tags (for all
128 * tag entities since that was how it was historically and we are not fixing non-contact entities).
129 *
130 * @param string $entity
131 * Entity to test
132 */
133 public function testThatForEntitiesEditAllContactsCanAddTags($entity) {
134
135 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['edit all contacts', 'access CiviCRM'];
136 $this->callAPISuccess('EntityTag', 'create', [
137 'entity_id' => 1,
138 'tag_id' => $entity,
139 'check_permissions' => TRUE,
140 'entity_table' => $this->getTableForTag($entity),
141 ]);
142 $this->callAPISuccessGetCount('EntityTag', [
143 'entity_id' => 1,
144 'entity_table' => $this->getTableForTag($entity),
145 ], 1);
146 }
147
148 /**
149 * This test checks that an ACL or edit all contacts is required to be able to create a contact.
150 *
151 * @dataProvider taggableEntities
152 */
153 public function testThatForEntityWithoutACLOrEditAllThereIsNoAccess($entity) {
154
155 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'view all contacts'];
156 $this->callAPIFailure('EntityTag', 'create', [
157 'entity_id' => 1,
158 'tag_id' => $entity,
159 'check_permissions' => TRUE,
160 'entity_table' => $this->getTableForTag($entity),
161 ]);
162 }
163
164 /**
165 * This test checks that permissions are not applied when check_permissions is off.
166 *
167 * @dataProvider taggableEntities
168 *
169 * @param string $entity
170 * Entity to test
171 */
172 public function testCheckPermissionsOffWorks($entity) {
173
174 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'view all contacts'];
175 $result = $this->callAPISuccess('EntityTag', 'create', [
176 'entity_id' => 1,
177 'tag_id' => $entity,
178 'check_permissions' => 0,
179 'entity_table' => $this->getTableForTag($entity),
180 ]);
181 $this->assertEquals(1, $result['added']);
182 $this->callAPISuccessGetCount('EntityTag', [
183 'entity_id' => 1,
184 'entity_table' => $this->getTableForTag($entity),
185 'check_permissions' => 0,
186 ], 1);
187 }
188
189 /**
190 * This test checks ACLs can be used to control who can edit a contact.
191 *
192 * Note that for other entities this hook will not allow them to edit the entity_tag and they still need
193 * edit all contacts (pending a more extensive fix).
194 *
195 * @dataProvider taggableEntities
196 *
197 * @param string $entity
198 * Entity to test
199 */
200 public function testThatForEntitiesACLApplies($entity) {
201
202 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'view all contacts'];
203 $this->hookClass->setHook('civicrm_aclWhereClause', [$this, 'aclWhereHookAllResults']);
204 civicrm_api('EntityTag', 'create', [
205 'version' => 3,
206 'entity_id' => 1,
207 'tag_id' => $entity,
208 'entity_table' => $this->getTableForTag($entity),
209 'check_permissions' => TRUE,
210 ]);
211 $this->callAPISuccessGetCount('EntityTag', [
212 'entity_id' => 1,
213 'entity_table' => $this->getTableForTag($entity),
214 ], ($entity == 'Contacts' ? 1 : 0));
215 }
216
217 }