(REF) Consistently pass `string $entity` to all flavors of checkAccess
authorTim Otten <totten@civicrm.org>
Mon, 7 Jun 2021 06:05:40 +0000 (23:05 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 8 Jun 2021 04:10:03 +0000 (21:10 -0700)
1. This removes the special-case where `CustomValue::checkAccess()` needs an extra parameter
   to identify the target entity.
2. This lines things up to do the swap from `_checkAccess()` to a hook/event listener

CRM/Contact/AccessTrait.php
CRM/Contact/BAO/Contact.php
CRM/Core/BAO/CustomValue.php
CRM/Core/DAO.php
CRM/Core/DynamicFKAccessTrait.php
Civi/Api4/Utils/CoreUtil.php

index 372a8d50dcf41ff9767a04bd2103ac71e5abc7d7..d5206e04b0a18b655573dbb41e610b1a78ad30bc 100644 (file)
 trait CRM_Contact_AccessTrait {
 
   /**
+   * @param string $entityName
    * @param string $action
    * @param array $record
    * @param int|NULL $userID
    * @return bool
    * @see CRM_Core_DAO::checkAccess
    */
-  public static function _checkAccess(string $action, array $record, $userID) {
+  public static function _checkAccess(string $entityName, string $action, array $record, $userID) {
     $cid = $record['contact_id'] ?? NULL;
     if (!$cid && !empty($record['id'])) {
       $cid = CRM_Core_DAO::getFieldValue(__CLASS__, $record['id'], 'contact_id');
index 5275f5a9fd991c130bfcb044721c7dd299d9da95..c76c2888366021e624d0831b3ceb81d7e828d320 100644 (file)
@@ -3729,13 +3729,14 @@ LEFT JOIN civicrm_address ON ( civicrm_address.contact_id = civicrm_contact.id )
   }
 
   /**
+   * @param string $entityName
    * @param string $action
    * @param array $record
    * @param $userID
    * @return bool
    * @see CRM_Core_DAO::checkAccess
    */
-  public static function _checkAccess(string $action, array $record, $userID): bool {
+  public static function _checkAccess(string $entityName, string $action, array $record, $userID): bool {
     switch ($action) {
       case 'create':
         return CRM_Core_Permission::check('add contacts', $userID);
index 0ad75b12a466df2f240f6e4d79a947191a19076c..02f7eb41043d00439dec8663ccfaea22e44336f8 100644 (file)
@@ -224,14 +224,17 @@ class CRM_Core_BAO_CustomValue extends CRM_Core_DAO {
   /**
    * Special checkAccess function for multi-record custom pseudo-entities
    *
+   * @param string $entityName
+   *   Ex: 'Contact' or 'Custom_Foobar'
    * @param string $action
    * @param array $record
-   * @param null $userID
+   * @param int|null $userID
+   *   Contact ID of the active user (whose access we must check). NULL for anonymous.
    * @param bool $granted
-   * @param string $groupName
    * @return bool
    */
-  public static function checkAccess(string $action, array $record, $userID = NULL, $granted = TRUE, $groupName = NULL): bool {
+  public static function checkAccess(string $entityName, string $action, array $record, $userID, $granted = TRUE): bool {
+    $groupName = substr($entityName, 0, 7) === 'Custom_' ? substr($entityName, 7) : NULL;
     if (!$groupName) {
       // $groupName is required but the function signature has to match the parent.
       throw new CRM_Core_Exception('Missing required $groupName in CustomValue::checkAccess');
index d8dbad2760a2b9adb6d99c35bad9920ad9f88f95..25d88a379f99f6f6e93546c7b0124c0da09960d7 100644 (file)
@@ -3045,21 +3045,22 @@ SELECT contact_id
    *
    * Dispatches to internal BAO function ('static::_checkAccess())` and `hook_civicrm_checkAccess`.
    *
+   * @param string $entityName
+   *   Ex: 'Contact' or 'Custom_Foobar'
    * @param string $action
    *   APIv4 action name.
    *   Ex: 'create', 'get', 'delete'
    * @param array $record
    *   All (known/loaded) values of individual record being accessed.
    *   The record should provide an 'id' but may otherwise be incomplete; guard accordingly.
-   * @param int $userID
-   *   Contact ID of the active user (whose access we must check).
+   * @param int|null $userID
+   *   Contact ID of the active user (whose access we must check). NULL for anonymous.
    * @param bool $granted
    *   Initial value (usually TRUE, but the API might pass FALSE if gatekeeper permissions fail)
    *
    * @return bool
    */
-  public static function checkAccess(string $action, array $record, $userID = NULL, $granted = TRUE): bool {
-    $entityName = CRM_Core_DAO_AllCoreTables::getBriefName(static::class);
+  public static function checkAccess(string $entityName, string $action, array $record, $userID, $granted = TRUE): bool {
     // Ensure this function was either called on a BAO class or a DAO that has no BAO
     if (!$entityName ||
       (!strpos(static::class, '_BAO_') && CRM_Core_DAO_AllCoreTables::getBAOClassName(static::class) !== static::class)
@@ -3069,7 +3070,7 @@ SELECT contact_id
     $userID = isset($userID) ? (int) $userID : CRM_Core_Session::getLoggedInContactID();
     // Dispatch to protected function _checkAccess in this BAO
     if ($granted && method_exists(static::class, '_checkAccess')) {
-      $granted = static::_checkAccess($action, $record, $userID);
+      $granted = static::_checkAccess($entityName, $action, $record, $userID);
     }
     // Dispatch to hook
     CRM_Utils_Hook::checkAccess($entityName, $action, $record, $userID, $granted);
index ce8dec38d44db9e2d3a21b4819feaa2cab0f9195..ebf83825539b5f72998fae79e7953f307807ab22 100644 (file)
 trait CRM_Core_DynamicFKAccessTrait {
 
   /**
+   * @param string $entityName
    * @param string $action
    * @param array $record
    * @param int|NULL $userID
    * @return bool
    * @see CRM_Core_DAO::checkAccess
    */
-  public static function _checkAccess(string $action, array $record, $userID): bool {
+  public static function _checkAccess(string $entityName, string $action, array $record, $userID): bool {
     $eid = $record['entity_id'] ?? NULL;
     $table = $record['entity_table'] ?? NULL;
     if (!$eid && !empty($record['id'])) {
index 2d723f05c59d83e809d0a3157f050aa54df57319..adc2a1670d16b413fa742ed31f6176486ddf2442 100644 (file)
@@ -179,12 +179,8 @@ class CoreUtil {
     else {
       // If entity has a BAO, run the BAO::checkAccess function, which will call the hook
       $baoName = self::getBAOFromApiName($entityName);
-      // CustomValue also requires the name of the group
-      if ($baoName === 'CRM_Core_BAO_CustomValue') {
-        $granted = \CRM_Core_BAO_CustomValue::checkAccess($actionName, $record, $userID, $granted, substr($entityName, 7));
-      }
-      elseif ($baoName) {
-        $granted = $baoName::checkAccess($actionName, $record, $userID, $granted);
+      if ($baoName) {
+        $granted = $baoName::checkAccess($entityName, $actionName, $record, $userID, $granted);
       }
       // Otherwise, call the hook directly
       else {