Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / metamta / util / PhabricatorMailUtil.php
bloba5fbc7179e310af528ffc67bd023a8a1766f042f
1 <?php
3 final class PhabricatorMailUtil
4 extends Phobject {
6 /**
7 * Normalize an email address for comparison or lookup.
9 * Phabricator can be configured to prepend a prefix to all reply addresses,
10 * which can make forwarding rules easier to write. This method strips the
11 * prefix if it is present, and normalizes casing and whitespace.
13 * @param PhutilEmailAddress Email address.
14 * @return PhutilEmailAddress Normalized address.
16 public static function normalizeAddress(PhutilEmailAddress $address) {
17 $raw_address = $address->getAddress();
18 $raw_address = phutil_utf8_strtolower($raw_address);
19 $raw_address = trim($raw_address);
21 // If a mailbox prefix is configured and present, strip it off.
22 $prefix_key = 'metamta.single-reply-handler-prefix';
23 $prefix = PhabricatorEnv::getEnvConfig($prefix_key);
24 $len = strlen($prefix);
26 if ($len) {
27 $prefix = $prefix.'+';
28 $len = $len + 1;
30 if (!strncasecmp($raw_address, $prefix, $len)) {
31 $raw_address = substr($raw_address, $len);
35 return id(clone $address)
36 ->setAddress($raw_address);
39 /**
40 * Determine if two inbound email addresses are effectively identical.
42 * This method strips and normalizes addresses so that equivalent variations
43 * are correctly detected as identical. For example, these addresses are all
44 * considered to match one another:
46 * "Abraham Lincoln" <alincoln@example.com>
47 * alincoln@example.com
48 * <ALincoln@example.com>
49 * "Abraham" <phabricator+ALINCOLN@EXAMPLE.COM> # With configured prefix.
51 * @param PhutilEmailAddress Email address.
52 * @param PhutilEmailAddress Another email address.
53 * @return bool True if addresses are effectively the same address.
55 public static function matchAddresses(
56 PhutilEmailAddress $u,
57 PhutilEmailAddress $v) {
59 $u = self::normalizeAddress($u);
60 $v = self::normalizeAddress($v);
62 return ($u->getAddress() === $v->getAddress());
65 public static function isReservedAddress(PhutilEmailAddress $address) {
66 $address = self::normalizeAddress($address);
67 $local = $address->getLocalPart();
69 $reserved = array(
70 'admin',
71 'administrator',
72 'hostmaster',
73 'list',
74 'list-request',
75 'majordomo',
76 'postmaster',
77 'root',
78 'ssl-admin',
79 'ssladmin',
80 'ssladministrator',
81 'sslwebmaster',
82 'sysadmin',
83 'uucp',
84 'webmaster',
86 'noreply',
87 'no-reply',
90 $reserved = array_fuse($reserved);
92 if (isset($reserved[$local])) {
93 return true;
96 $default_address = id(new PhabricatorMailEmailEngine())
97 ->newDefaultEmailAddress();
98 if (self::matchAddresses($address, $default_address)) {
99 return true;
102 $void_address = id(new PhabricatorMailEmailEngine())
103 ->newVoidEmailAddress();
104 if (self::matchAddresses($address, $void_address)) {
105 return true;
108 return false;
111 public static function isUserAddress(PhutilEmailAddress $address) {
112 $user_email = id(new PhabricatorUserEmail())->loadOneWhere(
113 'address = %s',
114 $address->getAddress());
116 return (bool)$user_email;