Page MenuHomePhabricator

D19948.id47620.diff
No OneTemporary

D19948.id47620.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -3422,6 +3422,7 @@
'PhabricatorMailRoutingRule' => 'applications/metamta/constants/PhabricatorMailRoutingRule.php',
'PhabricatorMailStamp' => 'applications/metamta/stamp/PhabricatorMailStamp.php',
'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php',
+ 'PhabricatorMailUtil' => 'applications/metamta/util/PhabricatorMailUtil.php',
'PhabricatorMainMenuBarExtension' => 'view/page/menu/PhabricatorMainMenuBarExtension.php',
'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
@@ -9248,6 +9249,7 @@
'PhabricatorMailRoutingRule' => 'Phobject',
'PhabricatorMailStamp' => 'Phobject',
'PhabricatorMailTarget' => 'Phobject',
+ 'PhabricatorMailUtil' => 'Phobject',
'PhabricatorMainMenuBarExtension' => 'Phobject',
'PhabricatorMainMenuSearchView' => 'AphrontView',
'PhabricatorMainMenuView' => 'AphrontView',
diff --git a/src/applications/metamta/receiver/PhabricatorMailReceiver.php b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
--- a/src/applications/metamta/receiver/PhabricatorMailReceiver.php
+++ b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
@@ -25,10 +25,10 @@
->withApplicationPHIDs(array($app->getPHID()))
->execute();
- foreach ($mail->getToAddresses() as $to_address) {
+ foreach ($mail->newTargetAddresses() as $address) {
foreach ($application_emails as $application_email) {
- $create_address = $application_email->getAddress();
- if ($this->matchAddresses($create_address, $to_address)) {
+ $create_address = $application_email->newAddress();
+ if (PhabricatorMailUtil::matchAddresses($create_address, $address)) {
$this->setApplicationEmail($application_email);
return true;
}
@@ -194,66 +194,6 @@
$reasons);
}
- /**
- * Determine if two inbound email addresses are effectively identical. This
- * method strips and normalizes addresses so that equivalent variations are
- * correctly detected as identical. For example, these addresses are all
- * considered to match one another:
- *
- * "Abraham Lincoln" <alincoln@example.com>
- * alincoln@example.com
- * <ALincoln@example.com>
- * "Abraham" <phabricator+ALINCOLN@EXAMPLE.COM> # With configured prefix.
- *
- * @param string Email address.
- * @param string Another email address.
- * @return bool True if addresses match.
- */
- public static function matchAddresses($u, $v) {
- $u = self::getRawAddress($u);
- $v = self::getRawAddress($v);
-
- $u = self::stripMailboxPrefix($u);
- $v = self::stripMailboxPrefix($v);
-
- return ($u === $v);
- }
-
-
- /**
- * Strip a global mailbox prefix from an address if it is present. Phabricator
- * can be configured to prepend a prefix to all reply addresses, which can
- * make forwarding rules easier to write. A prefix looks like:
- *
- * example@phabricator.example.com # No Prefix
- * phabricator+example@phabricator.example.com # Prefix "phabricator"
- *
- * @param string Email address, possibly with a mailbox prefix.
- * @return string Email address with any prefix stripped.
- */
- public static function stripMailboxPrefix($address) {
- $address = id(new PhutilEmailAddress($address))->getAddress();
-
- $prefix_key = 'metamta.single-reply-handler-prefix';
- $prefix = PhabricatorEnv::getEnvConfig($prefix_key);
-
- $len = strlen($prefix);
-
- if ($len) {
- $prefix = $prefix.'+';
- $len = $len + 1;
- }
-
- if ($len) {
- if (!strncasecmp($address, $prefix, $len)) {
- $address = substr($address, strlen($prefix));
- }
- }
-
- return $address;
- }
-
-
/**
* Reduce an email address to its canonical form. For example, an address
* like:
diff --git a/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php b/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php
--- a/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php
+++ b/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php
@@ -150,7 +150,7 @@
private function matchObjectAddressInMail(
PhabricatorMetaMTAReceivedMail $mail) {
- foreach ($mail->getToAddresses() as $address) {
+ foreach ($mail->newTargetAddresses() as $address) {
$parts = $this->matchObjectAddress($address);
if ($parts) {
return $parts;
@@ -160,12 +160,11 @@
return null;
}
- private function matchObjectAddress($address) {
- $regexp = $this->getAddressRegexp();
-
- $address = self::stripMailboxPrefix($address);
- $local = id(new PhutilEmailAddress($address))->getLocalPart();
+ private function matchObjectAddress(PhutilEmailAddress $address) {
+ $address = PhabricatorMailUtil::normalizeAddress($address);
+ $local = $address->getLocalPart();
+ $regexp = $this->getAddressRegexp();
$matches = null;
if (!preg_match($regexp, $local, $matches)) {
return false;
diff --git a/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php b/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
--- a/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
+++ b/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
@@ -17,7 +17,9 @@
foreach ($same as $address) {
$this->assertTrue(
- PhabricatorMailReceiver::matchAddresses($base, $address),
+ PhabricatorMailUtil::matchAddresses(
+ new PhutilEmailAddress($base),
+ new PhutilEmailAddress($address)),
pht('Address %s', $address));
}
@@ -32,7 +34,9 @@
foreach ($diff as $address) {
$this->assertFalse(
- PhabricatorMailReceiver::matchAddresses($base, $address),
+ PhabricatorMailUtil::matchAddresses(
+ new PhutilEmailAddress($base),
+ new PhutilEmailAddress($address)),
pht('Address: %s', $address));
}
}
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php
@@ -88,6 +88,10 @@
return $message;
}
+ public function newAddress() {
+ return new PhutilEmailAddress($this->getAddress());
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
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
@@ -82,6 +82,27 @@
return $this->getRawEmailAddresses(idx($this->headers, 'to'));
}
+ public function newTargetAddresses() {
+ $raw_addresses = array();
+
+ foreach ($this->getToAddresses() as $raw_address) {
+ $raw_addresses[] = $raw_address;
+ }
+
+ foreach ($this->getCCAddresses() as $raw_address) {
+ $raw_addresses[] = $raw_address;
+ }
+
+ $raw_addresses = array_unique($raw_addresses);
+
+ $addresses = array();
+ foreach ($raw_addresses as $raw_address) {
+ $addresses[] = new PhutilEmailAddress($raw_address);
+ }
+
+ return $addresses;
+ }
+
public function loadAllRecipientPHIDs() {
$addresses = array_merge(
$this->getToAddresses(),
diff --git a/src/applications/metamta/util/PhabricatorMailUtil.php b/src/applications/metamta/util/PhabricatorMailUtil.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/util/PhabricatorMailUtil.php
@@ -0,0 +1,65 @@
+<?php
+
+final class PhabricatorMailUtil
+ extends Phobject {
+
+ /**
+ * Normalize an email address for comparison or lookup.
+ *
+ * Phabricator can be configured to prepend a prefix to all reply addresses,
+ * which can make forwarding rules easier to write. This method strips the
+ * prefix if it is present, and normalizes casing and whitespace.
+ *
+ * @param PhutilEmailAddress Email address.
+ * @return PhutilEmailAddress Normalized address.
+ */
+ public static function normalizeAddress(PhutilEmailAddress $address) {
+ $raw_address = $address->getAddress();
+ $raw_address = phutil_utf8_strtolower($raw_address);
+ $raw_address = trim($raw_address);
+
+ // If a mailbox prefix is configured and present, strip it off.
+ $prefix_key = 'metamta.single-reply-handler-prefix';
+ $prefix = PhabricatorEnv::getEnvConfig($prefix_key);
+ $len = strlen($prefix);
+
+ if ($len) {
+ $prefix = $prefix.'+';
+ $len = $len + 1;
+
+ if (!strncasecmp($raw_address, $prefix, $len)) {
+ $raw_address = substr($raw_address, $len);
+ }
+ }
+
+ return id(clone $address)
+ ->setAddress($raw_address);
+ }
+
+ /**
+ * Determine if two inbound email addresses are effectively identical.
+ *
+ * This method strips and normalizes addresses so that equivalent variations
+ * are correctly detected as identical. For example, these addresses are all
+ * considered to match one another:
+ *
+ * "Abraham Lincoln" <alincoln@example.com>
+ * alincoln@example.com
+ * <ALincoln@example.com>
+ * "Abraham" <phabricator+ALINCOLN@EXAMPLE.COM> # With configured prefix.
+ *
+ * @param PhutilEmailAddress Email address.
+ * @param PhutilEmailAddress Another email address.
+ * @return bool True if addresses are effectively the same address.
+ */
+ public static function matchAddresses(
+ PhutilEmailAddress $u,
+ PhutilEmailAddress $v) {
+
+ $u = self::normalizeAddress($u);
+ $v = self::normalizeAddress($v);
+
+ return ($u->getAddress() === $v->getAddress());
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 2:57 AM (6 d, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7648126
Default Alt Text
D19948.id47620.diff (9 KB)

Event Timeline