Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-21261

Address Get API fails on ACL function for Anon Users

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 4.7.11, 4.7.25
    • Fix Version/s: None
    • Component/s: CiviCRM API
    • Labels:
      None
    • Versioning Impact:
      Patch (backwards-compatible bug fixes)
    • Documentation Required?:
      None
    • Funding Source:
      Needs Funding
    • Verified?:
      No

      Description

      Setup

      • create an ACL for "Everyone" to access some group
      • grant access ajax api permission to anon

      Steps to Reproduce

      • call API Contact.get and return address fields (from js console)
      • Observe that anon users can access contacts and addresses for the configured group.
      • call API Address.get for a contact in said group
      • Observe below constraint violation exception in ConfigAndLog

       

      Dead-end work-around and further observations

      Upon inspection of the civicrm_acl_contact_cache table, it was decided that the call in trace:

      CRM/Contact/BAO/Contact/Permission.php(235): CRM_Contact_BAO_Contact_Permission::cache(0)
      was invalid because the table expects a value of NULL for anon.
      It was then attempted to add

      $userID = ($userID === 0)? 'NULL' : $userID;

      ...before...

      $permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, $userID);

      This did indeed resolve the database constraint violation.

      However, this only resulted in no results returned.
      It was then surmized that since fetching addresses through Contact.get does work, that the same code-path is not active for Contact api calls in this scenario.

      This was proven with adding a debug log to the function which was not hit when calling Contact.get

      Trace

      Oct 04 14:06:28  [info] $Fatal Error Details = Array
      (
          [callback] => Array
              (
                  [0] => CRM_Core_Error
                  [1] => exceptionHandler
              )
      
          [code] => -3
          [message] => DB Error: constraint violation
          [mode] => 16
          [debug_info] =>
      INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )
      SELECT      0 as user_id, contact_a.id as contact_id, 'View' as operation
                FROM civicrm_contact contact_a  LEFT JOIN civicrm_group_contact `civicrm_group_contact-ACL` ON (contact_a.id = `civicrm_group_contact-ACL`.contact_id AND `civicrm_group_contact-ACL`.status IN ("Added"))   LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache-ACL` ON contact_a.id = `civicrm_group_contact_cache-ACL`.contact_id   LEFT JOIN civicrm_grant ON civicrm_grant.contact_id = contact_a.id
      WHERE     ( ( `civicrm_group_contact-ACL`.group_id IN (66) AND `civicrm_group_contact-ACL`.status IN ("Added") ) OR `civicrm_group_contact_cache-ACL`.group_id IN (66) )  AND (contact_a.is_deleted = 0)
      GROUP BY contact_a.id
      ON DUPLICATE KEY UPDATE
               user_id=VALUES(user_id),
               contact_id=VALUES(contact_id),
               operation=VALUES(operation) [nativecode=1452 ** Cannot add or update a child row: a foreign key constraint fails (`hungerfr_hungervol_civicrm_dev`.`civicrm_acl_contact_cache`, CONSTRAINT `FK_civicrm_acl_contact_cache_user_id` FOREIGN KEY (`user_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE)]
          [type] => DB_Error
          [user_info] =>
      INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )
      SELECT      0 as user_id, contact_a.id as contact_id, 'View' as operation
                FROM civicrm_contact contact_a  LEFT JOIN civicrm_group_contact `civicrm_group_contact-ACL` ON (contact_a.id = `civicrm_group_contact-ACL`.contact_id AND `civicrm_group_contact-ACL`.status IN ("Added"))   LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache-ACL` ON contact_a.id = `civicrm_group_contact_cache-ACL`.contact_id   LEFT JOIN civicrm_grant ON civicrm_grant.contact_id = contact_a.id
      WHERE     ( ( `civicrm_group_contact-ACL`.group_id IN (66) AND `civicrm_group_contact-ACL`.status IN ("Added") ) OR `civicrm_group_contact_cache-ACL`.group_id IN (66) )  AND (contact_a.is_deleted = 0)
      GROUP BY contact_a.id
      ON DUPLICATE KEY UPDATE
               user_id=VALUES(user_id),
               contact_id=VALUES(contact_id),
               operation=VALUES(operation) [nativecode=1452 ** Cannot add or update a child row: a foreign key constraint fails (`hungerfr_hungervol_civicrm_dev`.`civicrm_acl_contact_cache`, CONSTRAINT `FK_civicrm_acl_contact_cache_user_id` FOREIGN KEY (`user_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE)]
          [to_string] => [db_error: message="DB Error: constraint violation" code=-3 mode=callback callback=CRM_Core_Error::exceptionHandler prefix="" info="
      INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )
      SELECT      0 as user_id, contact_a.id as contact_id, 'View' as operation
                FROM civicrm_contact contact_a  LEFT JOIN civicrm_group_contact `civicrm_group_contact-ACL` ON (contact_a.id = `civicrm_group_contact-ACL`.contact_id AND `civicrm_group_contact-ACL`.status IN ("Added"))   LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache-ACL` ON contact_a.id = `civicrm_group_contact_cache-ACL`.contact_id   LEFT JOIN civicrm_grant ON civicrm_grant.contact_id = contact_a.id
      WHERE     ( ( `civicrm_group_contact-ACL`.group_id IN (66) AND `civicrm_group_contact-ACL`.status IN ("Added") ) OR `civicrm_group_contact_cache-ACL`.group_id IN (66) )  AND (contact_a.is_deleted = 0)
      GROUP BY contact_a.id
      ON DUPLICATE KEY UPDATE
               user_id=VALUES(user_id),
               contact_id=VALUES(contact_id),
               operation=VALUES(operation) [nativecode=1452 ** Cannot add or update a child row: a foreign key constraint fails (`hungerfr_hungervol_civicrm_dev`.`civicrm_acl_contact_cache`, CONSTRAINT `FK_civicrm_acl_contact_cache_user_id` FOREIGN KEY (`user_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE)]"]
      )
      
      
      Oct 04 14:06:28  [info] $backTrace = #0 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/Error.php(935): CRM_Core_Error::backtrace("backTrace", TRUE)
      #1 [internal function](): CRM_Core_Error::exceptionHandler(Object(DB_Error))
      #2 htdocs/sites/all/modules/contrib/civicrm/packages/PEAR.php(931): call_user_func((Array:2), Object(DB_Error))
      #3 htdocs/sites/all/modules/contrib/civicrm/packages/DB.php(976): PEAR_Error->PEAR_Error("DB Error: constraint violation", -3, 16, (Array:2), "\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #4 htdocs/sites/all/modules/contrib/civicrm/packages/PEAR.php(564): DB_Error->DB_Error(-3, 16, (Array:2), "\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #5 htdocs/sites/all/modules/contrib/civicrm/packages/DB/common.php(1905): PEAR->raiseError(NULL, -3, NULL, NULL, "\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...", "DB_Error", TRUE)
      #6 htdocs/sites/all/modules/contrib/civicrm/packages/DB/mysql.php(895): DB_common->raiseError(-3, NULL, NULL, NULL, "1452 ** Cannot add or update a child row: a foreign key constraint fails (`hu...")
      #7 htdocs/sites/all/modules/contrib/civicrm/packages/DB/mysql.php(328): DB_mysql->mysqlRaiseError()
      #8 htdocs/sites/all/modules/contrib/civicrm/packages/DB/common.php(1216): DB_mysql->simpleQuery("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #9 htdocs/sites/all/modules/contrib/civicrm/packages/DB/DataObject.php(2438): DB_common->query("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #10 htdocs/sites/all/modules/contrib/civicrm/packages/DB/DataObject.php(1627): DB_DataObject->_query("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #11 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/DAO.php(344): DB_DataObject->query("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #12 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/DAO.php(1265): CRM_Core_DAO->query("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...", TRUE)
      #13 htdocs/sites/all/modules/contrib/civicrm/CRM/Contact/BAO/Contact/Permission.php(138): CRM_Core_DAO::executeQuery("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nS...")
      #14 htdocs/sites/all/modules/contrib/civicrm/CRM/Contact/BAO/Contact/Permission.php(235): CRM_Contact_BAO_Contact_Permission::cache(0)
      #15 htdocs/sites/all/modules/contrib/civicrm/CRM/Contact/BAO/Contact.php(3428): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
      #16 htdocs/sites/all/modules/contrib/civicrm/CRM/Utils/SQL.php(48): CRM_Contact_BAO_Contact->addSelectWhereClause()
      #17 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/DAO.php(2415): CRM_Utils_SQL::mergeSubquery("Contact")
      #18 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/DAO.php(2436): CRM_Core_DAO->addSelectWhereClause()
      #19 htdocs/sites/all/modules/contrib/civicrm/Civi/API/SelectQuery.php(527): CRM_Core_DAO::getSelectWhereClause("a")
      #20 htdocs/sites/all/modules/contrib/civicrm/Civi/API/SelectQuery.php(116): Civi\API\SelectQuery->getAclClause("a", "CRM_Core_BAO_Address")
      #21 htdocs/sites/all/modules/contrib/civicrm/api/v3/utils.php(1340): Civi\API\SelectQuery->__construct("CRM_Core_BAO_Address", (Array:10), FALSE)
      #22 htdocs/sites/all/modules/contrib/civicrm/api/v3/Address.php(156): _civicrm_api3_basic_get("CRM_Core_BAO_Address", (Array:10), TRUE, "Address")
      #23 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Provider/MagicFunctionProvider.php(89): civicrm_api3_address_get((Array:10))
      #24 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Kernel.php(96): Civi\API\Provider\MagicFunctionProvider->invoke((Array:9))
      #25 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Subscriber/ChainSubscriber.php(198): Civi\API\Kernel->run("address", "get", (Array:10))
      #26 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Subscriber/ChainSubscriber.php(72): Civi\API\Subscriber\ChainSubscriber->callNestedApi(Object(Civi\API\Kernel), (Array:9), (Array:4), "get", "Contact", 3)
      #27 [internal function](): Civi\API\Subscriber\ChainSubscriber->onApiRespond(Object(Civi\API\Event\RespondEvent), "api.respond", Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher))
      #28 htdocs/sites/all/modules/contrib/civicrm/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcher.php(164): call_user_func((Array:2), Object(Civi\API\Event\RespondEvent), "api.respond", Object(Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher))
      #29 htdocs/sites/all/modules/contrib/civicrm/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/EventDispatcher.php(53): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch((Array:4), "api.respond", Object(Civi\API\Event\RespondEvent))
      #30 htdocs/sites/all/modules/contrib/civicrm/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php(170): Symfony\Component\EventDispatcher\EventDispatcher->dispatch("api.respond", Object(Civi\API\Event\RespondEvent))
      #31 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Kernel.php(221): Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch("api.respond", Object(Civi\API\Event\RespondEvent))
      #32 htdocs/sites/all/modules/contrib/civicrm/Civi/API/Kernel.php(98): Civi\API\Kernel->respond(Object(Civi\API\Provider\MagicFunctionProvider), (Array:9), (Array:4))
      #33 htdocs/sites/all/modules/contrib/civicrm/api/api.php(23): Civi\API\Kernel->run("Contact", "get", (Array:8), NULL)
      #34 htdocs/sites/all/modules/contrib/civicrm/CRM/Utils/REST.php(404): civicrm_api("Contact", "get", (Array:8))
      #35 htdocs/sites/all/modules/contrib/civicrm/CRM/Utils/REST.php(641): CRM_Utils_REST::process((Array:3), (Array:6))
      #36 [internal function](): CRM_Utils_REST::ajax()
      #37 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/Invoke.php(278): call_user_func((Array:2))
      #38 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/Invoke.php(86): CRM_Core_Invoke::runItem((Array:12))
      #39 htdocs/sites/all/modules/contrib/civicrm/CRM/Core/Invoke.php(54): CRM_Core_Invoke::_invoke((Array:3))
      #40 htdocs/sites/all/modules/contrib/civicrm/drupal/civicrm.module(448): CRM_Core_Invoke::invoke((Array:3))
      #41 [internal function](): civicrm_invoke("ajax", "rest")
      #42 htdocs/includes/menu.inc(527): call_user_func_array("civicrm_invoke", (Array:2))
      #43 htdocs/index.php(21): menu_execute_active_handler()
      #44 {main}

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              ginkgomzd Michael Z Daryabeygi
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: