3 final class PhabricatorMailManagementReceiveTestWorkflow
4 extends PhabricatorMailManagementWorkflow
{
6 protected function didConstruct() {
8 ->setName('receive-test')
11 'Simulate receiving mail. This is primarily useful if you are '.
12 'developing new mail receivers.'))
14 '**receive-test** --as alincoln --to D123 < body.txt')
20 'help' => pht('Act as the specified user.'),
25 'help' => pht('Simulate mail delivery "From:" the given user.'),
30 'help' => pht('Simulate mail delivery "To:" the given object.'),
35 'help' => pht('Simulate a mail delivery "Cc:" address.'),
41 public function execute(PhutilArgumentParser
$args) {
42 $viewer = $this->getViewer();
43 $console = PhutilConsole
::getConsole();
45 $to = $args->getArg('to');
47 throw new PhutilArgumentUsageException(
49 "Use '%s' to specify the receiving object or email address.",
53 $to_application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
54 ->setViewer($this->getViewer())
55 ->withAddresses(array($to))
58 $as = $args->getArg('as');
59 if (!$as && $to_application_email) {
60 $default_phid = $to_application_email->getConfigValue(
61 PhabricatorMetaMTAApplicationEmail
::CONFIG_DEFAULT_AUTHOR
);
63 $default_user = id(new PhabricatorPeopleQuery())
64 ->setViewer($this->getViewer())
65 ->withPHIDs(array($default_phid))
68 $as = $default_user->getUsername();
74 throw new PhutilArgumentUsageException(
75 pht("Use '--as' to specify the acting user."));
78 $user = id(new PhabricatorPeopleQuery())
79 ->setViewer($this->getViewer())
80 ->withUsernames(array($as))
83 throw new PhutilArgumentUsageException(
84 pht("No such user '%s' exists.", $as));
88 $from = $args->getArg('from');
90 $from = $user->loadPrimaryEmail()->getAddress();
93 $cc = $args->getArg('cc');
95 $console->writeErr("%s\n", pht('Reading message body from stdin...'));
96 $body = file_get_contents('php://stdin');
98 $received = new PhabricatorMetaMTAReceivedMail();
99 $header_content = array(
100 'Message-ID' => Filesystem
::readRandomCharacters(12),
102 'Cc' => implode(', ', $cc),
105 if (preg_match('/.+@.+/', $to)) {
106 $header_content['to'] = $to;
109 // We allow the user to use an object name instead of a real address
110 // as a convenience. To build the mail, we build a similar message and
111 // look for a receiver which will accept it.
113 // In the general case, mail may be processed by multiple receivers,
114 // but mail to objects only ever has one receiver today.
116 $pseudohash = PhabricatorObjectMailReceiver
::computeMailHash('x', 'y');
118 $raw_target = $to.'+1+'.$pseudohash;
119 $target = new PhutilEmailAddress($raw_target.'@local.cli');
121 $pseudomail = id(new PhabricatorMetaMTAReceivedMail())
127 $receivers = id(new PhutilClassMapQuery())
128 ->setAncestorClass('PhabricatorMailReceiver')
129 ->setFilterMethod('isEnabled')
133 foreach ($receivers as $possible_receiver) {
134 $possible_receiver = id(clone $possible_receiver)
138 if (!$possible_receiver->canAcceptMail($pseudomail, $target)) {
141 $receiver = $possible_receiver;
147 pht("No configured mail receiver can accept mail to '%s'.", $to));
150 if (!($receiver instanceof PhabricatorObjectMailReceiver
)) {
151 $class = get_class($receiver);
154 "Receiver '%s' accepts mail to '%s', but is not a ".
155 "subclass of PhabricatorObjectMailReceiver.",
160 $object = $receiver->loadMailReceiverObject($to, $user);
162 throw new Exception(pht("No such object '%s'!", $to));
165 $mail_key = PhabricatorMetaMTAMailProperties
::loadMailKey($object);
167 $hash = PhabricatorObjectMailReceiver
::computeMailHash(
171 $header_content['to'] = $to.'+'.$user->getID().'+'.$hash.'@test.com';
174 $received->setHeaders($header_content);
175 $received->setBodies(
181 $received->processReceivedMail();
184 "%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n",
185 pht('Mail received! You can view details by running this command:'),