Fix api_key handling from joins
authorColeman Watts <coleman@civicrm.org>
Mon, 1 Jul 2019 00:47:47 +0000 (20:47 -0400)
committerSeamus Lee <seamuslee001@gmail.com>
Sat, 9 Nov 2019 02:58:58 +0000 (13:58 +1100)
Civi/API/SelectQuery.php
Civi/Test/Api3TestTrait.php
Civi/Test/ContactTestTrait.php
tests/phpunit/api/v3/ContactTest.php

index 752159b3d7aa1213e723fd4fc64e1c85da8ca48b..95bd4ce093d55f7f92646a57f81d1b4c7ef739fb 100644 (file)
@@ -233,6 +233,12 @@ abstract class SelectQuery {
         // Join doesn't exist - might be another param with a dot in it for some reason, we'll just ignore it.
         return NULL;
       }
+
+      // Skip if we don't have permission to access this field
+      if ($this->checkPermissions && !empty($fieldInfo['permission']) && !\CRM_Core_Permission::check($fieldInfo['permission'])) {
+        return NULL;
+      }
+
       $fkTable = \CRM_Core_DAO_AllCoreTables::getTableForClass($fkField['FKClassName']);
       $tableAlias = implode('_to_', $subStack) . "_to_$fkTable";
 
index e853f5249b14fdb62e776ecc4aaf8b375d0f3fd6..8c4fcb5eb926855f01d556307a64d18c14b65baf 100644 (file)
@@ -320,8 +320,7 @@ trait Api3TestTrait {
       $v4Params['language'] = $language;
     }
     $toRemove = ['option.', 'return', 'api.', 'format.'];
-    $chains = [];
-    $custom = [];
+    $chains = $joins = $custom = [];
     foreach ($v3Params as $key => $val) {
       foreach ($toRemove as $remove) {
         if (strpos($key, $remove) === 0) {
@@ -410,6 +409,13 @@ trait Api3TestTrait {
       case 'get':
         if ($options['return'] && $v3Action !== 'getcount') {
           $v4Params['select'] = array_keys($options['return']);
+          // Convert join syntax
+          foreach ($v4Params['select'] as &$select) {
+            if (strstr($select, '_id.')) {
+              $joins[$select] = explode('.', str_replace('_id.', '.', $select));
+              $select = str_replace('_id.', '.', $select);
+            }
+          }
         }
         if ($options['limit'] && $v4Entity != 'Setting') {
           $v4Params['limit'] = $options['limit'];
@@ -575,6 +581,10 @@ trait Api3TestTrait {
       foreach ($chains as $key => $params) {
         $result[$index][$key] = $this->runApi4LegacyChain($key, $params, $v4Entity, $row, $sequential);
       }
+      // Convert join format
+      foreach ($joins as $api3Key => $api4Path) {
+        $result[$index][$api3Key] = \CRM_Utils_Array::pathGet($result[$index], $api4Path);
+      }
       // Resolve custom field names
       foreach ($custom as $group => $fields) {
         foreach ($fields as $field => $v3FieldName) {
index 50e256177fb55d71ffb8e1032d559a7650132018..f3e85083d92e43be8f93dbdfa2c2d3243fd7a2cb 100644 (file)
@@ -160,7 +160,7 @@ trait ContactTestTrait {
    *
    */
   private function _contactCreate($params) {
-    $result = $this->callAPISuccess('contact', 'create', $params);
+    $result = civicrm_api3('contact', 'create', $params);
     if (!empty($result['is_error']) || empty($result['id'])) {
       throw new \CRM_Core_Exception('Could not create test contact, with message: ' . \CRM_Utils_Array::value('error_message', $result) . "\nBacktrace:" . \CRM_Utils_Array::value('trace', $result));
     }
index 03dd75effaf015c2ee917469ee6368d362fa17ff..94ee4e49b8f865b9f59203a742942f5f84794762 100644 (file)
@@ -632,8 +632,16 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->assertEquals('B', $result['values'][$contactId]['last_name']);
     $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
 
+    // Should also be returned via join
+    $joinResult = $this->callAPISuccessGetSingle('Email', [
+      'check_permissions' => 1,
+      'contact_id' => $contactId,
+      'return' => 'contact_id.api_key',
+    ]);
+    $this->assertEquals('abcd1234', $joinResult['contact_id.api_key']);
+
     // Restricted return -- because we don't have permission
-    $config->userPermissionClass->permissions = ['access CiviCRM', 'edit all contacts'];
+    $config->userPermissionClass->permissions = ['access CiviCRM', 'view all contacts', 'edit all contacts'];
     $result = $this->callAPISuccess('Contact', 'create', [
       'check_permissions' => 1,
       'id' => $contactId,
@@ -642,6 +650,14 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->assertEquals('A4', $result['values'][$contactId]['first_name']);
     $this->assertEquals('B', $result['values'][$contactId]['last_name']);
     $this->assertTrue(empty($result['values'][$contactId]['api_key']));
+
+    // Should also be restricted via join
+    $joinResult = $this->callAPISuccessGetSingle('Email', [
+      'check_permissions' => 1,
+      'contact_id' => $contactId,
+      'return' => ['email', 'contact_id.api_key'],
+    ]);
+    $this->assertTrue(empty($joinResult['contact_id.api_key']));
   }
 
   /**