Merge pull request #19273 from eileenmcnaughton/complete
[civicrm-core.git] / CRM / Core / Permission.php
CommitLineData
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 * This is the basic permission class wrapper
20 */
21class CRM_Core_Permission {
22
23 /**
d09edf64 24 * Static strings used to compose permissions.
6a488035
TO
25 *
26 * @const
27 * @var string
28 */
7da04cde 29 const EDIT_GROUPS = 'edit contacts in ', VIEW_GROUPS = 'view contacts in ';
6a488035
TO
30
31 /**
d09edf64 32 * The various type of permissions.
6a488035
TO
33 *
34 * @var int
35 */
7da04cde 36 const EDIT = 1, VIEW = 2, DELETE = 3, CREATE = 4, SEARCH = 5, ALL = 6, ADMIN = 7;
6a488035 37
085823c1 38 /**
d09edf64 39 * A placeholder permission which always fails.
085823c1
TO
40 */
41 const ALWAYS_DENY_PERMISSION = "*always deny*";
42
43 /**
d09edf64 44 * A placeholder permission which always fails.
085823c1
TO
45 */
46 const ALWAYS_ALLOW_PERMISSION = "*always allow*";
47
6dd18b98 48 /**
d09edf64 49 * Various authentication sources.
6dd18b98
DS
50 *
51 * @var int
52 */
7da04cde 53 const AUTH_SRC_UNKNOWN = 0, AUTH_SRC_CHECKSUM = 1, AUTH_SRC_SITEKEY = 2, AUTH_SRC_LOGIN = 4;
6dd18b98 54
6a488035 55 /**
d09edf64 56 * Get the current permission of this user.
6a488035 57 *
a6c01b45
CW
58 * @return string
59 * the permission of the user (edit or view or null)
6a488035
TO
60 */
61 public static function getPermission() {
62 $config = CRM_Core_Config::singleton();
41f314b6 63 return $config->userPermissionClass->getPermission();
6a488035
TO
64 }
65
66 /**
100fef9d 67 * Given a permission string or array, check for access requirements
6a488035 68 *
9b61e85d
CW
69 * Ex 1: Must have 'access CiviCRM'
70 * (string) 'access CiviCRM'
60ec9f43 71 *
9b61e85d
CW
72 * Ex 2: Must have 'access CiviCRM' and 'access Ajax API'
73 * ['access CiviCRM', 'access Ajax API']
60ec9f43 74 *
9b61e85d
CW
75 * Ex 3: Must have 'access CiviCRM' or 'access Ajax API'
76 * [
77 * ['access CiviCRM', 'access Ajax API'],
78 * ],
60ec9f43 79 *
9b61e85d
CW
80 * Ex 4: Must have 'access CiviCRM' or 'access Ajax API' AND 'access CiviEvent'
81 * [
82 * ['access CiviCRM', 'access Ajax API'],
83 * 'access CiviEvent',
84 * ],
60ec9f43 85 *
9b61e85d
CW
86 * Note that in permissions.php this is keyed by the action eg.
87 * (access Civi || access AJAX) && (access CiviEvent || access CiviContribute)
88 * 'myaction' => [
89 * ['access CiviCRM', 'access Ajax API'],
90 * ['access CiviEvent', 'access CiviContribute']
91 * ],
60ec9f43 92 *
9b61e85d
CW
93 * @param string|array $permissions
94 * The permission to check as an array or string -see examples.
60ec9f43 95 *
9b61e85d
CW
96 * @param int $contactId
97 * Contact id to check permissions for. Defaults to current logged-in user.
6a488035 98 *
acb1052e 99 * @return bool
9b61e85d 100 * true if contact has permission(s), else false
6a488035 101 */
18be3201 102 public static function check($permissions, $contactId = NULL) {
60ec9f43 103 $permissions = (array) $permissions;
9b61e85d 104 $userId = CRM_Core_BAO_UFMatch::getUFId($contactId);
60ec9f43 105
18be3201 106 /** @var CRM_Core_Permission_Temp $tempPerm */
59735506
TO
107 $tempPerm = CRM_Core_Config::singleton()->userPermissionTemp;
108
60ec9f43 109 foreach ($permissions as $permission) {
22e263ad 110 if (is_array($permission)) {
60ec9f43 111 foreach ($permission as $orPerm) {
18be3201 112 if (self::check($orPerm, $contactId)) {
60ec9f43 113 //one of our 'or' permissions has succeeded - stop checking this permission
b8a19656 114 return TRUE;
60ec9f43
E
115 }
116 }
117 //none of our our conditions was met
118 return FALSE;
119 }
120 else {
3ae62cab 121 // This is an individual permission
755a1835 122 $impliedPermissions = self::getImpliedPermissionsFor($permission);
123 $impliedPermissions[] = $permission;
124 foreach ($impliedPermissions as $permissionOption) {
125 $granted = CRM_Core_Config::singleton()->userPermissionClass->check($permissionOption, $userId);
126 // Call the permission_check hook to permit dynamic escalation (CRM-19256)
127 CRM_Utils_Hook::permission_check($permissionOption, $granted, $contactId);
128 if ($granted) {
129 break;
130 }
131 }
132
59735506 133 if (
3ae62cab 134 !$granted
59735506
TO
135 && !($tempPerm && $tempPerm->check($permission))
136 ) {
60ec9f43
E
137 //one of our 'and' conditions has not been met
138 return FALSE;
139 }
140 }
141 }
142 return TRUE;
6a488035
TO
143 }
144
dc92f2f8 145 /**
d09edf64 146 * Determine if any one of the permissions strings applies to current user.
dc92f2f8
TO
147 *
148 * @param array $perms
149 * @return bool
150 */
151 public static function checkAnyPerm($perms) {
152 foreach ($perms as $perm) {
153 if (CRM_Core_Permission::check($perm)) {
154 return TRUE;
155 }
156 }
157 return FALSE;
158 }
159
6a488035
TO
160 /**
161 * Given a group/role array, check for access requirements
162 *
6a0b768e
TO
163 * @param array $array
164 * The group/role to check.
6a488035 165 *
acb1052e 166 * @return bool
a6c01b45 167 * true if yes, else false
6a488035 168 */
00be9182 169 public static function checkGroupRole($array) {
6a488035 170 $config = CRM_Core_Config::singleton();
41f314b6 171 return $config->userPermissionClass->checkGroupRole($array);
6a488035
TO
172 }
173
174 /**
d09edf64 175 * Get the permissioned where clause for the user.
6a488035 176 *
6a0b768e
TO
177 * @param int $type
178 * The type of permission needed.
179 * @param array $tables
180 * (reference ) add the tables that are needed for the select clause.
181 * @param array $whereTables
182 * (reference ) add the tables that are needed for the where clause.
6a488035 183 *
a6c01b45
CW
184 * @return string
185 * the group where clause for this user
6a488035
TO
186 */
187 public static function getPermissionedStaticGroupClause($type, &$tables, &$whereTables) {
188 $config = CRM_Core_Config::singleton();
41f314b6 189 return $config->userPermissionClass->getPermissionedStaticGroupClause($type, $tables, $whereTables);
6a488035
TO
190 }
191
192 /**
193 * Get all groups from database, filtered by permissions
194 * for this user
195 *
6a0b768e
TO
196 * @param string $groupType
197 * Type of group(Access/Mailing).
3f8d2862
CW
198 * @param bool $excludeHidden
199 * exclude hidden groups.
6a488035 200 *
6a488035 201 *
a6c01b45
CW
202 * @return array
203 * array reference of all groups.
6a488035
TO
204 */
205 public static function group($groupType, $excludeHidden = TRUE) {
206 $config = CRM_Core_Config::singleton();
41f314b6 207 return $config->userPermissionClass->group($groupType, $excludeHidden);
6a488035
TO
208 }
209
a0ee3941
EM
210 /**
211 * @return bool
212 */
6a488035
TO
213 public static function customGroupAdmin() {
214 $admin = FALSE;
215
216 // check if user has all powerful permission
217 // or administer civicrm permission (CRM-1905)
218 if (self::check('access all custom data')) {
219 return TRUE;
220 }
221
634e1a1a
DL
222 if (
223 self::check('administer Multiple Organizations') &&
6a488035
TO
224 self::isMultisiteEnabled()
225 ) {
226 return TRUE;
227 }
228
229 if (self::check('administer CiviCRM')) {
230 return TRUE;
231 }
232
233 return FALSE;
234 }
235
a0ee3941
EM
236 /**
237 * @param int $type
238 * @param bool $reset
239 *
240 * @return array
241 */
6a488035 242 public static function customGroup($type = CRM_Core_Permission::VIEW, $reset = FALSE) {
41f314b6 243 $customGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_CustomField', 'custom_group_id',
be2fb01f
CW
244 ['fresh' => $reset]);
245 $defaultGroups = [];
6a488035
TO
246
247 // check if user has all powerful permission
248 // or administer civicrm permission (CRM-1905)
249 if (self::customGroupAdmin()) {
250 $defaultGroups = array_keys($customGroups);
251 }
252
253 return CRM_ACL_API::group($type, NULL, 'civicrm_custom_group', $customGroups, $defaultGroups);
254 }
255
a0ee3941
EM
256 /**
257 * @param int $type
258 * @param null $prefix
259 * @param bool $reset
260 *
261 * @return string
262 */
00be9182 263 public static function customGroupClause($type = CRM_Core_Permission::VIEW, $prefix = NULL, $reset = FALSE) {
6a488035
TO
264 if (self::customGroupAdmin()) {
265 return ' ( 1 ) ';
266 }
267
268 $groups = self::customGroup($type, $reset);
269 if (empty($groups)) {
270 return ' ( 0 ) ';
271 }
272 else {
273 return "{$prefix}id IN ( " . implode(',', $groups) . ' ) ';
274 }
275 }
276
a0ee3941 277 /**
100fef9d 278 * @param int $gid
a0ee3941
EM
279 * @param int $type
280 *
281 * @return bool
282 */
6a488035
TO
283 public static function ufGroupValid($gid, $type = CRM_Core_Permission::VIEW) {
284 if (empty($gid)) {
285 return TRUE;
286 }
287
288 $groups = self::ufGroup($type);
63d76404 289 return !empty($groups) && in_array($gid, $groups);
6a488035
TO
290 }
291
a0ee3941
EM
292 /**
293 * @param int $type
294 *
295 * @return array
296 */
6a488035 297 public static function ufGroup($type = CRM_Core_Permission::VIEW) {
ff4f7744 298 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
299
300 $allGroups = array_keys($ufGroups);
301
302 // check if user has all powerful permission
303 if (self::check('profile listings and forms')) {
304 return $allGroups;
305 }
306
307 switch ($type) {
308 case CRM_Core_Permission::VIEW:
309 if (self::check('profile view')) {
310 return $allGroups;
311 }
312 break;
313
314 case CRM_Core_Permission::CREATE:
315 if (self::check('profile create')) {
316 return $allGroups;
317 }
318 break;
319
320 case CRM_Core_Permission::EDIT:
321 if (self::check('profile edit')) {
322 return $allGroups;
323 }
324 break;
325
326 case CRM_Core_Permission::SEARCH:
327 if (self::check('profile listings')) {
328 return $allGroups;
329 }
330 break;
331 }
332
333 return CRM_ACL_API::group($type, NULL, 'civicrm_uf_group', $ufGroups);
334 }
335
a0ee3941
EM
336 /**
337 * @param int $type
338 * @param null $prefix
339 * @param bool $returnUFGroupIds
340 *
341 * @return array|string
342 */
00be9182 343 public static function ufGroupClause($type = CRM_Core_Permission::VIEW, $prefix = NULL, $returnUFGroupIds = FALSE) {
6a488035
TO
344 $groups = self::ufGroup($type);
345 if ($returnUFGroupIds) {
346 return $groups;
347 }
348 elseif (empty($groups)) {
349 return ' ( 0 ) ';
350 }
351 else {
352 return "{$prefix}id IN ( " . implode(',', $groups) . ' ) ';
353 }
354 }
355
a0ee3941
EM
356 /**
357 * @param int $type
100fef9d 358 * @param int $eventID
a0ee3941
EM
359 * @param string $context
360 *
361 * @return array|null
362 */
e2d09ab4 363 public static function event($type = CRM_Core_Permission::VIEW, $eventID = NULL, $context = '') {
22e263ad
TO
364 if (!empty($context)) {
365 if (CRM_Core_Permission::check($context)) {
e2d09ab4
EM
366 return TRUE;
367 }
368 }
6a488035 369 $events = CRM_Event_PseudoConstant::event(NULL, TRUE);
be2fb01f 370 $includeEvents = [];
6a488035
TO
371
372 // check if user has all powerful permission
373 if (self::check('register for events')) {
374 $includeEvents = array_keys($events);
375 }
376
377 if ($type == CRM_Core_Permission::VIEW &&
378 self::check('view event info')
379 ) {
380 $includeEvents = array_keys($events);
381 }
382
383 $permissionedEvents = CRM_ACL_API::group($type, NULL, 'civicrm_event', $events, $includeEvents);
384 if (!$eventID) {
385 return $permissionedEvents;
386 }
41f314b6 387 if (!empty($permissionedEvents)) {
2efcf0c2 388 return array_search($eventID, $permissionedEvents) === FALSE ? NULL : $eventID;
41f314b6 389 }
dfa720e7 390 return NULL;
6a488035
TO
391 }
392
a0ee3941
EM
393 /**
394 * @param int $type
395 * @param null $prefix
396 *
397 * @return string
398 */
00be9182 399 public static function eventClause($type = CRM_Core_Permission::VIEW, $prefix = NULL) {
6a488035
TO
400 $events = self::event($type);
401 if (empty($events)) {
402 return ' ( 0 ) ';
403 }
404 else {
405 return "{$prefix}id IN ( " . implode(',', $events) . ' ) ';
406 }
407 }
408
a0ee3941 409 /**
44d17ec8
BS
410 * Checks that component is enabled and optionally that user has basic perm.
411 *
412 * @param string $module
413 * Specifies the name of the CiviCRM component.
a0ee3941 414 * @param bool $checkPermission
44d17ec8
BS
415 * Check not only that module is enabled, but that user has necessary
416 * permission.
417 * @param bool $requireAllCasesPermOnCiviCase
418 * Significant only if $module == CiviCase
419 * Require "access all cases and activities", not just
420 * "access my cases and activities".
a0ee3941
EM
421 *
422 * @return bool
44d17ec8 423 * Access to specified $module is granted.
a0ee3941 424 */
44d17ec8 425 public static function access($module, $checkPermission = TRUE, $requireAllCasesPermOnCiviCase = FALSE) {
6a488035
TO
426 $config = CRM_Core_Config::singleton();
427
428 if (!in_array($module, $config->enableComponents)) {
429 return FALSE;
430 }
431
432 if ($checkPermission) {
44d17ec8
BS
433 switch ($module) {
434 case 'CiviCase':
435 $access_all_cases = CRM_Core_Permission::check("access all cases and activities");
436 $access_my_cases = CRM_Core_Permission::check("access my cases and activities");
437 return $access_all_cases || (!$requireAllCasesPermOnCiviCase && $access_my_cases);
438
439 case 'CiviCampaign':
440 return CRM_Core_Permission::check("administer $module");
441
442 default:
443 return CRM_Core_Permission::check("access $module");
6a488035
TO
444 }
445 }
446
447 return TRUE;
448 }
449
450 /**
d09edf64 451 * Check permissions for delete and edit actions.
6a488035 452 *
6a0b768e
TO
453 * @param string $module
454 * Component name.
455 * @param int $action
456 * Action to be check across component.
6a488035 457 *
77b97be7
EM
458 *
459 * @return bool
460 */
00be9182 461 public static function checkActionPermission($module, $action) {
6a488035
TO
462 //check delete related permissions.
463 if ($action & CRM_Core_Action::DELETE) {
464 $permissionName = "delete in $module";
465 }
466 else {
be2fb01f 467 $editPermissions = [
6a488035
TO
468 'CiviEvent' => 'edit event participants',
469 'CiviMember' => 'edit memberships',
470 'CiviPledge' => 'edit pledges',
471 'CiviContribute' => 'edit contributions',
472 'CiviGrant' => 'edit grants',
473 'CiviMail' => 'access CiviMail',
474 'CiviAuction' => 'add auction items',
be2fb01f 475 ];
9c1bc317 476 $permissionName = $editPermissions[$module] ?? NULL;
6a488035
TO
477 }
478
479 if ($module == 'CiviCase' && !$permissionName) {
480 return CRM_Case_BAO_Case::accessCiviCase();
481 }
482 else {
483 //check for permission.
484 return CRM_Core_Permission::check($permissionName);
485 }
486 }
487
a0ee3941
EM
488 /**
489 * @param $args
490 * @param string $op
491 *
492 * @return bool
493 */
00be9182 494 public static function checkMenu(&$args, $op = 'and') {
6a488035
TO
495 if (!is_array($args)) {
496 return $args;
497 }
498 foreach ($args as $str) {
499 $res = CRM_Core_Permission::check($str);
500 if ($op == 'or' && $res) {
501 return TRUE;
502 }
503 elseif ($op == 'and' && !$res) {
504 return FALSE;
505 }
506 }
507 return ($op == 'or') ? FALSE : TRUE;
508 }
509
a0ee3941
EM
510 /**
511 * @param $item
512 *
513 * @return bool|mixed
514 * @throws Exception
515 */
00be9182 516 public static function checkMenuItem(&$item) {
6a488035
TO
517 if (!array_key_exists('access_callback', $item)) {
518 CRM_Core_Error::backtrace();
79e11805 519 throw new CRM_Core_Exception('Missing Access Callback key in menu item');
6a488035
TO
520 }
521
522 // if component_id is present, ensure it is enabled
3d31a5c6
TO
523 if (isset($item['component_id']) && $item['component_id']) {
524 if (!isset(Civi::$statics[__CLASS__]['componentNameId'])) {
525 Civi::$statics[__CLASS__]['componentNameId'] = array_flip(CRM_Core_Component::getComponentIDs());
526 }
527 $componentName = Civi::$statics[__CLASS__]['componentNameId'][$item['component_id']];
528
6a488035 529 $config = CRM_Core_Config::singleton();
3d31a5c6 530 if (is_array($config->enableComponents) && in_array($componentName, $config->enableComponents)) {
6a488035
TO
531 // continue with process
532 }
533 else {
534 return FALSE;
535 }
536 }
537
538 // the following is imitating drupal 6 code in includes/menu.inc
539 if (empty($item['access_callback']) ||
540 is_numeric($item['access_callback'])
541 ) {
596a8bdf 542 return (bool) $item['access_callback'];
6a488035
TO
543 }
544
545 // check whether the following Ajax requests submitted the right key
546 // FIXME: this should be integrated into ACLs proper
547 if (CRM_Utils_Array::value('page_type', $item) == 3) {
548 if (!CRM_Core_Key::validate($_REQUEST['key'], $item['path'])) {
549 return FALSE;
550 }
551 }
552
553 // check if callback is for checkMenu, if so optimize it
554 if (is_array($item['access_callback']) &&
555 $item['access_callback'][0] == 'CRM_Core_Permission' &&
556 $item['access_callback'][1] == 'checkMenu'
557 ) {
558 $op = CRM_Utils_Array::value(1, $item['access_arguments'], 'and');
559 return self::checkMenu($item['access_arguments'][0], $op);
560 }
561 else {
562 return call_user_func_array($item['access_callback'], $item['access_arguments']);
563 }
564 }
565
a0ee3941
EM
566 /**
567 * @param bool $all
9476d8d1 568 * Include disabled components
221b21b4 569 * @param bool $descriptions
9476d8d1 570 * Whether to return descriptions
a0ee3941
EM
571 *
572 * @return array
573 */
9476d8d1 574 public static function basicPermissions($all = FALSE, $descriptions = FALSE) {
be2fb01f 575 $cacheKey = implode('-', [$all, $descriptions]);
9476d8d1
CW
576 if (empty(Civi::$statics[__CLASS__][__FUNCTION__][$cacheKey])) {
577 Civi::$statics[__CLASS__][__FUNCTION__][$cacheKey] = self::assembleBasicPermissions($all, $descriptions);
221b21b4 578 }
9476d8d1 579 return Civi::$statics[__CLASS__][__FUNCTION__][$cacheKey];
221b21b4
AH
580 }
581
582 /**
583 * @param bool $all
584 * @param bool $descriptions
585 * whether to return descriptions
586 *
587 * @return array
588 */
589 public static function assembleBasicPermissions($all = FALSE, $descriptions = FALSE) {
590 $config = CRM_Core_Config::singleton();
591 $prefix = ts('CiviCRM') . ': ';
592 $permissions = self::getCorePermissions($descriptions);
593
594 if (self::isMultisiteEnabled()) {
be2fb01f 595 $permissions['administer Multiple Organizations'] = [$prefix . ts('administer Multiple Organizations')];
221b21b4
AH
596 }
597
8c282315 598 if (!$descriptions) {
599 foreach ($permissions as $name => $attr) {
600 $permissions[$name] = array_shift($attr);
601 }
602 }
221b21b4
AH
603 if (!$all) {
604 $components = CRM_Core_Component::getEnabledComponents();
605 }
606 else {
607 $components = CRM_Core_Component::getComponents();
608 }
609
610 foreach ($components as $comp) {
d47b93bf 611 $perm = $comp->getPermissions($all, $descriptions);
221b21b4
AH
612 if ($perm) {
613 $info = $comp->getInfo();
2666861c
KL
614 foreach ($perm as $p => $attr) {
615
616 if (!is_array($attr)) {
be2fb01f 617 $attr = [$attr];
2666861c
KL
618 }
619
620 $attr[0] = $info['translatedName'] . ': ' . $attr[0];
621
622 if ($descriptions) {
221b21b4
AH
623 $permissions[$p] = $attr;
624 }
2666861c
KL
625 else {
626 $permissions[$p] = $attr[0];
6a488035
TO
627 }
628 }
629 }
6a488035
TO
630 }
631
221b21b4 632 // Add any permissions defined in hook_civicrm_permission implementations.
f1db52b9 633 $module_permissions = $config->userPermissionClass->getAllModulePermissions($descriptions);
221b21b4 634 $permissions = array_merge($permissions, $module_permissions);
cb2f7dd1 635 CRM_Financial_BAO_FinancialType::permissionedFinancialTypes($permissions, $descriptions);
6a488035
TO
636 return $permissions;
637 }
638
a0ee3941
EM
639 /**
640 * @return array
641 */
00be9182 642 public static function getAnonymousPermissionsWarnings() {
be2fb01f 643 static $permissions = [];
81bb85ea 644 if (empty($permissions)) {
be2fb01f 645 $permissions = [
21dfd5f5 646 'administer CiviCRM',
be2fb01f 647 ];
81bb85ea
AC
648 $components = CRM_Core_Component::getComponents();
649 foreach ($components as $comp) {
650 if (!method_exists($comp, 'getAnonymousPermissionWarnings')) {
651 continue;
652 }
653 $permissions = array_merge($permissions, $comp->getAnonymousPermissionWarnings());
654 }
655 }
656 return $permissions;
657 }
658
a0ee3941
EM
659 /**
660 * @param $anonymous_perms
661 *
662 * @return array
663 */
00be9182 664 public static function validateForPermissionWarnings($anonymous_perms) {
81bb85ea
AC
665 return array_intersect($anonymous_perms, self::getAnonymousPermissionsWarnings());
666 }
667
a0ee3941 668 /**
6793d6a9 669 * Get core permissions.
221b21b4 670 *
a0ee3941
EM
671 * @return array
672 */
8c282315 673 public static function getCorePermissions() {
6a488035 674 $prefix = ts('CiviCRM') . ': ';
be2fb01f
CW
675 $permissions = [
676 'add contacts' => [
221b21b4
AH
677 $prefix . ts('add contacts'),
678 ts('Create a new contact record in CiviCRM'),
be2fb01f
CW
679 ],
680 'view all contacts' => [
221b21b4
AH
681 $prefix . ts('view all contacts'),
682 ts('View ANY CONTACT in the CiviCRM database, export contact info and perform activities such as Send Email, Phone Call, etc.'),
be2fb01f
CW
683 ],
684 'edit all contacts' => [
221b21b4
AH
685 $prefix . ts('edit all contacts'),
686 ts('View, Edit and Delete ANY CONTACT in the CiviCRM database; Create and edit relationships, tags and other info about the contacts'),
be2fb01f
CW
687 ],
688 'view my contact' => [
221b21b4 689 $prefix . ts('view my contact'),
be2fb01f
CW
690 ],
691 'edit my contact' => [
221b21b4 692 $prefix . ts('edit my contact'),
be2fb01f
CW
693 ],
694 'delete contacts' => [
221b21b4 695 $prefix . ts('delete contacts'),
be2fb01f
CW
696 ],
697 'access deleted contacts' => [
221b21b4
AH
698 $prefix . ts('access deleted contacts'),
699 ts('Access contacts in the trash'),
be2fb01f
CW
700 ],
701 'import contacts' => [
221b21b4
AH
702 $prefix . ts('import contacts'),
703 ts('Import contacts and activities'),
be2fb01f
CW
704 ],
705 'import SQL datasource' => [
40bc3c68
TO
706 $prefix . ts('import SQL datasource'),
707 ts('When importing, consume data directly from a SQL datasource'),
be2fb01f
CW
708 ],
709 'edit groups' => [
221b21b4
AH
710 $prefix . ts('edit groups'),
711 ts('Create new groups, edit group settings (e.g. group name, visibility...), delete groups'),
be2fb01f
CW
712 ],
713 'administer CiviCRM' => [
221b21b4
AH
714 $prefix . ts('administer CiviCRM'),
715 ts('Perform all tasks in the Administer CiviCRM control panel and Import Contacts'),
be2fb01f
CW
716 ],
717 'skip IDS check' => [
221b21b4 718 $prefix . ts('skip IDS check'),
d9a37cbc 719 ts('Warning: Give to trusted roles only; this permission has security implications. IDS system is bypassed for users with this permission. Prevents false errors for admin users.'),
be2fb01f
CW
720 ],
721 'access uploaded files' => [
221b21b4
AH
722 $prefix . ts('access uploaded files'),
723 ts('View / download files including images and photos'),
be2fb01f
CW
724 ],
725 'profile listings and forms' => [
221b21b4 726 $prefix . ts('profile listings and forms'),
d9a37cbc 727 ts('Warning: Give to trusted roles only; this permission has privacy implications. Add/edit data in online forms and access public searchable directories.'),
be2fb01f
CW
728 ],
729 'profile listings' => [
221b21b4 730 $prefix . ts('profile listings'),
d9a37cbc 731 ts('Warning: Give to trusted roles only; this permission has privacy implications. Access public searchable directories.'),
be2fb01f
CW
732 ],
733 'profile create' => [
221b21b4 734 $prefix . ts('profile create'),
d9a37cbc 735 ts('Add data in a profile form.'),
be2fb01f
CW
736 ],
737 'profile edit' => [
221b21b4 738 $prefix . ts('profile edit'),
d9a37cbc 739 ts('Edit data in a profile form.'),
be2fb01f
CW
740 ],
741 'profile view' => [
221b21b4 742 $prefix . ts('profile view'),
d9a37cbc 743 ts('View data in a profile.'),
be2fb01f
CW
744 ],
745 'access all custom data' => [
221b21b4
AH
746 $prefix . ts('access all custom data'),
747 ts('View all custom fields regardless of ACL rules'),
be2fb01f
CW
748 ],
749 'view all activities' => [
221b21b4
AH
750 $prefix . ts('view all activities'),
751 ts('View all activities (for visible contacts)'),
be2fb01f
CW
752 ],
753 'delete activities' => [
221b21b4 754 $prefix . ts('Delete activities'),
be2fb01f
CW
755 ],
756 'edit inbound email basic information' => [
ee90a98c
CR
757 $prefix . ts('edit inbound email basic information'),
758 ts('Edit all inbound email activities (for visible contacts) basic information. Content editing not allowed.'),
be2fb01f
CW
759 ],
760 'edit inbound email basic information and content' => [
ee90a98c
CR
761 $prefix . ts('edit inbound email basic information and content'),
762 ts('Edit all inbound email activities (for visible contacts) basic information and content.'),
be2fb01f
CW
763 ],
764 'access CiviCRM' => [
d9a37cbc
H
765 $prefix . ts('access CiviCRM backend and API'),
766 ts('Master control for access to the main CiviCRM backend and API. Give to trusted roles only.'),
be2fb01f
CW
767 ],
768 'access Contact Dashboard' => [
221b21b4
AH
769 $prefix . ts('access Contact Dashboard'),
770 ts('View Contact Dashboard (for themselves and visible contacts)'),
be2fb01f
CW
771 ],
772 'translate CiviCRM' => [
221b21b4
AH
773 $prefix . ts('translate CiviCRM'),
774 ts('Allow User to enable multilingual'),
be2fb01f
CW
775 ],
776 'manage tags' => [
eaaaef83
I
777 $prefix . ts('manage tags'),
778 ts('Create and rename tags'),
be2fb01f
CW
779 ],
780 'administer reserved groups' => [
221b21b4
AH
781 $prefix . ts('administer reserved groups'),
782 ts('Edit and disable Reserved Groups (Needs Edit Groups)'),
be2fb01f
CW
783 ],
784 'administer Tagsets' => [
221b21b4 785 $prefix . ts('administer Tagsets'),
be2fb01f
CW
786 ],
787 'administer reserved tags' => [
221b21b4 788 $prefix . ts('administer reserved tags'),
be2fb01f
CW
789 ],
790 'administer dedupe rules' => [
221b21b4
AH
791 $prefix . ts('administer dedupe rules'),
792 ts('Create and edit rules, change the supervised and unsupervised rules'),
be2fb01f
CW
793 ],
794 'merge duplicate contacts' => [
221b21b4
AH
795 $prefix . ts('merge duplicate contacts'),
796 ts('Delete Contacts must also be granted in order for this to work.'),
be2fb01f
CW
797 ],
798 'force merge duplicate contacts' => [
fd630ef9 799 $prefix . ts('force merge duplicate contacts'),
800 ts('Delete Contacts must also be granted in order for this to work.'),
be2fb01f
CW
801 ],
802 'view debug output' => [
221b21b4
AH
803 $prefix . ts('view debug output'),
804 ts('View results of debug and backtrace'),
be2fb01f 805 ],
02d451ab 806
be2fb01f 807 'view all notes' => [
221b21b4
AH
808 $prefix . ts('view all notes'),
809 ts("View notes (for visible contacts) even if they're marked admin only"),
be2fb01f
CW
810 ],
811 'add contact notes' => [
088101a4
O
812 $prefix . ts('add contact notes'),
813 ts("Create notes for contacts"),
be2fb01f
CW
814 ],
815 'access AJAX API' => [
221b21b4
AH
816 $prefix . ts('access AJAX API'),
817 ts('Allow API access even if Access CiviCRM is not granted'),
be2fb01f
CW
818 ],
819 'access contact reference fields' => [
221b21b4
AH
820 $prefix . ts('access contact reference fields'),
821 ts('Allow entering data into contact reference fields'),
be2fb01f
CW
822 ],
823 'create manual batch' => [
221b21b4
AH
824 $prefix . ts('create manual batch'),
825 ts('Create an accounting batch (with Access to CiviContribute and View Own/All Manual Batches)'),
be2fb01f
CW
826 ],
827 'edit own manual batches' => [
221b21b4
AH
828 $prefix . ts('edit own manual batches'),
829 ts('Edit accounting batches created by user'),
be2fb01f
CW
830 ],
831 'edit all manual batches' => [
221b21b4
AH
832 $prefix . ts('edit all manual batches'),
833 ts('Edit all accounting batches'),
be2fb01f
CW
834 ],
835 'close own manual batches' => [
47a98aef 836 $prefix . ts('close own manual batches'),
5ad18cc2 837 ts('Close accounting batches created by user (with Access to CiviContribute)'),
be2fb01f
CW
838 ],
839 'close all manual batches' => [
47a98aef 840 $prefix . ts('close all manual batches'),
5ad18cc2 841 ts('Close all accounting batches (with Access to CiviContribute)'),
be2fb01f
CW
842 ],
843 'reopen own manual batches' => [
47a98aef 844 $prefix . ts('reopen own manual batches'),
5ad18cc2 845 ts('Reopen accounting batches created by user (with Access to CiviContribute)'),
be2fb01f
CW
846 ],
847 'reopen all manual batches' => [
47a98aef 848 $prefix . ts('reopen all manual batches'),
5ad18cc2 849 ts('Reopen all accounting batches (with Access to CiviContribute)'),
be2fb01f
CW
850 ],
851 'view own manual batches' => [
221b21b4
AH
852 $prefix . ts('view own manual batches'),
853 ts('View accounting batches created by user (with Access to CiviContribute)'),
be2fb01f
CW
854 ],
855 'view all manual batches' => [
221b21b4
AH
856 $prefix . ts('view all manual batches'),
857 ts('View all accounting batches (with Access to CiviContribute)'),
be2fb01f
CW
858 ],
859 'delete own manual batches' => [
221b21b4
AH
860 $prefix . ts('delete own manual batches'),
861 ts('Delete accounting batches created by user'),
be2fb01f
CW
862 ],
863 'delete all manual batches' => [
221b21b4
AH
864 $prefix . ts('delete all manual batches'),
865 ts('Delete all accounting batches'),
be2fb01f
CW
866 ],
867 'export own manual batches' => [
221b21b4
AH
868 $prefix . ts('export own manual batches'),
869 ts('Export accounting batches created by user'),
be2fb01f
CW
870 ],
871 'export all manual batches' => [
221b21b4
AH
872 $prefix . ts('export all manual batches'),
873 ts('Export all accounting batches'),
be2fb01f
CW
874 ],
875 'administer payment processors' => [
221b21b4
AH
876 $prefix . ts('administer payment processors'),
877 ts('Add, Update, or Disable Payment Processors'),
be2fb01f
CW
878 ],
879 'edit message templates' => [
221b21b4 880 $prefix . ts('edit message templates'),
be2fb01f
CW
881 ],
882 'edit system workflow message templates' => [
40a732a9 883 $prefix . ts('edit system workflow message templates'),
be2fb01f
CW
884 ],
885 'edit user-driven message templates' => [
40a732a9 886 $prefix . ts('edit user-driven message templates'),
be2fb01f
CW
887 ],
888 'view my invoices' => [
a664e7b3 889 $prefix . ts('view my invoices'),
dc6b437a 890 ts('Allow users to view/ download their own invoices'),
be2fb01f
CW
891 ],
892 'edit api keys' => [
d4463076
TO
893 $prefix . ts('edit api keys'),
894 ts('Edit API keys'),
be2fb01f
CW
895 ],
896 'edit own api keys' => [
d4463076
TO
897 $prefix . ts('edit own api keys'),
898 ts('Edit user\'s own API keys'),
be2fb01f
CW
899 ],
900 'send SMS' => [
63483feb
MM
901 $prefix . ts('send SMS'),
902 ts('Send an SMS'),
be2fb01f 903 ],
755a1835 904 'administer CiviCRM system' => [
905 'label' => $prefix . ts('administer CiviCRM System'),
4c85c7b6 906 'description' => ts('Perform all system administration tasks in CiviCRM'),
755a1835 907 ],
908 'administer CiviCRM data' => [
909 'label' => $prefix . ts('administer CiviCRM Data'),
4c85c7b6 910 'description' => ts('Permit altering all restricted data options'),
755a1835 911 ],
be2fb01f 912 ];
755a1835 913 foreach (self::getImpliedPermissions() as $name => $includes) {
914 foreach ($includes as $permission) {
915 $permissions[$name][] = $permissions[$permission];
916 }
917 }
6a488035
TO
918 return $permissions;
919 }
920
755a1835 921 /**
922 * Get permissions implied by 'superset' permissions.
923 *
924 * @return array
925 */
926 public static function getImpliedPermissions() {
927 return [
928 'administer CiviCRM' => ['administer CiviCRM system', 'administer CiviCRM data'],
929 'administer CiviCRM data' => ['edit message templates', 'administer dedupe rules'],
c424169e 930 'administer CiviCRM system' => ['edit system workflow message templates'],
755a1835 931 ];
932 }
933
934 /**
935 * Get any super-permissions that imply the given permission.
936 *
937 * @param string $permission
938 *
939 * @return array
940 */
941 public static function getImpliedPermissionsFor(string $permission) {
942 $return = [];
943 foreach (self::getImpliedPermissions() as $superPermission => $components) {
944 if (in_array($permission, $components, TRUE)) {
945 $return[$superPermission] = $superPermission;
946 }
947 }
948 return $return;
949 }
950
bf9a7c0f
ES
951 /**
952 * For each entity provides an array of permissions required for each action
953 *
954 * The action is the array key, possible values:
955 * * create: applies to create (with no id in params)
956 * * update: applies to update, setvalue, create (with id in params)
957 * * get: applies to getcount, getsingle, getvalue and other gets
958 * * delete: applies to delete, replace
959 * * meta: applies to getfields, getoptions, getspec
960 * * default: catch-all for anything not declared
961 *
962 * Note: some APIs declare other actions as well
963 *
964 * Permissions should use arrays for AND and arrays of arrays for OR
1a5a2ade 965 * @see CRM_Core_Permission::check
bf9a7c0f
ES
966 *
967 * @return array of permissions
968 */
969 public static function getEntityActionPermissions() {
be2fb01f 970 $permissions = [];
bf9a7c0f
ES
971 // These are the default permissions - if any entity does not declare permissions for a given action,
972 // (or the entity does not declare permissions at all) - then the action will be used from here
be2fb01f 973 $permissions['default'] = [
bf9a7c0f 974 // applies to getfields, getoptions, etc.
be2fb01f 975 'meta' => ['access CiviCRM'],
bf9a7c0f
ES
976 // catch-all, applies to create, get, delete, etc.
977 // If an entity declares it's own 'default' action it will override this one
be2fb01f
CW
978 'default' => ['administer CiviCRM'],
979 ];
bf9a7c0f
ES
980
981 // Note: Additional permissions in DynamicFKAuthorization
be2fb01f
CW
982 $permissions['attachment'] = [
983 'default' => [
984 ['access CiviCRM', 'access AJAX API'],
985 ],
986 ];
bf9a7c0f
ES
987
988 // Contact permissions
be2fb01f
CW
989 $permissions['contact'] = [
990 'create' => [
bf9a7c0f
ES
991 'access CiviCRM',
992 'add contacts',
be2fb01f
CW
993 ],
994 'delete' => [
bf9a7c0f
ES
995 'access CiviCRM',
996 'delete contacts',
be2fb01f 997 ],
bf9a7c0f 998 // managed by query object
be2fb01f 999 'get' => [],
bf9a7c0f 1000 // managed by _civicrm_api3_check_edit_permissions
be2fb01f
CW
1001 'update' => [],
1002 'getquick' => [
1003 ['access CiviCRM', 'access AJAX API'],
1004 ],
1005 'duplicatecheck' => [
f257308b 1006 'access CiviCRM',
be2fb01f 1007 ],
9f8c8b7a 1008 'merge' => ['merge duplicate contacts'],
be2fb01f 1009 ];
bf9a7c0f 1010
cc477693 1011 $permissions['dedupe'] = [
1012 'getduplicates' => ['access CiviCRM'],
3ea6ec7d 1013 'getstatistics' => ['access CiviCRM'],
cc477693 1014 ];
1015
bf9a7c0f 1016 // CRM-16963 - Permissions for country.
be2fb01f
CW
1017 $permissions['country'] = [
1018 'get' => [
bf9a7c0f 1019 'access CiviCRM',
be2fb01f
CW
1020 ],
1021 'default' => [
bf9a7c0f 1022 'administer CiviCRM',
be2fb01f
CW
1023 ],
1024 ];
bf9a7c0f
ES
1025
1026 // Contact-related data permissions.
be2fb01f 1027 $permissions['address'] = [
bf9a7c0f
ES
1028 // get is managed by BAO::addSelectWhereClause
1029 // create/delete are managed by _civicrm_api3_check_edit_permissions
be2fb01f
CW
1030 'default' => [],
1031 ];
bf9a7c0f
ES
1032 $permissions['email'] = $permissions['address'];
1033 $permissions['phone'] = $permissions['address'];
1034 $permissions['website'] = $permissions['address'];
1035 $permissions['im'] = $permissions['address'];
1036 $permissions['open_i_d'] = $permissions['address'];
1037
1038 // Also managed by ACLs - CRM-19448
be2fb01f 1039 $permissions['entity_tag'] = ['default' => []];
bf9a7c0f
ES
1040 $permissions['note'] = $permissions['entity_tag'];
1041
1042 // Allow non-admins to get and create tags to support tagset widget
1043 // Delete is still reserved for admins
be2fb01f
CW
1044 $permissions['tag'] = [
1045 'get' => ['access CiviCRM'],
1046 'create' => ['access CiviCRM'],
1047 'update' => ['access CiviCRM'],
1048 ];
bf9a7c0f
ES
1049
1050 //relationship permissions
be2fb01f 1051 $permissions['relationship'] = [
bf9a7c0f 1052 // get is managed by BAO::addSelectWhereClause
be2fb01f
CW
1053 'get' => [],
1054 'delete' => [
bf9a7c0f
ES
1055 'access CiviCRM',
1056 'edit all contacts',
be2fb01f
CW
1057 ],
1058 'default' => [
bf9a7c0f
ES
1059 'access CiviCRM',
1060 'edit all contacts',
be2fb01f
CW
1061 ],
1062 ];
bf9a7c0f
ES
1063
1064 // CRM-17741 - Permissions for RelationshipType.
be2fb01f
CW
1065 $permissions['relationship_type'] = [
1066 'get' => [
bf9a7c0f 1067 'access CiviCRM',
be2fb01f
CW
1068 ],
1069 'default' => [
bf9a7c0f 1070 'administer CiviCRM',
be2fb01f
CW
1071 ],
1072 ];
bf9a7c0f
ES
1073
1074 // Activity permissions
be2fb01f
CW
1075 $permissions['activity'] = [
1076 'delete' => [
bf9a7c0f
ES
1077 'access CiviCRM',
1078 'delete activities',
be2fb01f
CW
1079 ],
1080 'get' => [
bf9a7c0f
ES
1081 'access CiviCRM',
1082 // Note that view all activities is also required within the api
1083 // if the id is not passed in. Where the id is passed in the activity
1084 // specific check functions are used and tested.
be2fb01f
CW
1085 ],
1086 'default' => [
bf9a7c0f
ES
1087 'access CiviCRM',
1088 'view all activities',
be2fb01f
CW
1089 ],
1090 ];
cdacd6ab 1091 $permissions['activity_contact'] = $permissions['activity'];
bf9a7c0f
ES
1092
1093 // Case permissions
be2fb01f
CW
1094 $permissions['case'] = [
1095 'create' => [
bf9a7c0f
ES
1096 'access CiviCRM',
1097 'add cases',
be2fb01f
CW
1098 ],
1099 'delete' => [
bf9a7c0f
ES
1100 'access CiviCRM',
1101 'delete in CiviCase',
be2fb01f
CW
1102 ],
1103 'restore' => [
8572e6de 1104 'administer CiviCase',
be2fb01f
CW
1105 ],
1106 'merge' => [
a6bc7218 1107 'administer CiviCase',
be2fb01f
CW
1108 ],
1109 'default' => [
bf9a7c0f 1110 // At minimum the user needs one of the following. Finer-grained access is controlled by CRM_Case_BAO_Case::addSelectWhereClause
be2fb01f
CW
1111 ['access my cases and activities', 'access all cases and activities'],
1112 ],
1113 ];
bf9a7c0f
ES
1114 $permissions['case_contact'] = $permissions['case'];
1115
be2fb01f
CW
1116 $permissions['case_type'] = [
1117 'default' => ['administer CiviCase'],
1118 'get' => [
bf9a7c0f 1119 // nested array = OR
be2fb01f
CW
1120 ['access my cases and activities', 'access all cases and activities'],
1121 ],
1122 ];
bf9a7c0f
ES
1123
1124 // Campaign permissions
be2fb01f
CW
1125 $permissions['campaign'] = [
1126 'get' => ['access CiviCRM'],
1127 'default' => [
bf9a7c0f 1128 // nested array = OR
be2fb01f
CW
1129 ['administer CiviCampaign', 'manage campaign'],
1130 ],
1131 ];
bf9a7c0f
ES
1132 $permissions['survey'] = $permissions['campaign'];
1133
1134 // Financial permissions
be2fb01f
CW
1135 $permissions['contribution'] = [
1136 'get' => [
bf9a7c0f
ES
1137 'access CiviCRM',
1138 'access CiviContribute',
be2fb01f
CW
1139 ],
1140 'delete' => [
bf9a7c0f
ES
1141 'access CiviCRM',
1142 'access CiviContribute',
1143 'delete in CiviContribute',
be2fb01f
CW
1144 ],
1145 'completetransaction' => [
bf9a7c0f 1146 'edit contributions',
be2fb01f
CW
1147 ],
1148 'default' => [
bf9a7c0f
ES
1149 'access CiviCRM',
1150 'access CiviContribute',
1151 'edit contributions',
be2fb01f
CW
1152 ],
1153 ];
bf9a7c0f
ES
1154 $permissions['line_item'] = $permissions['contribution'];
1155
1156 // Payment permissions
be2fb01f
CW
1157 $permissions['payment'] = [
1158 'get' => [
bf9a7c0f
ES
1159 'access CiviCRM',
1160 'access CiviContribute',
be2fb01f
CW
1161 ],
1162 'delete' => [
bf9a7c0f
ES
1163 'access CiviCRM',
1164 'access CiviContribute',
1165 'delete in CiviContribute',
be2fb01f
CW
1166 ],
1167 'cancel' => [
bf9a7c0f
ES
1168 'access CiviCRM',
1169 'access CiviContribute',
1170 'edit contributions',
be2fb01f
CW
1171 ],
1172 'create' => [
bf9a7c0f
ES
1173 'access CiviCRM',
1174 'access CiviContribute',
1175 'edit contributions',
be2fb01f
CW
1176 ],
1177 'default' => [
bf9a7c0f
ES
1178 'access CiviCRM',
1179 'access CiviContribute',
1180 'edit contributions',
be2fb01f
CW
1181 ],
1182 ];
e4124a88 1183 $permissions['contribution_recur'] = $permissions['payment'];
bf9a7c0f
ES
1184
1185 // Custom field permissions
be2fb01f
CW
1186 $permissions['custom_field'] = [
1187 'default' => [
bf9a7c0f
ES
1188 'administer CiviCRM',
1189 'access all custom data',
be2fb01f
CW
1190 ],
1191 ];
bf9a7c0f
ES
1192 $permissions['custom_group'] = $permissions['custom_field'];
1193
1194 // Event permissions
be2fb01f
CW
1195 $permissions['event'] = [
1196 'create' => [
bf9a7c0f
ES
1197 'access CiviCRM',
1198 'access CiviEvent',
1199 'edit all events',
be2fb01f
CW
1200 ],
1201 'delete' => [
bf9a7c0f
ES
1202 'access CiviCRM',
1203 'access CiviEvent',
1204 'delete in CiviEvent',
be2fb01f
CW
1205 ],
1206 'get' => [
bf9a7c0f
ES
1207 'access CiviCRM',
1208 'access CiviEvent',
1209 'view event info',
be2fb01f
CW
1210 ],
1211 'update' => [
bf9a7c0f
ES
1212 'access CiviCRM',
1213 'access CiviEvent',
1214 'edit all events',
be2fb01f
CW
1215 ],
1216 ];
170af518 1217 // Exception refers to dedupe_exception.
1218 $permissions['exception'] = [
1219 'default' => ['merge duplicate contacts'],
1220 ];
5654496c 1221
418ffc5b 1222 $permissions['job'] = [
1223 'process_batch_merge' => ['merge duplicate contacts'],
1224 ];
5654496c 1225 $permissions['rule_group']['get'] = [['merge duplicate contacts', 'administer CiviCRM']];
bf9a7c0f
ES
1226 // Loc block is only used for events
1227 $permissions['loc_block'] = $permissions['event'];
1228
be2fb01f
CW
1229 $permissions['state_province'] = [
1230 'get' => [
fc2d1728 1231 'access CiviCRM',
be2fb01f
CW
1232 ],
1233 ];
fc2d1728 1234
bf9a7c0f 1235 // Price sets are shared by several components, user needs access to at least one of them
be2fb01f
CW
1236 $permissions['price_set'] = [
1237 'default' => [
1238 ['access CiviEvent', 'access CiviContribute', 'access CiviMember'],
1239 ],
1240 'get' => [
1241 ['access CiviCRM', 'view event info', 'make online contributions'],
1242 ],
1243 ];
bf9a7c0f
ES
1244
1245 // File permissions
be2fb01f
CW
1246 $permissions['file'] = [
1247 'default' => [
bf9a7c0f
ES
1248 'access CiviCRM',
1249 'access uploaded files',
be2fb01f
CW
1250 ],
1251 ];
bf9a7c0f
ES
1252 $permissions['files_by_entity'] = $permissions['file'];
1253
1254 // Group permissions
be2fb01f
CW
1255 $permissions['group'] = [
1256 'get' => [
bf9a7c0f 1257 'access CiviCRM',
be2fb01f
CW
1258 ],
1259 'default' => [
bf9a7c0f
ES
1260 'access CiviCRM',
1261 'edit groups',
be2fb01f
CW
1262 ],
1263 ];
bf9a7c0f
ES
1264
1265 $permissions['group_nesting'] = $permissions['group'];
1266 $permissions['group_organization'] = $permissions['group'];
1267
1268 //Group Contact permission
be2fb01f
CW
1269 $permissions['group_contact'] = [
1270 'get' => [
bf9a7c0f 1271 'access CiviCRM',
be2fb01f
CW
1272 ],
1273 'default' => [
bf9a7c0f
ES
1274 'access CiviCRM',
1275 'edit all contacts',
be2fb01f
CW
1276 ],
1277 ];
bf9a7c0f
ES
1278
1279 // CiviMail Permissions
be2fb01f 1280 $civiMailBasePerms = [
bf9a7c0f
ES
1281 // To get/preview/update, one must have least one of these perms:
1282 // Mailing API implementations enforce nuances of create/approve/schedule permissions.
1283 'access CiviMail',
1284 'create mailings',
1285 'schedule mailings',
1286 'approve mailings',
be2fb01f
CW
1287 ];
1288 $permissions['mailing'] = [
1289 'get' => [
bf9a7c0f
ES
1290 'access CiviCRM',
1291 $civiMailBasePerms,
be2fb01f
CW
1292 ],
1293 'delete' => [
bf9a7c0f
ES
1294 'access CiviCRM',
1295 $civiMailBasePerms,
1296 'delete in CiviMail',
be2fb01f
CW
1297 ],
1298 'submit' => [
bf9a7c0f 1299 'access CiviCRM',
be2fb01f
CW
1300 ['access CiviMail', 'schedule mailings'],
1301 ],
1302 'default' => [
bf9a7c0f
ES
1303 'access CiviCRM',
1304 $civiMailBasePerms,
be2fb01f
CW
1305 ],
1306 ];
bf9a7c0f
ES
1307 $permissions['mailing_group'] = $permissions['mailing'];
1308 $permissions['mailing_job'] = $permissions['mailing'];
1309 $permissions['mailing_recipients'] = $permissions['mailing'];
1310
be2fb01f
CW
1311 $permissions['mailing_a_b'] = [
1312 'get' => [
bf9a7c0f
ES
1313 'access CiviCRM',
1314 'access CiviMail',
be2fb01f
CW
1315 ],
1316 'delete' => [
bf9a7c0f
ES
1317 'access CiviCRM',
1318 'access CiviMail',
1319 'delete in CiviMail',
be2fb01f
CW
1320 ],
1321 'submit' => [
bf9a7c0f 1322 'access CiviCRM',
be2fb01f
CW
1323 ['access CiviMail', 'schedule mailings'],
1324 ],
1325 'default' => [
bf9a7c0f
ES
1326 'access CiviCRM',
1327 'access CiviMail',
be2fb01f
CW
1328 ],
1329 ];
bf9a7c0f
ES
1330
1331 // Membership permissions
be2fb01f
CW
1332 $permissions['membership'] = [
1333 'get' => [
bf9a7c0f
ES
1334 'access CiviCRM',
1335 'access CiviMember',
be2fb01f
CW
1336 ],
1337 'delete' => [
bf9a7c0f
ES
1338 'access CiviCRM',
1339 'access CiviMember',
1340 'delete in CiviMember',
be2fb01f
CW
1341 ],
1342 'default' => [
bf9a7c0f
ES
1343 'access CiviCRM',
1344 'access CiviMember',
1345 'edit memberships',
be2fb01f
CW
1346 ],
1347 ];
bf9a7c0f
ES
1348 $permissions['membership_status'] = $permissions['membership'];
1349 $permissions['membership_type'] = $permissions['membership'];
be2fb01f
CW
1350 $permissions['membership_payment'] = [
1351 'create' => [
bf9a7c0f
ES
1352 'access CiviCRM',
1353 'access CiviMember',
1354 'edit memberships',
1355 'access CiviContribute',
1356 'edit contributions',
be2fb01f
CW
1357 ],
1358 'delete' => [
bf9a7c0f
ES
1359 'access CiviCRM',
1360 'access CiviMember',
1361 'delete in CiviMember',
1362 'access CiviContribute',
1363 'delete in CiviContribute',
be2fb01f
CW
1364 ],
1365 'get' => [
bf9a7c0f
ES
1366 'access CiviCRM',
1367 'access CiviMember',
1368 'access CiviContribute',
be2fb01f
CW
1369 ],
1370 'update' => [
bf9a7c0f
ES
1371 'access CiviCRM',
1372 'access CiviMember',
1373 'edit memberships',
1374 'access CiviContribute',
1375 'edit contributions',
be2fb01f
CW
1376 ],
1377 ];
bf9a7c0f
ES
1378
1379 // Participant permissions
be2fb01f
CW
1380 $permissions['participant'] = [
1381 'create' => [
bf9a7c0f
ES
1382 'access CiviCRM',
1383 'access CiviEvent',
1384 'register for events',
be2fb01f
CW
1385 ],
1386 'delete' => [
bf9a7c0f
ES
1387 'access CiviCRM',
1388 'access CiviEvent',
1389 'edit event participants',
be2fb01f
CW
1390 ],
1391 'get' => [
bf9a7c0f
ES
1392 'access CiviCRM',
1393 'access CiviEvent',
1394 'view event participants',
be2fb01f
CW
1395 ],
1396 'update' => [
bf9a7c0f
ES
1397 'access CiviCRM',
1398 'access CiviEvent',
1399 'edit event participants',
be2fb01f
CW
1400 ],
1401 ];
1402 $permissions['participant_payment'] = [
1403 'create' => [
bf9a7c0f
ES
1404 'access CiviCRM',
1405 'access CiviEvent',
1406 'register for events',
1407 'access CiviContribute',
1408 'edit contributions',
be2fb01f
CW
1409 ],
1410 'delete' => [
bf9a7c0f
ES
1411 'access CiviCRM',
1412 'access CiviEvent',
1413 'edit event participants',
1414 'access CiviContribute',
1415 'delete in CiviContribute',
be2fb01f
CW
1416 ],
1417 'get' => [
bf9a7c0f
ES
1418 'access CiviCRM',
1419 'access CiviEvent',
1420 'view event participants',
1421 'access CiviContribute',
be2fb01f
CW
1422 ],
1423 'update' => [
bf9a7c0f
ES
1424 'access CiviCRM',
1425 'access CiviEvent',
1426 'edit event participants',
1427 'access CiviContribute',
1428 'edit contributions',
be2fb01f
CW
1429 ],
1430 ];
bf9a7c0f
ES
1431
1432 // Pledge permissions
be2fb01f
CW
1433 $permissions['pledge'] = [
1434 'create' => [
bf9a7c0f
ES
1435 'access CiviCRM',
1436 'access CiviPledge',
1437 'edit pledges',
be2fb01f
CW
1438 ],
1439 'delete' => [
bf9a7c0f
ES
1440 'access CiviCRM',
1441 'access CiviPledge',
1442 'delete in CiviPledge',
be2fb01f
CW
1443 ],
1444 'get' => [
bf9a7c0f
ES
1445 'access CiviCRM',
1446 'access CiviPledge',
be2fb01f
CW
1447 ],
1448 'update' => [
bf9a7c0f
ES
1449 'access CiviCRM',
1450 'access CiviPledge',
1451 'edit pledges',
be2fb01f
CW
1452 ],
1453 ];
bf9a7c0f
ES
1454
1455 //CRM-16777: Disable schedule reminder for user that have 'edit all events' and 'administer CiviCRM' permission.
be2fb01f
CW
1456 $permissions['action_schedule'] = [
1457 'update' => [
1458 [
bf9a7c0f
ES
1459 'access CiviCRM',
1460 'edit all events',
be2fb01f
CW
1461 ],
1462 ],
1463 ];
bf9a7c0f 1464
be2fb01f
CW
1465 $permissions['pledge_payment'] = [
1466 'create' => [
bf9a7c0f
ES
1467 'access CiviCRM',
1468 'access CiviPledge',
1469 'edit pledges',
1470 'access CiviContribute',
1471 'edit contributions',
be2fb01f
CW
1472 ],
1473 'delete' => [
bf9a7c0f
ES
1474 'access CiviCRM',
1475 'access CiviPledge',
1476 'delete in CiviPledge',
1477 'access CiviContribute',
1478 'delete in CiviContribute',
be2fb01f
CW
1479 ],
1480 'get' => [
bf9a7c0f
ES
1481 'access CiviCRM',
1482 'access CiviPledge',
1483 'access CiviContribute',
be2fb01f
CW
1484 ],
1485 'update' => [
bf9a7c0f
ES
1486 'access CiviCRM',
1487 'access CiviPledge',
1488 'edit pledges',
1489 'access CiviContribute',
1490 'edit contributions',
be2fb01f
CW
1491 ],
1492 ];
bf9a7c0f 1493
dfcf5ba2
CW
1494 // Dashboard permissions
1495 $permissions['dashboard'] = [
1496 'get' => [
1497 'access CiviCRM',
1498 ],
1499 ];
1500 $permissions['dashboard_contact'] = [
1501 'default' => [
1502 'access CiviCRM',
1503 ],
1504 ];
1505
bf9a7c0f 1506 // Profile permissions
be2fb01f 1507 $permissions['profile'] = [
518fa0ee
SL
1508 // the profile will take care of this
1509 'get' => [],
be2fb01f 1510 ];
bf9a7c0f 1511
be2fb01f
CW
1512 $permissions['uf_group'] = [
1513 'create' => [
bf9a7c0f 1514 'access CiviCRM',
be2fb01f 1515 [
bf9a7c0f
ES
1516 'administer CiviCRM',
1517 'manage event profiles',
be2fb01f
CW
1518 ],
1519 ],
1520 'get' => [
bf9a7c0f 1521 'access CiviCRM',
be2fb01f
CW
1522 ],
1523 'update' => [
bf9a7c0f 1524 'access CiviCRM',
be2fb01f 1525 [
bf9a7c0f
ES
1526 'administer CiviCRM',
1527 'manage event profiles',
be2fb01f
CW
1528 ],
1529 ],
1530 ];
bf9a7c0f 1531 $permissions['uf_field'] = $permissions['uf_join'] = $permissions['uf_group'];
be2fb01f 1532 $permissions['uf_field']['delete'] = [
bf9a7c0f 1533 'access CiviCRM',
be2fb01f 1534 [
bf9a7c0f
ES
1535 'administer CiviCRM',
1536 'manage event profiles',
be2fb01f
CW
1537 ],
1538 ];
bf9a7c0f
ES
1539 $permissions['option_value'] = $permissions['uf_group'];
1540 $permissions['option_group'] = $permissions['option_value'];
1541
be2fb01f
CW
1542 $permissions['custom_value'] = [
1543 'gettree' => ['access CiviCRM'],
1544 ];
f26fa703 1545
be2fb01f
CW
1546 $permissions['message_template'] = [
1547 'get' => ['access CiviCRM'],
1548 'create' => [['edit message templates', 'edit user-driven message templates', 'edit system workflow message templates']],
1549 'update' => [['edit message templates', 'edit user-driven message templates', 'edit system workflow message templates']],
1550 ];
4341efe4
JV
1551
1552 $permissions['report_template']['update'] = 'save Report Criteria';
1553 $permissions['report_template']['create'] = 'save Report Criteria';
bf9a7c0f
ES
1554 return $permissions;
1555 }
1556
1557 /**
1558 * Translate an unknown action to a canonical form.
1559 *
1560 * @param string $action
1561 *
1562 * @return string
1563 * the standardised action name
1564 */
1565 public static function getGenericAction($action) {
1566 $snippet = substr($action, 0, 3);
1567 if ($action == 'replace' || $snippet == 'del') {
1568 // 'Replace' is a combination of get+create+update+delete; however, the permissions
1569 // on each of those will be tested separately at runtime. This is just a sniff-test
1570 // based on the heuristic that 'delete' tends to be the most closely guarded
1571 // of the necessary permissions.
1572 $action = 'delete';
1573 }
1574 elseif ($action == 'setvalue' || $snippet == 'upd') {
1575 $action = 'update';
1576 }
1577 elseif ($action == 'getfields' || $action == 'getfield' || $action == 'getspec' || $action == 'getoptions') {
1578 $action = 'meta';
1579 }
1580 elseif ($snippet == 'get') {
1581 $action = 'get';
1582 }
1583 return $action;
1584 }
1585
6a488035 1586 /**
d09edf64 1587 * Validate user permission across.
6a488035
TO
1588 * edit or view or with supportable acls.
1589 *
acb1052e
WA
1590 * @return bool
1591 */
00be9182 1592 public static function giveMeAllACLs() {
6a488035
TO
1593 if (CRM_Core_Permission::check('view all contacts') ||
1594 CRM_Core_Permission::check('edit all contacts')
1595 ) {
1596 return TRUE;
1597 }
1598
1599 $session = CRM_Core_Session::singleton();
1600 $contactID = $session->get('userID');
1601
6a488035
TO
1602 //check for acl.
1603 $aclPermission = self::getPermission();
be2fb01f 1604 if (in_array($aclPermission, [
6a488035 1605 CRM_Core_Permission::EDIT,
41f314b6 1606 CRM_Core_Permission::VIEW,
be2fb01f 1607 ])
41f314b6 1608 ) {
6a488035
TO
1609 return TRUE;
1610 }
1611
1612 // run acl where hook and see if the user is supplying an ACL clause
1613 // that is not false
be2fb01f 1614 $tables = $whereTables = [];
6a488035
TO
1615 $where = NULL;
1616
1617 CRM_Utils_Hook::aclWhereClause(CRM_Core_Permission::VIEW,
1618 $tables, $whereTables,
1619 $contactID, $where
1620 );
1621 return empty($whereTables) ? FALSE : TRUE;
1622 }
1623
1624 /**
100fef9d 1625 * Get component name from given permission.
6a488035 1626 *
41f314b6 1627 * @param string $permission
6a488035 1628 *
76e7a76c
CW
1629 * @return null|string
1630 * the name of component.
6a488035 1631 */
00be9182 1632 public static function getComponentName($permission) {
6a488035
TO
1633 $componentName = NULL;
1634 $permission = trim($permission);
1635 if (empty($permission)) {
1636 return $componentName;
1637 }
1638
be2fb01f 1639 static $allCompPermissions = [];
6a488035
TO
1640 if (empty($allCompPermissions)) {
1641 $components = CRM_Core_Component::getComponents();
1642 foreach ($components as $name => $comp) {
33777e4a
PJ
1643 //get all permissions of each components unconditionally
1644 $allCompPermissions[$name] = $comp->getPermissions(TRUE);
6a488035
TO
1645 }
1646 }
1647
1648 if (is_array($allCompPermissions)) {
1649 foreach ($allCompPermissions as $name => $permissions) {
b9021475 1650 if (array_key_exists($permission, $permissions)) {
6a488035
TO
1651 $componentName = $name;
1652 break;
1653 }
1654 }
1655 }
1656
1657 return $componentName;
1658 }
1659
1660 /**
d09edf64 1661 * Get all the contact emails for users that have a specific permission.
6a488035 1662 *
6a0b768e
TO
1663 * @param string $permissionName
1664 * Name of the permission we are interested in.
6a488035 1665 *
a6c01b45
CW
1666 * @return string
1667 * a comma separated list of email addresses
6a488035
TO
1668 */
1669 public static function permissionEmails($permissionName) {
1670 $config = CRM_Core_Config::singleton();
41f314b6 1671 return $config->userPermissionClass->permissionEmails($permissionName);
6a488035
TO
1672 }
1673
1674 /**
d09edf64 1675 * Get all the contact emails for users that have a specific role.
6a488035 1676 *
6a0b768e
TO
1677 * @param string $roleName
1678 * Name of the role we are interested in.
6a488035 1679 *
a6c01b45
CW
1680 * @return string
1681 * a comma separated list of email addresses
6a488035
TO
1682 */
1683 public static function roleEmails($roleName) {
1684 $config = CRM_Core_Config::singleton();
41f314b6 1685 return $config->userRoleClass->roleEmails($roleName);
6a488035
TO
1686 }
1687
a0ee3941
EM
1688 /**
1689 * @return bool
1690 */
00be9182 1691 public static function isMultisiteEnabled() {
63d76404 1692 return (bool) Civi::settings()->get('is_enabled');
6a488035 1693 }
96025800 1694
dc6b437a
GC
1695 /**
1696 * Verify if the user has permission to get the invoice.
1697 *
1698 * @return bool
1699 * TRUE if the user has download all invoices permission or download my
1700 * invoices permission and the invoice author is the current user.
1701 */
1702 public static function checkDownloadInvoice() {
4cfd4f45 1703 $cid = CRM_Core_Session::getLoggedInContactID();
dc6b437a
GC
1704 if (CRM_Core_Permission::check('access CiviContribute') ||
1705 (CRM_Core_Permission::check('view my invoices') && $_GET['cid'] == $cid)
1706 ) {
1707 return TRUE;
1708 }
1709 return FALSE;
1710 }
1711
6a488035 1712}