--- /dev/null
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+use Civi\Core\Event\GenericHookEvent;
+
+/**
+ * Class CRM_Core_Permission_List
+ *
+ * When presenting the administrator with a list of available permissions (`Permission.get`),
+ * the methods in provide the default implementations.
+ *
+ * These methods are not intended for public consumption or frequent execution.
+ *
+ * @see \Civi\Api4\Action\Permission\Get
+ */
+class CRM_Core_Permission_List {
+
+ /**
+ * Enumerate concrete permissions that originate in CiviCRM (core or extension).
+ *
+ * @param \Civi\Core\Event\GenericHookEvent $e
+ * @see \CRM_Utils_Hook::permissionList
+ */
+ public static function findCiviPermissions(GenericHookEvent $e) {
+ $activeCorePerms = \CRM_Core_Permission::basicPermissions(FALSE);
+ $allCorePerms = \CRM_Core_Permission::basicPermissions(TRUE, TRUE);
+ foreach ($allCorePerms as $permName => $corePerm) {
+ $e->permissions[$permName] = [
+ 'group' => 'civicrm',
+ 'title' => $corePerm['label'] ?? $corePerm[0] ?? $permName,
+ 'description' => $corePerm['description'] ?? $corePerm[1] ?? NULL,
+ 'is_active' => isset($activeCorePerms[$permName]),
+ ];
+ }
+ }
+
+ /**
+ * Enumerate permissions that originate in the CMS (core or module/plugin),
+ * excluding any Civi permissions.
+ *
+ * @param \Civi\Core\Event\GenericHookEvent $e
+ * @see \CRM_Utils_Hook::permissionList
+ */
+ public static function findCmsPermissions(GenericHookEvent $e) {
+ $config = \CRM_Core_Config::singleton();
+
+ $ufPerms = $config->userPermissionClass->getAvailablePermissions();
+ foreach ($ufPerms as $permName => $cmsPerm) {
+ $e->permissions[$permName] = [
+ 'group' => 'cms',
+ 'title' => $cmsPerm['title'] ?? $permName,
+ 'description' => $cmsPerm['description'] ?? NULL,
+ ];
+ }
+
+ // There are a handful of special permissions defined in CRM/Core/Permission/*.php
+ // using the `translatePermission()` mechanism.
+ $e->permissions['cms:view user account'] = [
+ 'group' => 'cms',
+ 'title' => ts('CMS') . ': ' . ts('View user accounts'),
+ 'description' => ts('View user accounts. (Synthetic permission - adapts to local CMS)'),
+ 'is_synthetic' => TRUE,
+ ];
+ $e->permissions['cms:administer users'] = [
+ 'group' => 'cms',
+ 'title' => ts('CMS') . ': ' . ts('Administer user accounts'),
+ 'description' => ts('Administer user accounts. (Synthetic permission - adapts to local CMS)'),
+ 'is_synthetic' => TRUE,
+ ];
+ }
+
+ /**
+ * @param \Civi\Core\Event\GenericHookEvent $e
+ * @see \CRM_Utils_Hook::permissionList
+ */
+ public static function findConstPermissions(GenericHookEvent $e) {
+ // There are a handful of special permissions defined in CRM/Core/Permission.
+ $e->permissions[\CRM_Core_Permission::ALWAYS_DENY_PERMISSION] = [
+ 'group' => 'const',
+ 'title' => ts('Constant: Always deny'),
+ 'is_synthetic' => TRUE,
+ ];
+ $e->permissions[\CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION] = [
+ 'group' => 'const',
+ 'title' => ts('Constant: Always allow'),
+ 'is_synthetic' => TRUE,
+ ];
+ }
+
+}
}
/**
- * This hook is called when loading CMS permissions; use this hook to modify
+ * This hook is called when exporting Civi's permission to the CMS. Use this hook to modify
* the array of system permissions for CiviCRM.
*
* @param array $permissions
);
}
+ /**
+ * This hook is used to enumerate the list of available permissions. It may
+ * include concrete permissions defined by Civi, concrete permissions defined
+ * by the CMS, and/or synthetic permissions.
+ *
+ * @param array $permissions
+ * Array of permissions, keyed by symbolic name. Each is an array with fields:
+ * - group: string (ex: "civicrm", "cms")
+ * - title: string (ex: "CiviEvent: Register for events")
+ * - description: string (ex: "Register for events online")
+ * - is_synthetic: bool (TRUE for synthetic permissions with a bespoke evaluation. FALSE for concrete permissions that registered+granted in the UF user-management layer.
+ * Default TRUE iff name begins with '@')
+ * - is_active: bool (TRUE if this permission is defined by. Default: TRUE)
+ *
+ * @return null
+ * The return value is ignored
+ * @see Civi\Api4\Permission::get()
+ */
+ public static function permissionList(&$permissions) {
+ return self::singleton()->invoke(['permissions'], $permissions,
+ self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject,
+ 'civicrm_permissionList'
+ );
+ }
+
/**
* This hook is called when checking permissions; use this hook to dynamically
* escalate user permissions in certain use cases (cf. CRM-19256).
--- /dev/null
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Action\Permission;
+
+use Civi\Api4\Generic\BasicGetAction;
+
+/**
+ * Get a list of extant permissions.
+ *
+ * NOTE: This is a high-level API intended for introspective use by administrative tools.
+ * It may be poorly suited to recursive usage (e.g. permissions defined dynamically
+ * on top of permissions!) or during install/uninstall processes.
+ *
+ * The list of permissions is generated via hook, and there is a standard/default
+ * listener.
+ *
+ * @see CRM_Core_Permission_List
+ * @see \CRM_Utils_Hook::permissionList
+ */
+class Get extends BasicGetAction {
+
+ public function getRecords() {
+ $cacheKey = 'list_' . $GLOBALS['tsLocale'];
+ if (!isset(\Civi::$statics[__CLASS__][$cacheKey])) {
+ $perms = [];
+ \CRM_Utils_Hook::permissionList($perms);
+ foreach (array_keys($perms) as $permName) {
+ $defaults = [
+ 'name' => $permName,
+ 'group' => 'unknown',
+ 'is_synthetic' => ($permName[0] === '@'),
+ 'is_active' => TRUE,
+ ];
+ $perms[$permName] = array_merge($defaults, $perms[$permName]);
+ }
+ \Civi::$statics[__CLASS__][$cacheKey] = $perms;
+ }
+
+ return \Civi::$statics[__CLASS__][$cacheKey];
+ }
+
+}
--- /dev/null
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC https://civicrm.org/licensing
+ */
+
+namespace Civi\Api4;
+
+/**
+ * (Read-only) Available permissions
+ *
+ * NOTE: This is a high-level API intended for introspective use by administrative tools.
+ * It may be poorly suited to recursive usage (e.g. permissions defined dynamically
+ * on top of permissions!) or during install/uninstall processes.
+ *
+ * @searchable false
+ * @package Civi\Api4
+ */
+class Permission extends Generic\AbstractEntity {
+
+ /**
+ * @param bool $checkPermissions
+ * @return \Civi\Api4\Generic\BasicGetAction
+ */
+ public static function get($checkPermissions = TRUE) {
+ return (new \Civi\Api4\Action\Permission\Get(__CLASS__, __FUNCTION__))->setCheckPermissions($checkPermissions);
+ }
+
+ /**
+ * @param bool $checkPermissions
+ * @return Generic\BasicGetFieldsAction
+ */
+ public static function getFields($checkPermissions = TRUE) {
+ return (new Generic\BasicGetFieldsAction(__CLASS__, __FUNCTION__, function() {
+ return [
+ [
+ 'name' => 'group',
+ 'title' => 'Group',
+ 'required' => TRUE,
+ 'data_type' => 'String',
+ ],
+ [
+ 'name' => 'name',
+ 'title' => 'Name',
+ 'required' => TRUE,
+ 'data_type' => 'String',
+ ],
+ [
+ 'name' => 'title',
+ 'title' => 'Title',
+ 'required' => TRUE,
+ 'data_type' => 'String',
+ ],
+ [
+ 'name' => 'description',
+ 'title' => 'Description',
+ 'required' => FALSE,
+ 'data_type' => 'String',
+ ],
+ [
+ 'name' => 'is_synthetic',
+ 'title' => 'Is Synthetic',
+ 'required' => FALSE,
+ 'data_type' => 'Boolean',
+ ],
+ [
+ 'name' => 'is_active',
+ 'title' => 'Is Active',
+ 'description' => '',
+ 'default' => TRUE,
+ 'required' => FALSE,
+ 'data_type' => 'Boolean',
+ ],
+ ];
+ }))->setCheckPermissions($checkPermissions);
+ }
+
+ /**
+ * @return array
+ */
+ public static function permissions() {
+ return [
+ "meta" => ["access CiviCRM"],
+ "default" => ["access CiviCRM"],
+ ];
+ }
+
+}
$dispatcher->addListener('hook_civicrm_coreResourceList', ['\CRM_Utils_System', 'appendCoreResources']);
$dispatcher->addListener('hook_civicrm_getAssetUrl', ['\CRM_Utils_System', 'alterAssetUrl']);
$dispatcher->addListener('hook_civicrm_alterExternUrl', ['\CRM_Utils_System', 'migrateExternUrl'], 1000);
+ $dispatcher->addListener('hook_civicrm_permissionList', ['CRM_Core_Permission_List', 'findConstPermissions'], 975);
+ $dispatcher->addListener('hook_civicrm_permissionList', ['CRM_Core_Permission_List', 'findCiviPermissions'], 950);
+ $dispatcher->addListener('hook_civicrm_permissionList', ['CRM_Core_Permission_List', 'findCmsPermissions'], 925);
+
$dispatcher->addListener('hook_civicrm_triggerInfo', ['\CRM_Contact_BAO_RelationshipCache', 'onHookTriggerInfo']);
$dispatcher->addListener('civi.dao.postInsert', ['\CRM_Core_BAO_RecurringEntity', 'triggerInsert']);
$dispatcher->addListener('civi.dao.postUpdate', ['\CRM_Core_BAO_RecurringEntity', 'triggerUpdate']);