diff --git a/resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql b/resources/sql/patches/20130102.metamtareceivedmailmessageidhash.sql new file mode 100644 index 0000000000..3a1198370d --- /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/scripts/mail/mail_handler.php b/scripts/mail/mail_handler.php index 19e315364d..409b25081d 100755 --- a/scripts/mail/mail_handler.php +++ b/scripts/mail/mail_handler.php @@ -34,6 +34,9 @@ $received->setBodies(array( 'text' => $text_body, 'html' => $parser->getMessageBody('html'), )); +$received->setMessageIDHash( + PhabricatorHash::digestForIndex($received->getMessageID()) +); $attachments = array(); foreach ($parser->getAttachments() as $attachment) { diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php index 1c5d300ba3..6ee4df4a76 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php @@ -9,6 +9,7 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO { protected $relatedPHID; protected $authorPHID; protected $message; + protected $messageIDHash; public function getConfiguration() { return array( @@ -145,6 +146,27 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO { 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, $receiver_name, $user_id, diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index cc909fc4b1..98f4b9b2cf 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1076,6 +1076,11 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'type' => 'sql', 'name' => $this->getPatchPath('20130101.confxaction.sql'), ), + '20130102.metamtareceivedmailmessageidhash.sql' => array( + 'type' => 'sql', + 'name' => + $this->getPatchPath('20130102.metamtareceivedmailmessageidhash.sql'), + ), ); }