(dev/mail/6) Using ACL to restrict mailing recipients leads to fatal error
authordeb.monish <monish.deb@jmaconsulting.biz>
Tue, 10 Apr 2018 13:13:50 +0000 (18:43 +0530)
committerdeb.monish <monish.deb@jmaconsulting.biz>
Mon, 16 Apr 2018 11:20:19 +0000 (16:50 +0530)
CRM/Mailing/BAO/Mailing.php
tests/phpunit/CRM/Mailing/BAO/MailingTest.php

index 3a0f08048c52f006681fa93e006e980558bd8a9c..3790cd540f5b492aee0c47eabec56a7216077043 100644 (file)
@@ -335,7 +335,7 @@ class CRM_Mailing_BAO_Mailing extends CRM_Mailing_DAO_Mailing {
 
     $query = $query->select($selectClause)->orderBy($orderBy);
     if (!CRM_Utils_System::isNull($aclFrom)) {
-      $query = $query->from('acl', $aclFrom);
+      $query = $query->join('acl', $aclFrom);
     }
     if (!CRM_Utils_System::isNull($aclWhere)) {
       $query = $query->where($aclWhere);
index 73253085c6a33ccb3af647ca3e3ab3447f44e5f5..57c1d5b63bc723edf74cdd2339953ef3b269f1ee 100644 (file)
@@ -30,6 +30,8 @@
  */
 class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase {
 
+  protected $allowedContactId = 0;
+
   public function setUp() {
     parent::setUp();
   }
@@ -84,6 +86,64 @@ class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase {
     ));
   }
 
+  /**
+   * Test to ensure that using ACL permitted contacts are correctly fetched for bulk mailing
+   */
+  public function testgetRecipientsUsingACL() {
+    $this->prepareForACLs();
+    $this->createLoggedInUser();
+    // create hook to build ACL where clause which choses $this->allowedContactId as the only contact to be considered as mail recipient
+    $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereAllowedOnlyOne'));
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'view my contact');
+
+    // Create dummy group and assign 2 contacts
+    $name = 'Test static group ' . substr(sha1(rand()), 0, 7);
+    $groupID = $this->groupCreate([
+      'name' => $name,
+      'title' => $name,
+      'is_active' => 1,
+    ]);
+    // Create 2 contacts where one of them identified as $this->allowedContactId will be used in ACL where clause
+    $contactID1 = $this->individualCreate(array(), 0);
+    $this->allowedContactId = $this->individualCreate(array(), 1);
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupID,
+      'contact_id' => $contactID1,
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupID,
+      'contact_id' => $this->allowedContactId,
+    ));
+
+    // Create dummy mailing
+    $mailingID = $this->callAPISuccess('Mailing', 'create', array())['id'];
+    $this->createMailingGroup($mailingID, $groupID);
+
+    // Check that the desired contact (identified as Contact ID - $this->allowedContactId) is the only
+    //  contact chosen as mail recipient
+    $expectedContactIDs = [$this->allowedContactId];
+    $this->assertRecipientsCorrect($mailingID, $expectedContactIDs);
+
+    $this->cleanUpAfterACLs();
+    $this->contactDelete($contactID1);
+    $this->contactDelete($this->allowedContactId);
+  }
+
+  /**
+   * Build ACL where clause
+   *
+   * @implements CRM_Utils_Hook::aclWhereClause
+   *
+   * @param string $type
+   * @param array $tables
+   * @param array $whereTables
+   * @param int $contactID
+   * @param string $where
+   */
+  public function aclWhereAllowedOnlyOne($type, &$tables, &$whereTables, &$contactID, &$where) {
+    $where = " contact_a.id = " . $this->allowedContactId;
+  }
+
   /**
    * @todo Missing tests:
    * - Ensure opt out emails are not mailed