From 3448781c40f0e45a4e7e19ab9f1e601df8485b13 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Fri, 04 Jan 2013 01:04:30 +0000 Subject: [PATCH] de-duplicate emails received by phabricator multiple times Summary: this can happen if you have Phabricator and email lists co-mingling such that Phabricator receives an email multiple times. we can prevent this from then spamming everyone or otherwise taking the action multiple times by storing a message id hash and dropping the message if we have more than one message that matches. Test Plan: simulated sending the same email multiple times on the command line. noted only the first one made it through. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T1726 Differential Revision: https://secure.phabricator.com/D4328 --- scripts/mail/mail_handler.php | 3 +++ resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql | 3 +++ src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php | 22 ++++++++++++++++++++++ src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php | 5 +++++ 4 file(s) changed, 33 insertion(s)(+), 0 deletion(s)(-) diff --git a/scripts/mail/mail_handler.php b/scripts/mail/mail_handler.php --- a/scripts/mail/mail_handler.php +++ b/scripts/mail/mail_handler.php @@ -34,6 +34,9 @@ 'text' => $text_body, 'html' => $parser->getMessageBody('html'), )); +$received->setMessageIDHash( + PhabricatorHash::digestForIndex($received->getMessageID()) +); $attachments = array(); foreach ($parser->getAttachments() as $attachment) { diff --git a/resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql b/resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql new file mode 100644 --- /dev/null +++ b/resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql @@ -0,0 +1,3 @@ +ALTER TABLE `{$NAMESPACE}_metamta`.`metamta_receivedmail` + ADD `messageIDHash` CHAR(12) BINARY NOT NULL, + ADD KEY `key_messageIDHash` (`messageIDHash`); diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php --- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php @@ -9,6 +9,7 @@ protected $relatedPHID; protected $authorPHID; protected $message; + protected $messageIDHash; public function getConfiguration() { return array( @@ -143,6 +144,27 @@ $message = "Ignoring email with 'X-Phabricator-Sent-This-Message' ". "header to avoid loops."; return $this->setMessage($message)->save(); + } + + $message_id_hash = $this->getMessageIDHash(); + if ($message_id_hash) { + $messages = $this->loadAllWhere( + 'messageIDHash = %s', + $message_id_hash + ); + $messages_count = count($messages); + if ($messages_count > 1) { + $first_message = reset($messages); + if ($first_message->getID() != $this->getID()) { + $message = sprintf( + 'Ignoring email with message id hash "%s" that has been seen %d '. + 'times, including this message.', + $message_id_hash, + $messages_count + ); + return $this->setMessage($message)->save(); + } + } } list($to, diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1076,6 +1076,11 @@ 'type' => 'sql', 'name' => $this->getPatchPath('20130101.confxaction.sql'), ), + '20130102.metamtareceivedmailmessageidhash.sql' => array( + 'type' => 'sql', + 'name' => + $this->getPatchPath('20130102.metamtareceivedmailmessageidhash.sql'), + ), ); } -- tangled.sh