From eca8cf67dc10ef4cd3fd6cbb214b2d353bae9053 Mon Sep 17 00:00:00 2001 From: Brendan Heywood Date: Tue, 2 Feb 2016 18:05:53 +1100 Subject: [PATCH] MDL-52818 core: Added CFG->divertallemailsexcept config option When $CFG->divertallemailsto is specified, this allows a list of email or domain exceptions to be whitelisted enabling easier testing by groups of testers who don't share a single email address. --- config-dist.php | 4 +++ lib/moodlelib.php | 29 +++++++++++++++- lib/tests/moodlelib_test.php | 67 ++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/config-dist.php b/config-dist.php index beb9ac347b1..04b51d7bda1 100644 --- a/config-dist.php +++ b/config-dist.php @@ -589,6 +589,10 @@ $CFG->admin = 'admin'; // Divert all outgoing emails to this address to test and debug emailing features // $CFG->divertallemailsto = 'root@localhost.local'; // NOT FOR PRODUCTION SERVERS! // +// Except for certain email addresses you want to let through for testing. Accepts +// a comma separated list of regexes. +// $CFG->divertallemailsexcept = 'tester@dev.com, fred(\+.*)?@example.com'; // NOT FOR PRODUCTION SERVERS! +// // Uncomment if you want to allow empty comments when modifying install.xml files. // $CFG->xmldbdisablecommentchecking = true; // NOT FOR PRODUCTION SERVERS! // diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 5e045816adf..a9c2539bfeb 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -5433,6 +5433,33 @@ function get_mailer($action='get') { } } +/** + * A helper function to test for email diversion + * + * @param string $email + * @return bool Returns true if the email should be diverted + */ +function email_should_be_diverted($email) { + global $CFG; + + if (empty($CFG->divertallemailsto)) { + return false; + } + + if (empty($CFG->divertallemailsexcept)) { + return true; + } + + $patterns = array_map('trim', explode(',', $CFG->divertallemailsexcept)); + foreach ($patterns as $pattern) { + if (preg_match("/$pattern/", $email)) { + return false; + } + } + + return true; +} + /** * Send an email to a specified user * @@ -5481,7 +5508,7 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '', return true; } - if (!empty($CFG->divertallemailsto)) { + if (email_should_be_diverted($user->email)) { $subject = "[DIVERTED {$user->email}] $subject"; $user = clone($user); $user->email = $CFG->divertallemailsto; diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 229e918186b..e337c76aa7c 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -2644,6 +2644,73 @@ class core_moodlelib_testcase extends advanced_testcase { $this->assertEventContextNotUsed($event); } + + public function diverted_emails_provider() { + return array( + 'nodiverts' => array( + 'divertallemailsto' => null, + 'divertallemailsexcept' => null, + array( + 'foo@example.com', + 'test@real.com', + 'fred.jones@example.com', + 'dev1@dev.com', + 'fred@example.com', + 'fred+verp@example.com', + ), + false, + ), + 'alldiverts' => array( + 'divertallemailsto' => 'somewhere@elsewhere.com', + 'divertallemailsexcept' => null, + array( + 'foo@example.com', + 'test@real.com', + 'fred.jones@example.com', + 'dev1@dev.com', + 'fred@example.com', + 'fred+verp@example.com', + ), + true, + ), + 'alsodiverts' => array( + 'divertallemailsto' => 'somewhere@elsewhere.com', + 'divertallemailsexcept' => '@dev.com, fred(\+.*)?@example.com', + array( + 'foo@example.com', + 'test@real.com', + 'fred.jones@example.com', + ), + true, + ), + 'divertsexceptions' => array( + 'divertallemailsto' => 'somewhere@elsewhere.com', + 'divertallemailsexcept' => '@dev.com, fred(\+.*)?@example.com', + array( + 'dev1@dev.com', + 'fred@example.com', + 'fred+verp@example.com', + ), + false, + ), + ); + } + + /** + * @dataProvider diverted_emails_provider + */ + public function test_email_should_be_diverted($divertallemailsto, $divertallemailsexcept, $addresses, $expected) { + global $CFG; + + $this->resetAfterTest(); + $CFG->divertallemailsto = $divertallemailsto; + $CFG->divertallemailsexcept = $divertallemailsexcept; + + foreach ($addresses as $address) { + $this->assertEquals($expected, email_should_be_diverted($address)); + } + } + public function test_email_to_user() { global $CFG;