Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 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 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
19 | * | |
20 | */ | |
21 | class CRM_Core_Permission_Base { | |
22 | ||
518fa0ee SL |
23 | /** |
24 | * permission mapping to stub check() calls | |
25 | * @var array | |
26 | */ | |
dcbec360 EM |
27 | public $permissions = NULL; |
28 | ||
7ffbc14e SL |
29 | /** |
30 | * Is this user someone with access for the entire system. | |
31 | * | |
32 | * @var bool | |
33 | */ | |
34 | protected $_viewAdminUser = FALSE; | |
35 | protected $_editAdminUser = FALSE; | |
36 | ||
37 | /** | |
38 | * Am in in view permission or edit permission? | |
39 | * | |
40 | * @var bool | |
41 | */ | |
42 | protected $_viewPermission = FALSE; | |
43 | protected $_editPermission = FALSE; | |
44 | ||
085823c1 | 45 | /** |
d09edf64 | 46 | * Translate permission. |
085823c1 | 47 | * |
6ad55d91 EM |
48 | * @param string $perm |
49 | * Permission string e.g "administer CiviCRM", "cms:access user record", "Drupal:administer content", | |
50 | * "Joomla:action:com_asset" | |
51 | * | |
085823c1 | 52 | * @param string $nativePrefix |
6a0b768e TO |
53 | * @param array $map |
54 | * Array($portableName => $nativeName). | |
77b97be7 | 55 | * |
72b3a70c CW |
56 | * @return NULL|string |
57 | * a permission name | |
085823c1 TO |
58 | */ |
59 | public function translatePermission($perm, $nativePrefix, $map) { | |
ea54c6e5 | 60 | [$civiPrefix, $name] = CRM_Utils_String::parsePrefix(':', $perm, NULL); |
085823c1 TO |
61 | switch ($civiPrefix) { |
62 | case $nativePrefix: | |
2aa397bc TO |
63 | return $name; |
64 | ||
65 | // pass through | |
085823c1 TO |
66 | case 'cms': |
67 | return CRM_Utils_Array::value($name, $map, CRM_Core_Permission::ALWAYS_DENY_PERMISSION); | |
2aa397bc | 68 | |
085823c1 TO |
69 | case NULL: |
70 | return $name; | |
2aa397bc | 71 | |
085823c1 TO |
72 | default: |
73 | return CRM_Core_Permission::ALWAYS_DENY_PERMISSION; | |
74 | } | |
75 | } | |
76 | ||
42762e35 | 77 | /** |
d09edf64 | 78 | * Get the current permission of this user. |
42762e35 | 79 | * |
a6c01b45 CW |
80 | * @return string |
81 | * the permission of the user (edit or view or null) | |
42762e35 DL |
82 | */ |
83 | public function getPermission() { | |
7ffbc14e SL |
84 | $this->group(); |
85 | ||
86 | if ($this->_editPermission) { | |
87 | return CRM_Core_Permission::EDIT; | |
88 | } | |
89 | elseif ($this->_viewPermission) { | |
90 | return CRM_Core_Permission::VIEW; | |
91 | } | |
92 | return NULL; | |
42762e35 DL |
93 | } |
94 | ||
6a488035 | 95 | /** |
d09edf64 | 96 | * Get the permissioned where clause for the user. |
6a488035 | 97 | * |
6a0b768e TO |
98 | * @param int $type |
99 | * The type of permission needed. | |
100 | * @param array $tables | |
101 | * (reference ) add the tables that are needed for the select clause. | |
102 | * @param array $whereTables | |
103 | * (reference ) add the tables that are needed for the where clause. | |
6a488035 | 104 | * |
a6c01b45 CW |
105 | * @return string |
106 | * the group where clause for this user | |
6a488035 TO |
107 | */ |
108 | public function whereClause($type, &$tables, &$whereTables) { | |
109 | return '( 1 )'; | |
110 | } | |
353ffa53 | 111 | |
6a488035 | 112 | /** |
d09edf64 | 113 | * Get the permissioned where clause for the user when trying to see groups. |
6a488035 | 114 | * |
6a0b768e TO |
115 | * @param int $type |
116 | * The type of permission needed. | |
117 | * @param array $tables | |
118 | * (reference ) add the tables that are needed for the select clause. | |
119 | * @param array $whereTables | |
120 | * (reference ) add the tables that are needed for the where clause. | |
6a488035 | 121 | * |
a6c01b45 CW |
122 | * @return string |
123 | * the group where clause for this user | |
6a488035 TO |
124 | */ |
125 | public function getPermissionedStaticGroupClause($type, &$tables, &$whereTables) { | |
126 | $this->group(); | |
127 | return $this->groupClause($type, $tables, $whereTables); | |
128 | } | |
77b97be7 | 129 | |
6a488035 TO |
130 | /** |
131 | * Get all groups from database, filtered by permissions | |
132 | * for this user | |
133 | * | |
6a0b768e TO |
134 | * @param string $groupType |
135 | * Type of group(Access/Mailing). | |
3f8d2862 CW |
136 | * @param bool $excludeHidden |
137 | * exclude hidden groups. | |
6a488035 | 138 | * |
6a488035 | 139 | * |
a6c01b45 CW |
140 | * @return array |
141 | * array reference of all groups. | |
6a488035 TO |
142 | */ |
143 | public function group($groupType = NULL, $excludeHidden = TRUE) { | |
7ffbc14e SL |
144 | $userId = CRM_Core_Session::getLoggedInContactID(); |
145 | $domainId = CRM_Core_Config::domainID(); | |
146 | if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId])) { | |
147 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId] = Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId] = []; | |
148 | } | |
149 | ||
150 | $groupKey = $groupType ? $groupType : 'all'; | |
151 | ||
152 | if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) { | |
153 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = []; | |
154 | ||
155 | $groups = CRM_Core_PseudoConstant::allGroup($groupType, $excludeHidden); | |
156 | ||
157 | if ($this->check('edit all contacts')) { | |
158 | // this is the most powerful permission, so we return | |
159 | // immediately rather than dilute it further | |
160 | $this->_editAdminUser = $this->_viewAdminUser = TRUE; | |
161 | $this->_editPermission = $this->_viewPermission = TRUE; | |
162 | Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups; | |
163 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups; | |
164 | return Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]; | |
165 | } | |
166 | elseif ($this->check('view all contacts')) { | |
167 | $this->_viewAdminUser = TRUE; | |
168 | $this->_viewPermission = TRUE; | |
169 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups; | |
170 | } | |
171 | ||
172 | $ids = CRM_ACL_API::group(CRM_Core_Permission::VIEW, NULL, 'civicrm_saved_search', $groups); | |
173 | if (!empty($ids)) { | |
174 | foreach (array_values($ids) as $id) { | |
175 | $title = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'title'); | |
176 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title; | |
177 | $this->_viewPermission = TRUE; | |
178 | } | |
179 | } | |
180 | ||
181 | $ids = CRM_ACL_API::group(CRM_Core_Permission::EDIT, NULL, 'civicrm_saved_search', $groups); | |
182 | if (!empty($ids)) { | |
183 | foreach (array_values($ids) as $id) { | |
184 | $title = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'title'); | |
185 | Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title; | |
186 | Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title; | |
187 | $this->_editPermission = TRUE; | |
188 | $this->_viewPermission = TRUE; | |
189 | } | |
190 | } | |
191 | } | |
192 | ||
193 | return Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]; | |
6a488035 TO |
194 | } |
195 | ||
196 | /** | |
d09edf64 | 197 | * Get group clause for this user. |
6a488035 | 198 | * |
6a0b768e TO |
199 | * @param int $type |
200 | * The type of permission needed. | |
201 | * @param array $tables | |
202 | * (reference ) add the tables that are needed for the select clause. | |
203 | * @param array $whereTables | |
204 | * (reference ) add the tables that are needed for the where clause. | |
6a488035 | 205 | * |
a6c01b45 CW |
206 | * @return string |
207 | * the group where clause for this user | |
6a488035 TO |
208 | */ |
209 | public function groupClause($type, &$tables, &$whereTables) { | |
7ffbc14e SL |
210 | $userId = CRM_Core_Session::getLoggedInContactID(); |
211 | $domainId = CRM_Core_Config::domainID(); | |
212 | if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId])) { | |
213 | $this->group(); | |
214 | } | |
215 | ||
216 | // we basically get all the groups here | |
217 | $groupKey = 'all'; | |
218 | if ($type == CRM_Core_Permission::EDIT) { | |
219 | if ($this->_editAdminUser) { | |
220 | $clause = ' ( 1 ) '; | |
221 | } | |
222 | elseif (empty(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) { | |
223 | $clause = ' ( 0 ) '; | |
224 | } | |
225 | else { | |
226 | $clauses = []; | |
227 | $groups = implode(', ', Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]); | |
228 | $clauses[] = ' ( civicrm_group_contact.group_id IN ( ' . implode(', ', array_keys(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) . " ) AND civicrm_group_contact.status = 'Added' ) "; | |
229 | $tables['civicrm_group_contact'] = 1; | |
230 | $whereTables['civicrm_group_contact'] = 1; | |
231 | ||
232 | // foreach group that is potentially a saved search, add the saved search clause | |
233 | foreach (array_keys(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]) as $id) { | |
234 | $group = new CRM_Contact_DAO_Group(); | |
235 | $group->id = $id; | |
236 | if ($group->find(TRUE) && $group->saved_search_id) { | |
237 | $clause = CRM_Contact_BAO_SavedSearch::whereClause($group->saved_search_id, | |
238 | $tables, | |
239 | $whereTables | |
240 | ); | |
241 | if (trim($clause)) { | |
242 | $clauses[] = $clause; | |
243 | } | |
244 | } | |
245 | } | |
246 | $clause = ' ( ' . implode(' OR ', $clauses) . ' ) '; | |
247 | } | |
248 | } | |
249 | else { | |
250 | if ($this->_viewAdminUser) { | |
251 | $clause = ' ( 1 ) '; | |
252 | } | |
253 | elseif (empty(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) { | |
254 | $clause = ' ( 0 ) '; | |
255 | } | |
256 | else { | |
257 | $clauses = []; | |
258 | $groups = implode(', ', Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]); | |
259 | $clauses[] = ' civicrm_group.id IN (' . implode(', ', array_keys(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) . " ) "; | |
260 | $tables['civicrm_group'] = 1; | |
261 | $whereTables['civicrm_group'] = 1; | |
262 | $clause = ' ( ' . implode(' OR ', $clauses) . ' ) '; | |
263 | } | |
264 | } | |
265 | return $clause; | |
6a488035 TO |
266 | } |
267 | ||
268 | /** | |
100fef9d | 269 | * Given a permission string, check for access requirements |
6a488035 | 270 | * |
6a0b768e TO |
271 | * @param string $str |
272 | * The permission to check. | |
18be3201 | 273 | * @param int $userId |
6a488035 | 274 | * |
ea54c6e5 | 275 | * @return bool; |
276 | * | |
6a488035 | 277 | */ |
18be3201 | 278 | public function check($str, $userId = NULL) { |
42762e35 | 279 | //no default behaviour |
ea54c6e5 | 280 | return FALSE; |
6a488035 TO |
281 | } |
282 | ||
283 | /** | |
284 | * Given a roles array, check for access requirements | |
285 | * | |
6a0b768e TO |
286 | * @param array $array |
287 | * The roles to check. | |
6a488035 | 288 | * |
7c550ca0 | 289 | * @return bool |
a6c01b45 | 290 | * true if yes, else false |
6a488035 | 291 | */ |
00be9182 | 292 | public function checkGroupRole($array) { |
6a488035 TO |
293 | return FALSE; |
294 | } | |
295 | ||
0247a000 TO |
296 | /** |
297 | * Get the palette of available permissions in the CMS's user-management system. | |
298 | * | |
299 | * @return array | |
300 | * List of permissions, keyed by symbolic name. Each item may have fields: | |
301 | * - title: string | |
302 | * - description: string | |
303 | * | |
304 | * The permission-name should correspond to the Civi notation used by | |
305 | * 'CRM_Core_Permission::check()'. For CMS-specific permissions, these are | |
306 | * translated names (eg "WordPress:list_users" or "Drupal:post comments"). | |
307 | * | |
308 | * The list should include *only* CMS permissions. Exclude Civi-native permissions. | |
309 | * | |
310 | * @see \CRM_Core_Permission_Base::translatePermission() | |
311 | */ | |
312 | public function getAvailablePermissions() { | |
313 | return []; | |
314 | } | |
315 | ||
6a488035 | 316 | /** |
d09edf64 | 317 | * Get all the contact emails for users that have a specific permission. |
6a488035 | 318 | * |
6a0b768e TO |
319 | * @param string $permissionName |
320 | * Name of the permission we are interested in. | |
6a488035 | 321 | * |
b5834543 | 322 | * @throws CRM_Core_Exception. |
6a488035 TO |
323 | */ |
324 | public function permissionEmails($permissionName) { | |
b5834543 | 325 | throw new CRM_Core_Exception("this function only works in Drupal 6 at the moment"); |
6a488035 TO |
326 | } |
327 | ||
328 | /** | |
d09edf64 | 329 | * Get all the contact emails for users that have a specific role. |
6a488035 | 330 | * |
6a0b768e TO |
331 | * @param string $roleName |
332 | * Name of the role we are interested in. | |
6a488035 | 333 | * |
b5834543 | 334 | * @throws CRM_Core_Exception. |
6a488035 TO |
335 | */ |
336 | public function roleEmails($roleName) { | |
b5834543 | 337 | throw new CRM_Core_Exception("this function only works in Drupal 6 at the moment"); |
6a488035 TO |
338 | } |
339 | ||
7fccad46 TO |
340 | /** |
341 | * Determine whether the permission store allows us to store | |
342 | * a list of permissions generated dynamically (eg by | |
343 | * hook_civicrm_permissions.) | |
344 | * | |
345 | * @return bool | |
346 | */ | |
347 | public function isModulePermissionSupported() { | |
348 | return FALSE; | |
349 | } | |
350 | ||
6a488035 | 351 | /** |
0d8fc497 TO |
352 | * Ensure that the CMS supports all the permissions defined by CiviCRM |
353 | * and its extensions. If there are stale permissions, they should be | |
354 | * deleted. This is useful during module upgrade when the newer module | |
355 | * version has removed permission that were defined in the older version. | |
c4bc14ed | 356 | * |
6a0b768e TO |
357 | * @param array $permissions |
358 | * Same format as CRM_Core_Permission::getCorePermissions(). | |
77b97be7 EM |
359 | * |
360 | * @throws CRM_Core_Exception | |
c4bc14ed | 361 | * @see CRM_Core_Permission::getCorePermissions |
6a488035 | 362 | */ |
00be9182 | 363 | public function upgradePermissions($permissions) { |
7fccad46 | 364 | throw new CRM_Core_Exception("Unimplemented method: CRM_Core_Permission_*::upgradePermissions"); |
6a488035 TO |
365 | } |
366 | ||
367 | /** | |
368 | * Get the permissions defined in the hook_civicrm_permission implementation | |
369 | * of the given module. | |
370 | * | |
789565bf TO |
371 | * Note: At time of writing, this is only used with native extension-modules, so |
372 | * there's one, predictable calling convention (regardless of CMS). | |
373 | * | |
77b97be7 EM |
374 | * @param $module |
375 | * | |
16b10e64 CW |
376 | * @return array |
377 | * Array of permissions, in the same format as CRM_Core_Permission::getCorePermissions(). | |
b57fc2e3 | 378 | * @see CRM_Core_Permission::getCorePermissions |
6a488035 | 379 | */ |
ea54c6e5 | 380 | public function getModulePermissions($module): array { |
be2fb01f | 381 | $return_permissions = []; |
789565bf TO |
382 | $fn_name = "{$module}_civicrm_permission"; |
383 | if (function_exists($fn_name)) { | |
be2fb01f | 384 | $module_permissions = []; |
789565bf TO |
385 | $fn_name($module_permissions); |
386 | $return_permissions = $module_permissions; | |
387 | } | |
388 | return $return_permissions; | |
6a488035 TO |
389 | } |
390 | ||
391 | /** | |
392 | * Get the permissions defined in the hook_civicrm_permission implementation | |
393 | * in all enabled CiviCRM module extensions. | |
394 | * | |
54957108 | 395 | * @param bool $descriptions |
396 | * | |
16b10e64 CW |
397 | * @return array |
398 | * Array of permissions, in the same format as CRM_Core_Permission::getCorePermissions(). | |
6a488035 | 399 | */ |
34f47692 YN |
400 | public function getAllModulePermissions($descriptions = FALSE): array { |
401 | $permissions = []; | |
402 | CRM_Utils_Hook::permission($permissions); | |
f1db52b9 AH |
403 | |
404 | if ($descriptions) { | |
405 | foreach ($permissions as $permission => $label) { | |
be2fb01f | 406 | $permissions[$permission] = (is_array($label)) ? $label : [$label]; |
f1db52b9 AH |
407 | } |
408 | } | |
409 | else { | |
ea54c6e5 | 410 | // Passing in false here is to be deprecated. |
f1db52b9 AH |
411 | foreach ($permissions as $permission => $label) { |
412 | $permissions[$permission] = (is_array($label)) ? array_shift($label) : $label; | |
413 | } | |
414 | } | |
6a488035 TO |
415 | return $permissions; |
416 | } | |
96025800 | 417 | |
6a488035 | 418 | } |