Merge pull request #22164 from eileenmcnaughton/parent
[civicrm-core.git] / Civi / Test / ACLPermissionTrait.php
CommitLineData
2f6c641a 1<?php
2/*
3 +--------------------------------------------------------------------+
7d61e75f 4 | Copyright CiviCRM LLC. All rights reserved. |
2f6c641a 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 |
2f6c641a 9 +--------------------------------------------------------------------+
10 */
11
57a4d21c
SL
12namespace Civi\Test;
13
2f6c641a 14/**
57a4d21c 15 * Trait Civi\Test\ACLPermissionTrait.
2f6c641a 16 *
17 * Trait for working with ACLs in tests
18 */
57a4d21c 19trait ACLPermissionTrait {
2f6c641a 20
39b959db
SL
21 /**
22 * ContactID of allowed Contact
23 * @var int
24 */
2f6c641a 25 protected $allowedContactId = 0;
39b959db
SL
26
27 /**
28 * Array of allowed contactIds
29 * @var array
30 */
2f6c641a 31 protected $allowedContacts = [];
32
8e12938a 33 /**
34 * Ids created for the scenario in use.
35 *
36 * @var array
37 */
38 protected $scenarioIDs = [];
39
2f6c641a 40 /**
41 * All results returned.
42 *
43 * @implements CRM_Utils_Hook::aclWhereClause
44 *
45 * @param string $type
46 * @param array $tables
47 * @param array $whereTables
48 * @param int $contactID
49 * @param string $where
50 */
51 public function aclWhereHookAllResults($type, &$tables, &$whereTables, &$contactID, &$where) {
52 $where = " (1) ";
53 }
54
2ed07c20 55 /**
56 * No results returned.
57 *
58 * @implements CRM_Utils_Hook::aclWhereClause
59 *
60 * @param string $type
61 * @param array $tables
62 * @param array $whereTables
63 * @param int $contactID
64 * @param string $where
65 */
66 public function aclWhereHookNoResults($type, &$tables, &$whereTables, &$contactID, &$where) {
67 }
68
2f6c641a 69 /**
70 * All but first results returned.
71 *
72 * @implements CRM_Utils_Hook::aclWhereClause
73 *
74 * @param string $type
75 * @param array $tables
76 * @param array $whereTables
77 * @param int $contactID
78 * @param string $where
79 */
80 public function aclWhereOnlySecond($type, &$tables, &$whereTables, &$contactID, &$where) {
81 $where = " contact_a.id > 1";
82 }
83
84 /**
85 * Only specified contact returned.
86 *
87 * @implements CRM_Utils_Hook::aclWhereClause
88 *
89 * @param string $type
90 * @param array $tables
91 * @param array $whereTables
92 * @param int $contactID
93 * @param string $where
94 */
95 public function aclWhereOnlyOne($type, &$tables, &$whereTables, &$contactID, &$where) {
96 $where = " contact_a.id = " . $this->allowedContactId;
97 }
98
faa79dbf
CW
99 /**
100 * Results after the allowedContact are returned.
101 *
102 * @implements CRM_Utils_Hook::aclWhereClause
103 *
104 * @param string $type
105 * @param array $tables
106 * @param array $whereTables
107 * @param int $contactID
108 * @param string $where
109 */
110 public function aclWhereGreaterThan($type, &$tables, &$whereTables, &$contactID, &$where) {
111 $where = " contact_a.id > " . $this->allowedContactId;
112 }
113
8e12938a 114 /**
115 * Set up a core ACL.
116 *
117 * It is recommended that this helper function is accessed through a scenario function.
118 *
119 * @param array $permissionedEntities Array of groups for whom ACLs enable access.
120 * @param string|int $groupAllowedAccess Group permitted to access the permissioned Group
121 * An ID of 0 means that 'Everyone' can access the group.
122 * @param string $operation View|Edit|Create|Delete|Search|All
123 * @param string $entity Group|CustomGroup|Profile|Event
124 *
125 * @throws CRM_Core_Exception
126 */
11fa49fe 127 public function setupCoreACLPermittedAcl($permissionedEntities = [], $groupAllowedAccess = 'Everyone', $operation = 'View', $entity = 'Group') {
8e12938a 128 $tableMap = ['Group' => 'civicrm_saved_search', 'CustomGroup' => 'civicrm_custom_group', 'Profile' => 'civicrm_uf_match', 'Event' => 'civicrm_event'];
129 $entityTable = $tableMap[$entity];
130
131 $permittedRoleID = ($groupAllowedAccess === 'Everyone') ? 0 : $groupAllowedAccess;
132 if ($permittedRoleID !== 0) {
57a4d21c 133 throw new \CRM_Core_Exception('only handling everyone group as yet');
8e12938a 134 }
135
136 foreach ($permissionedEntities as $permissionedEntityID) {
137 $this->callAPISuccess('Acl', 'create', [
138 'name' => uniqid(),
139 'operation' => $operation,
140 'entity_id' => $permittedRoleID,
141 'object_id' => $permissionedEntityID,
142 'object_table' => $entityTable,
143 ]);
144 }
145 }
146
147 /**
148 * Set up a scenario where everyone can access the permissioned group.
149 *
150 * A scenario in this class involves multiple defined assets. In this case we create
151 * - a group to which the everyone has permission
152 * - a contact in the group
153 * - a contact not in the group
154 *
155 * These are arrayed as follows
156 * $this->scenarioIDs['Contact'] = ['permitted_contact' => x, 'non_permitted_contact' => y]
157 * $this->scenarioIDs['Group'] = ['permitted_group' => x]
158 */
159 public function setupScenarioCoreACLEveryonePermittedToGroup() {
160 $this->quickCleanup(['civicrm_acl_cache', 'civicrm_acl_contact_cache']);
161 $this->scenarioIDs['Group']['permitted_group'] = $this->groupCreate();
162 $this->scenarioIDs['Contact']['permitted_contact'] = $this->individualCreate();
163 $result = $this->callAPISuccess('GroupContact', 'create', ['group_id' => $this->scenarioIDs['Group']['permitted_group'], 'contact_id' => $this->scenarioIDs['Contact']['permitted_contact'], 'status' => 'Added']);
164 $this->scenarioIDs['Contact']['non_permitted_contact'] = $this->individualCreate();
57a4d21c 165 \CRM_Core_Config::singleton()->userPermissionClass->permissions = [];
11fa49fe 166 $this->setupCoreACLPermittedAcl([$this->scenarioIDs['Group']['permitted_group']]);
167 }
168
169 /**
170 * Set up a scenario where everyone can access the permissioned group.
171 *
172 * A scenario in this class involves multiple defined assets. In this case we create
173 * - a group to which the everyone has permission
174 * - a contact in the group
175 * - a contact not in the group
176 *
177 * These are arrayed as follows
178 * $this->scenarioIDs['Contact'] = ['permitted_contact' => x, 'non_permitted_contact' => y]
179 * $this->scenarioIDs['Group'] = ['permitted_group' => x]
180 */
181 public function setupScenarioCoreACLEveryonePermittedToEvent() {
182 $this->quickCleanup(['civicrm_acl_cache', 'civicrm_acl_contact_cache']);
183 $this->scenarioIDs['Event']['permitted_event'] = $this->eventCreate()['id'];
184 $this->scenarioIDs['Contact']['permitted_contact'] = $this->individualCreate();
57a4d21c 185 \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['view event info'];
11fa49fe 186 $this->setupCoreACLPermittedAcl([$this->scenarioIDs['Event']['permitted_event']], 'Everyone', 'View', 'Event');
8e12938a 187 }
188
cdacd6ab 189 /**
190 * Clean up places where permissions get cached.
191 */
192 protected function cleanupCachedPermissions() {
57a4d21c
SL
193 if (isset(\Civi::$statics['CRM_Contact_BAO_Contact_Permission'])) {
194 unset(\Civi::$statics['CRM_Contact_BAO_Contact_Permission']);
cdacd6ab 195 }
57a4d21c 196 \CRM_Core_DAO::executeQuery('TRUNCATE civicrm_acl_contact_cache');
cdacd6ab 197 }
198
2f6c641a 199}