Skip to content

Commit

Permalink
(dev/mail/6) Using ACL to restrict mailing recipients leads to fatal …
Browse files Browse the repository at this point in the history
…error
  • Loading branch information
monishdeb committed Apr 16, 2018
1 parent 37c97de commit fae688e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CRM/Mailing/BAO/Mailing.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ public static function getRecipients($mailingID) {

$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);
Expand Down
60 changes: 60 additions & 0 deletions tests/phpunit/CRM/Mailing/BAO/MailingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
*/
class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase {

protected $allowedContactId = 0;

public function setUp() {
parent::setUp();
}
Expand Down Expand Up @@ -84,6 +86,64 @@ private function createMailingGroup($mailingID, $groupID, $type = 'Include') {
));
}

/**
* 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
Expand Down

0 comments on commit fae688e

Please sign in to comment.