3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2018
37 * This is the basic permission class wrapper
39 class CRM_Core_Permission
{
42 * Static strings used to compose permissions.
47 const EDIT_GROUPS
= 'edit contacts in ', VIEW_GROUPS
= 'view contacts in ';
50 * The various type of permissions.
54 const EDIT
= 1, VIEW
= 2, DELETE
= 3, CREATE
= 4, SEARCH
= 5, ALL
= 6, ADMIN
= 7;
57 * A placeholder permission which always fails.
59 const ALWAYS_DENY_PERMISSION
= "*always deny*";
62 * A placeholder permission which always fails.
64 const ALWAYS_ALLOW_PERMISSION
= "*always allow*";
67 * Various authentication sources.
71 const AUTH_SRC_UNKNOWN
= 0, AUTH_SRC_CHECKSUM
= 1, AUTH_SRC_SITEKEY
= 2, AUTH_SRC_LOGIN
= 4;
74 * Get the current permission of this user.
77 * the permission of the user (edit or view or null)
79 public static function getPermission() {
80 $config = CRM_Core_Config
::singleton();
81 return $config->userPermissionClass
->getPermission();
85 * Given a permission string or array, check for access requirements
86 * @param string|array $permissions
87 * The permission to check as an array or string -see examples.
89 * @param int $contactId
90 * Contact id to check permissions for. Defaults to current logged-in user.
94 * Must have 'access CiviCRM'
95 * (string) 'access CiviCRM'
98 * Ex 2 Must have 'access CiviCRM' and 'access Ajax API'
99 * array('access CiviCRM', 'access Ajax API')
101 * Ex 3 Must have 'access CiviCRM' or 'access Ajax API'
103 * array('access CiviCRM', 'access Ajax API'),
106 * Ex 4 Must have 'access CiviCRM' or 'access Ajax API' AND 'access CiviEvent'
108 * array('access CiviCRM', 'access Ajax API'),
109 * 'access CiviEvent',
112 * Note that in permissions.php this is keyed by the action eg.
113 * (access Civi || access AJAX) && (access CiviEvent || access CiviContribute)
114 * 'myaction' => array(
115 * array('access CiviCRM', 'access Ajax API'),
116 * array('access CiviEvent', 'access CiviContribute')
120 * true if yes, else false
122 public static function check($permissions, $contactId = NULL) {
123 $permissions = (array) $permissions;
126 $userId = CRM_Core_BAO_UFMatch
::getUFId($contactId);
129 /** @var CRM_Core_Permission_Temp $tempPerm */
130 $tempPerm = CRM_Core_Config
::singleton()->userPermissionTemp
;
132 foreach ($permissions as $permission) {
133 if (is_array($permission)) {
134 foreach ($permission as $orPerm) {
135 if (self
::check($orPerm, $contactId)) {
136 //one of our 'or' permissions has succeeded - stop checking this permission
140 //none of our our conditions was met
144 // This is an individual permission
145 $granted = CRM_Core_Config
::singleton()->userPermissionClass
->check($permission, $userId);
146 // Call the permission_check hook to permit dynamic escalation (CRM-19256)
147 CRM_Utils_Hook
::permission_check($permission, $granted, $contactId);
150 && !($tempPerm && $tempPerm->check($permission))
152 //one of our 'and' conditions has not been met
161 * Determine if any one of the permissions strings applies to current user.
163 * @param array $perms
166 public static function checkAnyPerm($perms) {
167 foreach ($perms as $perm) {
168 if (CRM_Core_Permission
::check($perm)) {
176 * Given a group/role array, check for access requirements
178 * @param array $array
179 * The group/role to check.
182 * true if yes, else false
184 public static function checkGroupRole($array) {
185 $config = CRM_Core_Config
::singleton();
186 return $config->userPermissionClass
->checkGroupRole($array);
190 * Get the permissioned where clause for the user.
193 * The type of permission needed.
194 * @param array $tables
195 * (reference ) add the tables that are needed for the select clause.
196 * @param array $whereTables
197 * (reference ) add the tables that are needed for the where clause.
200 * the group where clause for this user
202 public static function getPermissionedStaticGroupClause($type, &$tables, &$whereTables) {
203 $config = CRM_Core_Config
::singleton();
204 return $config->userPermissionClass
->getPermissionedStaticGroupClause($type, $tables, $whereTables);
208 * Get all groups from database, filtered by permissions
211 * @param string $groupType
212 * Type of group(Access/Mailing).
213 * @param bool $excludeHidden
214 * exclude hidden groups.
218 * array reference of all groups.
220 public static function group($groupType, $excludeHidden = TRUE) {
221 $config = CRM_Core_Config
::singleton();
222 return $config->userPermissionClass
->group($groupType, $excludeHidden);
228 public static function customGroupAdmin() {
231 // check if user has all powerful permission
232 // or administer civicrm permission (CRM-1905)
233 if (self
::check('access all custom data')) {
238 self
::check('administer Multiple Organizations') &&
239 self
::isMultisiteEnabled()
244 if (self
::check('administer CiviCRM')) {
257 public static function customGroup($type = CRM_Core_Permission
::VIEW
, $reset = FALSE) {
258 $customGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_CustomField', 'custom_group_id',
259 array('fresh' => $reset));
260 $defaultGroups = array();
262 // check if user has all powerful permission
263 // or administer civicrm permission (CRM-1905)
264 if (self
::customGroupAdmin()) {
265 $defaultGroups = array_keys($customGroups);
268 return CRM_ACL_API
::group($type, NULL, 'civicrm_custom_group', $customGroups, $defaultGroups);
273 * @param null $prefix
278 public static function customGroupClause($type = CRM_Core_Permission
::VIEW
, $prefix = NULL, $reset = FALSE) {
279 if (self
::customGroupAdmin()) {
283 $groups = self
::customGroup($type, $reset);
284 if (empty($groups)) {
288 return "{$prefix}id IN ( " . implode(',', $groups) . ' ) ';
298 public static function ufGroupValid($gid, $type = CRM_Core_Permission
::VIEW
) {
303 $groups = self
::ufGroup($type);
304 return !empty($groups) && in_array($gid, $groups) ?
TRUE : FALSE;
312 public static function ufGroup($type = CRM_Core_Permission
::VIEW
) {
313 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
315 $allGroups = array_keys($ufGroups);
317 // check if user has all powerful permission
318 if (self
::check('profile listings and forms')) {
323 case CRM_Core_Permission
::VIEW
:
324 if (self
::check('profile view')) {
329 case CRM_Core_Permission
::CREATE
:
330 if (self
::check('profile create')) {
335 case CRM_Core_Permission
::EDIT
:
336 if (self
::check('profile edit')) {
341 case CRM_Core_Permission
::SEARCH
:
342 if (self
::check('profile listings')) {
348 return CRM_ACL_API
::group($type, NULL, 'civicrm_uf_group', $ufGroups);
353 * @param null $prefix
354 * @param bool $returnUFGroupIds
356 * @return array|string
358 public static function ufGroupClause($type = CRM_Core_Permission
::VIEW
, $prefix = NULL, $returnUFGroupIds = FALSE) {
359 $groups = self
::ufGroup($type);
360 if ($returnUFGroupIds) {
363 elseif (empty($groups)) {
367 return "{$prefix}id IN ( " . implode(',', $groups) . ' ) ';
373 * @param int $eventID
374 * @param string $context
378 public static function event($type = CRM_Core_Permission
::VIEW
, $eventID = NULL, $context = '') {
379 if (!empty($context)) {
380 if (CRM_Core_Permission
::check($context)) {
384 $events = CRM_Event_PseudoConstant
::event(NULL, TRUE);
385 $includeEvents = array();
387 // check if user has all powerful permission
388 if (self
::check('register for events')) {
389 $includeEvents = array_keys($events);
392 if ($type == CRM_Core_Permission
::VIEW
&&
393 self
::check('view event info')
395 $includeEvents = array_keys($events);
398 $permissionedEvents = CRM_ACL_API
::group($type, NULL, 'civicrm_event', $events, $includeEvents);
400 return $permissionedEvents;
402 if (!empty($permissionedEvents)) {
403 return array_search($eventID, $permissionedEvents) === FALSE ?
NULL : $eventID;
410 * @param null $prefix
414 public static function eventClause($type = CRM_Core_Permission
::VIEW
, $prefix = NULL) {
415 $events = self
::event($type);
416 if (empty($events)) {
420 return "{$prefix}id IN ( " . implode(',', $events) . ' ) ';
425 * Checks that component is enabled and optionally that user has basic perm.
427 * @param string $module
428 * Specifies the name of the CiviCRM component.
429 * @param bool $checkPermission
430 * Check not only that module is enabled, but that user has necessary
432 * @param bool $requireAllCasesPermOnCiviCase
433 * Significant only if $module == CiviCase
434 * Require "access all cases and activities", not just
435 * "access my cases and activities".
438 * Access to specified $module is granted.
440 public static function access($module, $checkPermission = TRUE, $requireAllCasesPermOnCiviCase = FALSE) {
441 $config = CRM_Core_Config
::singleton();
443 if (!in_array($module, $config->enableComponents
)) {
447 if ($checkPermission) {
450 $access_all_cases = CRM_Core_Permission
::check("access all cases and activities");
451 $access_my_cases = CRM_Core_Permission
::check("access my cases and activities");
452 return $access_all_cases ||
(!$requireAllCasesPermOnCiviCase && $access_my_cases);
455 return CRM_Core_Permission
::check("administer $module");
458 return CRM_Core_Permission
::check("access $module");
466 * Check permissions for delete and edit actions.
468 * @param string $module
471 * Action to be check across component.
476 public static function checkActionPermission($module, $action) {
477 //check delete related permissions.
478 if ($action & CRM_Core_Action
::DELETE
) {
479 $permissionName = "delete in $module";
482 $editPermissions = array(
483 'CiviEvent' => 'edit event participants',
484 'CiviMember' => 'edit memberships',
485 'CiviPledge' => 'edit pledges',
486 'CiviContribute' => 'edit contributions',
487 'CiviGrant' => 'edit grants',
488 'CiviMail' => 'access CiviMail',
489 'CiviAuction' => 'add auction items',
491 $permissionName = CRM_Utils_Array
::value($module, $editPermissions);
494 if ($module == 'CiviCase' && !$permissionName) {
495 return CRM_Case_BAO_Case
::accessCiviCase();
498 //check for permission.
499 return CRM_Core_Permission
::check($permissionName);
509 public static function checkMenu(&$args, $op = 'and') {
510 if (!is_array($args)) {
513 foreach ($args as $str) {
514 $res = CRM_Core_Permission
::check($str);
515 if ($op == 'or' && $res) {
518 elseif ($op == 'and' && !$res) {
522 return ($op == 'or') ?
FALSE : TRUE;
531 public static function checkMenuItem(&$item) {
532 if (!array_key_exists('access_callback', $item)) {
533 CRM_Core_Error
::backtrace();
534 CRM_Core_Error
::fatal();
537 // if component_id is present, ensure it is enabled
538 if (isset($item['component_id']) && $item['component_id']) {
539 if (!isset(Civi
::$statics[__CLASS__
]['componentNameId'])) {
540 Civi
::$statics[__CLASS__
]['componentNameId'] = array_flip(CRM_Core_Component
::getComponentIDs());
542 $componentName = Civi
::$statics[__CLASS__
]['componentNameId'][$item['component_id']];
544 $config = CRM_Core_Config
::singleton();
545 if (is_array($config->enableComponents
) && in_array($componentName, $config->enableComponents
)) {
546 // continue with process
553 // the following is imitating drupal 6 code in includes/menu.inc
554 if (empty($item['access_callback']) ||
555 is_numeric($item['access_callback'])
557 return (boolean
) $item['access_callback'];
560 // check whether the following Ajax requests submitted the right key
561 // FIXME: this should be integrated into ACLs proper
562 if (CRM_Utils_Array
::value('page_type', $item) == 3) {
563 if (!CRM_Core_Key
::validate($_REQUEST['key'], $item['path'])) {
568 // check if callback is for checkMenu, if so optimize it
569 if (is_array($item['access_callback']) &&
570 $item['access_callback'][0] == 'CRM_Core_Permission' &&
571 $item['access_callback'][1] == 'checkMenu'
573 $op = CRM_Utils_Array
::value(1, $item['access_arguments'], 'and');
574 return self
::checkMenu($item['access_arguments'][0], $op);
577 return call_user_func_array($item['access_callback'], $item['access_arguments']);
583 * Include disabled components
584 * @param bool $descriptions
585 * Whether to return descriptions
589 public static function basicPermissions($all = FALSE, $descriptions = FALSE) {
590 $cacheKey = implode('-', array($all, $descriptions));
591 if (empty(Civi
::$statics[__CLASS__
][__FUNCTION__
][$cacheKey])) {
592 Civi
::$statics[__CLASS__
][__FUNCTION__
][$cacheKey] = self
::assembleBasicPermissions($all, $descriptions);
594 return Civi
::$statics[__CLASS__
][__FUNCTION__
][$cacheKey];
599 * @param bool $descriptions
600 * whether to return descriptions
604 public static function assembleBasicPermissions($all = FALSE, $descriptions = FALSE) {
605 $config = CRM_Core_Config
::singleton();
606 $prefix = ts('CiviCRM') . ': ';
607 $permissions = self
::getCorePermissions($descriptions);
609 if (self
::isMultisiteEnabled()) {
610 $permissions['administer Multiple Organizations'] = array($prefix . ts('administer Multiple Organizations'));
613 if (!$descriptions) {
614 foreach ($permissions as $name => $attr) {
615 $permissions[$name] = array_shift($attr);
619 $components = CRM_Core_Component
::getEnabledComponents();
622 $components = CRM_Core_Component
::getComponents();
625 foreach ($components as $comp) {
626 $perm = $comp->getPermissions(FALSE, $descriptions);
628 $info = $comp->getInfo();
629 foreach ($perm as $p => $attr) {
631 if (!is_array($attr)) {
632 $attr = array($attr);
635 $attr[0] = $info['translatedName'] . ': ' . $attr[0];
638 $permissions[$p] = $attr;
641 $permissions[$p] = $attr[0];
647 // Add any permissions defined in hook_civicrm_permission implementations.
648 $module_permissions = $config->userPermissionClass
->getAllModulePermissions($descriptions);
649 $permissions = array_merge($permissions, $module_permissions);
650 CRM_Financial_BAO_FinancialType
::permissionedFinancialTypes($permissions, $descriptions);
657 public static function getAnonymousPermissionsWarnings() {
658 static $permissions = array();
659 if (empty($permissions)) {
660 $permissions = array(
661 'administer CiviCRM',
663 $components = CRM_Core_Component
::getComponents();
664 foreach ($components as $comp) {
665 if (!method_exists($comp, 'getAnonymousPermissionWarnings')) {
668 $permissions = array_merge($permissions, $comp->getAnonymousPermissionWarnings());
675 * @param $anonymous_perms
679 public static function validateForPermissionWarnings($anonymous_perms) {
680 return array_intersect($anonymous_perms, self
::getAnonymousPermissionsWarnings());
684 * Get core permissions.
688 public static function getCorePermissions() {
689 $prefix = ts('CiviCRM') . ': ';
690 $permissions = array(
691 'add contacts' => array(
692 $prefix . ts('add contacts'),
693 ts('Create a new contact record in CiviCRM'),
695 'view all contacts' => array(
696 $prefix . ts('view all contacts'),
697 ts('View ANY CONTACT in the CiviCRM database, export contact info and perform activities such as Send Email, Phone Call, etc.'),
699 'edit all contacts' => array(
700 $prefix . ts('edit all contacts'),
701 ts('View, Edit and Delete ANY CONTACT in the CiviCRM database; Create and edit relationships, tags and other info about the contacts'),
703 'view my contact' => array(
704 $prefix . ts('view my contact'),
706 'edit my contact' => array(
707 $prefix . ts('edit my contact'),
709 'delete contacts' => array(
710 $prefix . ts('delete contacts'),
712 'access deleted contacts' => array(
713 $prefix . ts('access deleted contacts'),
714 ts('Access contacts in the trash'),
716 'import contacts' => array(
717 $prefix . ts('import contacts'),
718 ts('Import contacts and activities'),
720 'import SQL datasource' => array(
721 $prefix . ts('import SQL datasource'),
722 ts('When importing, consume data directly from a SQL datasource'),
724 'edit groups' => array(
725 $prefix . ts('edit groups'),
726 ts('Create new groups, edit group settings (e.g. group name, visibility...), delete groups'),
728 'administer CiviCRM' => array(
729 $prefix . ts('administer CiviCRM'),
730 ts('Perform all tasks in the Administer CiviCRM control panel and Import Contacts'),
732 'skip IDS check' => array(
733 $prefix . ts('skip IDS check'),
734 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.'),
736 'access uploaded files' => array(
737 $prefix . ts('access uploaded files'),
738 ts('View / download files including images and photos'),
740 'profile listings and forms' => array(
741 $prefix . ts('profile listings and forms'),
742 ts('Warning: Give to trusted roles only; this permission has privacy implications. Add/edit data in online forms and access public searchable directories.'),
744 'profile listings' => array(
745 $prefix . ts('profile listings'),
746 ts('Warning: Give to trusted roles only; this permission has privacy implications. Access public searchable directories.'),
748 'profile create' => array(
749 $prefix . ts('profile create'),
750 ts('Add data in a profile form.'),
752 'profile edit' => array(
753 $prefix . ts('profile edit'),
754 ts('Edit data in a profile form.'),
756 'profile view' => array(
757 $prefix . ts('profile view'),
758 ts('View data in a profile.'),
760 'access all custom data' => array(
761 $prefix . ts('access all custom data'),
762 ts('View all custom fields regardless of ACL rules'),
764 'view all activities' => array(
765 $prefix . ts('view all activities'),
766 ts('View all activities (for visible contacts)'),
768 'delete activities' => array(
769 $prefix . ts('Delete activities'),
771 'edit inbound email basic information' => array(
772 $prefix . ts('edit inbound email basic information'),
773 ts('Edit all inbound email activities (for visible contacts) basic information. Content editing not allowed.'),
775 'edit inbound email basic information and content' => array(
776 $prefix . ts('edit inbound email basic information and content'),
777 ts('Edit all inbound email activities (for visible contacts) basic information and content.'),
779 'access CiviCRM' => array(
780 $prefix . ts('access CiviCRM backend and API'),
781 ts('Master control for access to the main CiviCRM backend and API. Give to trusted roles only.'),
783 'access Contact Dashboard' => array(
784 $prefix . ts('access Contact Dashboard'),
785 ts('View Contact Dashboard (for themselves and visible contacts)'),
787 'translate CiviCRM' => array(
788 $prefix . ts('translate CiviCRM'),
789 ts('Allow User to enable multilingual'),
791 'manage tags' => array(
792 $prefix . ts('manage tags'),
793 ts('Create and rename tags'),
795 'administer reserved groups' => array(
796 $prefix . ts('administer reserved groups'),
797 ts('Edit and disable Reserved Groups (Needs Edit Groups)'),
799 'administer Tagsets' => array(
800 $prefix . ts('administer Tagsets'),
802 'administer reserved tags' => array(
803 $prefix . ts('administer reserved tags'),
805 'administer dedupe rules' => array(
806 $prefix . ts('administer dedupe rules'),
807 ts('Create and edit rules, change the supervised and unsupervised rules'),
809 'merge duplicate contacts' => array(
810 $prefix . ts('merge duplicate contacts'),
811 ts('Delete Contacts must also be granted in order for this to work.'),
813 'force merge duplicate contacts' => array(
814 $prefix . ts('force merge duplicate contacts'),
815 ts('Delete Contacts must also be granted in order for this to work.'),
817 'view debug output' => array(
818 $prefix . ts('view debug output'),
819 ts('View results of debug and backtrace'),
822 'view all notes' => array(
823 $prefix . ts('view all notes'),
824 ts("View notes (for visible contacts) even if they're marked admin only"),
826 'add contact notes' => array(
827 $prefix . ts('add contact notes'),
828 ts("Create notes for contacts"),
830 'access AJAX API' => array(
831 $prefix . ts('access AJAX API'),
832 ts('Allow API access even if Access CiviCRM is not granted'),
834 'access contact reference fields' => array(
835 $prefix . ts('access contact reference fields'),
836 ts('Allow entering data into contact reference fields'),
838 'create manual batch' => array(
839 $prefix . ts('create manual batch'),
840 ts('Create an accounting batch (with Access to CiviContribute and View Own/All Manual Batches)'),
842 'edit own manual batches' => array(
843 $prefix . ts('edit own manual batches'),
844 ts('Edit accounting batches created by user'),
846 'edit all manual batches' => array(
847 $prefix . ts('edit all manual batches'),
848 ts('Edit all accounting batches'),
850 'close own manual batches' => array(
851 $prefix . ts('close own manual batches'),
852 ts('Close accounting batches created by user (with Access to CiviContribute)'),
854 'close all manual batches' => array(
855 $prefix . ts('close all manual batches'),
856 ts('Close all accounting batches (with Access to CiviContribute)'),
858 'reopen own manual batches' => array(
859 $prefix . ts('reopen own manual batches'),
860 ts('Reopen accounting batches created by user (with Access to CiviContribute)'),
862 'reopen all manual batches' => array(
863 $prefix . ts('reopen all manual batches'),
864 ts('Reopen all accounting batches (with Access to CiviContribute)'),
866 'view own manual batches' => array(
867 $prefix . ts('view own manual batches'),
868 ts('View accounting batches created by user (with Access to CiviContribute)'),
870 'view all manual batches' => array(
871 $prefix . ts('view all manual batches'),
872 ts('View all accounting batches (with Access to CiviContribute)'),
874 'delete own manual batches' => array(
875 $prefix . ts('delete own manual batches'),
876 ts('Delete accounting batches created by user'),
878 'delete all manual batches' => array(
879 $prefix . ts('delete all manual batches'),
880 ts('Delete all accounting batches'),
882 'export own manual batches' => array(
883 $prefix . ts('export own manual batches'),
884 ts('Export accounting batches created by user'),
886 'export all manual batches' => array(
887 $prefix . ts('export all manual batches'),
888 ts('Export all accounting batches'),
890 'administer payment processors' => array(
891 $prefix . ts('administer payment processors'),
892 ts('Add, Update, or Disable Payment Processors'),
894 'edit message templates' => array(
895 $prefix . ts('edit message templates'),
897 'edit system workflow message templates' => array(
898 $prefix . ts('edit system workflow message templates'),
900 'edit user-driven message templates' => array(
901 $prefix . ts('edit user-driven message templates'),
903 'view my invoices' => array(
904 $prefix . ts('view my invoices'),
905 ts('Allow users to view/ download their own invoices'),
907 'edit api keys' => array(
908 $prefix . ts('edit api keys'),
911 'edit own api keys' => array(
912 $prefix . ts('edit own api keys'),
913 ts('Edit user\'s own API keys'),
916 $prefix . ts('send SMS'),
925 * For each entity provides an array of permissions required for each action
927 * The action is the array key, possible values:
928 * * create: applies to create (with no id in params)
929 * * update: applies to update, setvalue, create (with id in params)
930 * * get: applies to getcount, getsingle, getvalue and other gets
931 * * delete: applies to delete, replace
932 * * meta: applies to getfields, getoptions, getspec
933 * * default: catch-all for anything not declared
935 * Note: some APIs declare other actions as well
937 * Permissions should use arrays for AND and arrays of arrays for OR
938 * @see CRM_Core_Permission::check
940 * @return array of permissions
942 public static function getEntityActionPermissions() {
943 $permissions = array();
944 // These are the default permissions - if any entity does not declare permissions for a given action,
945 // (or the entity does not declare permissions at all) - then the action will be used from here
946 $permissions['default'] = array(
947 // applies to getfields, getoptions, etc.
948 'meta' => array('access CiviCRM'),
949 // catch-all, applies to create, get, delete, etc.
950 // If an entity declares it's own 'default' action it will override this one
951 'default' => array('administer CiviCRM'),
954 // Note: Additional permissions in DynamicFKAuthorization
955 $permissions['attachment'] = array(
957 array('access CiviCRM', 'access AJAX API'),
961 // Contact permissions
962 $permissions['contact'] = array(
971 // managed by query object
973 // managed by _civicrm_api3_check_edit_permissions
976 array('access CiviCRM', 'access AJAX API'),
980 // CRM-16963 - Permissions for country.
981 $permissions['country'] = array(
986 'administer CiviCRM',
990 // Contact-related data permissions.
991 $permissions['address'] = array(
992 // get is managed by BAO::addSelectWhereClause
993 // create/delete are managed by _civicrm_api3_check_edit_permissions
994 'default' => array(),
996 $permissions['email'] = $permissions['address'];
997 $permissions['phone'] = $permissions['address'];
998 $permissions['website'] = $permissions['address'];
999 $permissions['im'] = $permissions['address'];
1000 $permissions['open_i_d'] = $permissions['address'];
1002 // Also managed by ACLs - CRM-19448
1003 $permissions['entity_tag'] = array('default' => array());
1004 $permissions['note'] = $permissions['entity_tag'];
1006 // Allow non-admins to get and create tags to support tagset widget
1007 // Delete is still reserved for admins
1008 $permissions['tag'] = array(
1009 'get' => array('access CiviCRM'),
1010 'create' => array('access CiviCRM'),
1011 'update' => array('access CiviCRM'),
1014 //relationship permissions
1015 $permissions['relationship'] = array(
1016 // get is managed by BAO::addSelectWhereClause
1020 'edit all contacts',
1024 'edit all contacts',
1028 // CRM-17741 - Permissions for RelationshipType.
1029 $permissions['relationship_type'] = array(
1034 'administer CiviCRM',
1038 // Activity permissions
1039 $permissions['activity'] = array(
1042 'delete activities',
1046 // Note that view all activities is also required within the api
1047 // if the id is not passed in. Where the id is passed in the activity
1048 // specific check functions are used and tested.
1052 'view all activities',
1057 $permissions['case'] = array(
1064 'delete in CiviCase',
1067 'administer CiviCase',
1070 'administer CiviCase',
1073 // At minimum the user needs one of the following. Finer-grained access is controlled by CRM_Case_BAO_Case::addSelectWhereClause
1074 array('access my cases and activities', 'access all cases and activities'),
1077 $permissions['case_contact'] = $permissions['case'];
1079 $permissions['case_type'] = array(
1080 'default' => array('administer CiviCase'),
1082 // nested array = OR
1083 array('access my cases and activities', 'access all cases and activities'),
1087 // Campaign permissions
1088 $permissions['campaign'] = array(
1089 'get' => array('access CiviCRM'),
1091 // nested array = OR
1092 array('administer CiviCampaign', 'manage campaign'),
1095 $permissions['survey'] = $permissions['campaign'];
1097 // Financial permissions
1098 $permissions['contribution'] = array(
1101 'access CiviContribute',
1105 'access CiviContribute',
1106 'delete in CiviContribute',
1108 'completetransaction' => array(
1109 'edit contributions',
1113 'access CiviContribute',
1114 'edit contributions',
1117 $permissions['line_item'] = $permissions['contribution'];
1119 // Payment permissions
1120 $permissions['payment'] = array(
1123 'access CiviContribute',
1127 'access CiviContribute',
1128 'delete in CiviContribute',
1132 'access CiviContribute',
1133 'edit contributions',
1137 'access CiviContribute',
1138 'edit contributions',
1142 'access CiviContribute',
1143 'edit contributions',
1146 $permissions['contribution_recur'] = $permissions['payment'];
1148 // Custom field permissions
1149 $permissions['custom_field'] = array(
1151 'administer CiviCRM',
1152 'access all custom data',
1155 $permissions['custom_group'] = $permissions['custom_field'];
1157 // Event permissions
1158 $permissions['event'] = array(
1167 'delete in CiviEvent',
1180 // Loc block is only used for events
1181 $permissions['loc_block'] = $permissions['event'];
1183 $permissions['state_province'] = array(
1189 // Price sets are shared by several components, user needs access to at least one of them
1190 $permissions['price_set'] = array(
1192 array('access CiviEvent', 'access CiviContribute', 'access CiviMember'),
1195 array('access CiviCRM', 'view event info', 'make online contributions'),
1200 $permissions['file'] = array(
1203 'access uploaded files',
1206 $permissions['files_by_entity'] = $permissions['file'];
1208 // Group permissions
1209 $permissions['group'] = array(
1219 $permissions['group_nesting'] = $permissions['group'];
1220 $permissions['group_organization'] = $permissions['group'];
1222 //Group Contact permission
1223 $permissions['group_contact'] = array(
1229 'edit all contacts',
1233 // CiviMail Permissions
1234 $civiMailBasePerms = array(
1235 // To get/preview/update, one must have least one of these perms:
1236 // Mailing API implementations enforce nuances of create/approve/schedule permissions.
1239 'schedule mailings',
1242 $permissions['mailing'] = array(
1250 'delete in CiviMail',
1254 array('access CiviMail', 'schedule mailings'),
1261 $permissions['mailing_group'] = $permissions['mailing'];
1262 $permissions['mailing_job'] = $permissions['mailing'];
1263 $permissions['mailing_recipients'] = $permissions['mailing'];
1265 $permissions['mailing_a_b'] = array(
1273 'delete in CiviMail',
1277 array('access CiviMail', 'schedule mailings'),
1285 // Membership permissions
1286 $permissions['membership'] = array(
1289 'access CiviMember',
1293 'access CiviMember',
1294 'delete in CiviMember',
1298 'access CiviMember',
1302 $permissions['membership_status'] = $permissions['membership'];
1303 $permissions['membership_type'] = $permissions['membership'];
1304 $permissions['membership_payment'] = array(
1307 'access CiviMember',
1309 'access CiviContribute',
1310 'edit contributions',
1314 'access CiviMember',
1315 'delete in CiviMember',
1316 'access CiviContribute',
1317 'delete in CiviContribute',
1321 'access CiviMember',
1322 'access CiviContribute',
1326 'access CiviMember',
1328 'access CiviContribute',
1329 'edit contributions',
1333 // Participant permissions
1334 $permissions['participant'] = array(
1338 'register for events',
1343 'edit event participants',
1348 'view event participants',
1353 'edit event participants',
1356 $permissions['participant_payment'] = array(
1360 'register for events',
1361 'access CiviContribute',
1362 'edit contributions',
1367 'edit event participants',
1368 'access CiviContribute',
1369 'delete in CiviContribute',
1374 'view event participants',
1375 'access CiviContribute',
1380 'edit event participants',
1381 'access CiviContribute',
1382 'edit contributions',
1386 // Pledge permissions
1387 $permissions['pledge'] = array(
1390 'access CiviPledge',
1395 'access CiviPledge',
1396 'delete in CiviPledge',
1400 'access CiviPledge',
1404 'access CiviPledge',
1409 //CRM-16777: Disable schedule reminder for user that have 'edit all events' and 'administer CiviCRM' permission.
1410 $permissions['action_schedule'] = array(
1419 $permissions['pledge_payment'] = array(
1422 'access CiviPledge',
1424 'access CiviContribute',
1425 'edit contributions',
1429 'access CiviPledge',
1430 'delete in CiviPledge',
1431 'access CiviContribute',
1432 'delete in CiviContribute',
1436 'access CiviPledge',
1437 'access CiviContribute',
1441 'access CiviPledge',
1443 'access CiviContribute',
1444 'edit contributions',
1448 // Profile permissions
1449 $permissions['profile'] = array(
1450 'get' => array(), // the profile will take care of this
1453 $permissions['uf_group'] = array(
1457 'administer CiviCRM',
1458 'manage event profiles',
1467 'administer CiviCRM',
1468 'manage event profiles',
1472 $permissions['uf_field'] = $permissions['uf_join'] = $permissions['uf_group'];
1473 $permissions['uf_field']['delete'] = array(
1476 'administer CiviCRM',
1477 'manage event profiles',
1480 $permissions['option_value'] = $permissions['uf_group'];
1481 $permissions['option_group'] = $permissions['option_value'];
1483 $permissions['custom_value'] = array(
1484 'gettree' => array('access CiviCRM'),
1487 $permissions['message_template'] = array(
1488 'get' => array('access CiviCRM'),
1489 'create' => array(array('edit message templates', 'edit user-driven message templates', 'edit system workflow message templates')),
1490 'update' => array(array('edit message templates', 'edit user-driven message templates', 'edit system workflow message templates')),
1493 $permissions['report_template']['update'] = 'save Report Criteria';
1494 $permissions['report_template']['create'] = 'save Report Criteria';
1495 return $permissions;
1499 * Translate an unknown action to a canonical form.
1501 * @param string $action
1504 * the standardised action name
1506 public static function getGenericAction($action) {
1507 $snippet = substr($action, 0, 3);
1508 if ($action == 'replace' ||
$snippet == 'del') {
1509 // 'Replace' is a combination of get+create+update+delete; however, the permissions
1510 // on each of those will be tested separately at runtime. This is just a sniff-test
1511 // based on the heuristic that 'delete' tends to be the most closely guarded
1512 // of the necessary permissions.
1515 elseif ($action == 'setvalue' ||
$snippet == 'upd') {
1518 elseif ($action == 'getfields' ||
$action == 'getfield' ||
$action == 'getspec' ||
$action == 'getoptions') {
1521 elseif ($snippet == 'get') {
1528 * Validate user permission across.
1529 * edit or view or with supportable acls.
1533 public static function giveMeAllACLs() {
1534 if (CRM_Core_Permission
::check('view all contacts') ||
1535 CRM_Core_Permission
::check('edit all contacts')
1540 $session = CRM_Core_Session
::singleton();
1541 $contactID = $session->get('userID');
1544 $aclPermission = self
::getPermission();
1545 if (in_array($aclPermission, array(
1546 CRM_Core_Permission
::EDIT
,
1547 CRM_Core_Permission
::VIEW
,
1553 // run acl where hook and see if the user is supplying an ACL clause
1554 // that is not false
1555 $tables = $whereTables = array();
1558 CRM_Utils_Hook
::aclWhereClause(CRM_Core_Permission
::VIEW
,
1559 $tables, $whereTables,
1562 return empty($whereTables) ?
FALSE : TRUE;
1566 * Get component name from given permission.
1568 * @param string $permission
1570 * @return null|string
1571 * the name of component.
1573 public static function getComponentName($permission) {
1574 $componentName = NULL;
1575 $permission = trim($permission);
1576 if (empty($permission)) {
1577 return $componentName;
1580 static $allCompPermissions = array();
1581 if (empty($allCompPermissions)) {
1582 $components = CRM_Core_Component
::getComponents();
1583 foreach ($components as $name => $comp) {
1584 //get all permissions of each components unconditionally
1585 $allCompPermissions[$name] = $comp->getPermissions(TRUE);
1589 if (is_array($allCompPermissions)) {
1590 foreach ($allCompPermissions as $name => $permissions) {
1591 if (array_key_exists($permission, $permissions)) {
1592 $componentName = $name;
1598 return $componentName;
1602 * Get all the contact emails for users that have a specific permission.
1604 * @param string $permissionName
1605 * Name of the permission we are interested in.
1608 * a comma separated list of email addresses
1610 public static function permissionEmails($permissionName) {
1611 $config = CRM_Core_Config
::singleton();
1612 return $config->userPermissionClass
->permissionEmails($permissionName);
1616 * Get all the contact emails for users that have a specific role.
1618 * @param string $roleName
1619 * Name of the role we are interested in.
1622 * a comma separated list of email addresses
1624 public static function roleEmails($roleName) {
1625 $config = CRM_Core_Config
::singleton();
1626 return $config->userRoleClass
->roleEmails($roleName);
1632 public static function isMultisiteEnabled() {
1633 return Civi
::settings()->get('is_enabled') ?
TRUE : FALSE;
1637 * Verify if the user has permission to get the invoice.
1640 * TRUE if the user has download all invoices permission or download my
1641 * invoices permission and the invoice author is the current user.
1643 public static function checkDownloadInvoice() {
1644 $cid = CRM_Core_Session
::getLoggedInContactID();
1645 if (CRM_Core_Permission
::check('access CiviContribute') ||
1646 (CRM_Core_Permission
::check('view my invoices') && $_GET['cid'] == $cid)