mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-03 02:18:24 +01:00
Move mail "Receive Test" from web UI to CLI
Summary: Ref T3306. Moves this from the web to the CLI, which is a tiny bit clunkier but way better as far as policies go and more repeatable for development. See discussion in D6413. Test Plan: Ran `bin/mail receive-test`, verified mail was received. Used and abused various options. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3306 Differential Revision: https://secure.phabricator.com/D6417
This commit is contained in:
parent
70fd3dd54f
commit
7fa2343822
6 changed files with 146 additions and 146 deletions
|
@ -19,6 +19,7 @@ $workflows = array(
|
|||
new PhutilHelpArgumentWorkflow(),
|
||||
new PhabricatorMailManagementShowOutboundWorkflow(),
|
||||
new PhabricatorMailManagementShowInboundWorkflow(),
|
||||
new PhabricatorMailManagementReceiveTestWorkflow(),
|
||||
);
|
||||
|
||||
$args->parseWorkflows($workflows);
|
||||
|
|
|
@ -1211,6 +1211,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
|
||||
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
|
||||
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
|
||||
'PhabricatorMailManagementReceiveTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php',
|
||||
'PhabricatorMailManagementResendWorkflow' => 'applications/metamta/management/PhabricatorMailManagementResendWorkflow.php',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
|
||||
|
@ -1244,7 +1245,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
|
||||
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
|
||||
'PhabricatorMetaMTAMailingList' => 'applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php',
|
||||
'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTAReceiveController.php',
|
||||
'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/PhabricatorMetaMTAReceivedListController.php',
|
||||
'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php',
|
||||
'PhabricatorMetaMTAReceivedMailProcessingException' => 'applications/metamta/exception/PhabricatorMetaMTAReceivedMailProcessingException.php',
|
||||
|
@ -3166,6 +3166,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMailManagementReceiveTestWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorMailManagementResendWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
|
@ -3191,7 +3192,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
|
||||
'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
|
||||
'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
|
||||
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
|
||||
'PhabricatorMetaMTAReceivedMailProcessingException' => 'Exception',
|
||||
|
|
|
@ -32,7 +32,6 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
|
|||
'' => 'PhabricatorMetaMTAListController',
|
||||
'send/' => 'PhabricatorMetaMTASendController',
|
||||
'view/(?P<id>[1-9]\d*)/' => 'PhabricatorMetaMTAViewController',
|
||||
'receive/' => 'PhabricatorMetaMTAReceiveController',
|
||||
'received/' => 'PhabricatorMetaMTAReceivedListController',
|
||||
'sendgrid/' => 'PhabricatorMetaMTASendGridReceiveController',
|
||||
),
|
||||
|
|
|
@ -17,7 +17,6 @@ abstract class PhabricatorMetaMTAController extends PhabricatorController {
|
|||
if ($this->getRequest()->getUser()->getIsAdmin()) {
|
||||
$nav->addLabel(pht('Diagnostics'));
|
||||
$nav->addFilter('send', pht('Send Test'));
|
||||
$nav->addFilter('receive', pht('Receive Test'));
|
||||
}
|
||||
|
||||
return $nav;
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorMetaMTAReceiveController
|
||||
extends PhabricatorMetaMTAController {
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$received = new PhabricatorMetaMTAReceivedMail();
|
||||
$header_content = array(
|
||||
'Message-ID' => Filesystem::readRandomCharacters(12),
|
||||
);
|
||||
$from = $request->getStr('sender');
|
||||
$to = $request->getStr('receiver');
|
||||
$uri = '/mail/received/';
|
||||
|
||||
if (!empty($from)) {
|
||||
$header_content['from'] = $from;
|
||||
} else {
|
||||
// If the user doesn't provide a "From" address, use their primary
|
||||
// address.
|
||||
$header_content['from'] = $user->loadPrimaryEmail()->getAddress();
|
||||
}
|
||||
|
||||
if (preg_match('/.+@.+/', $to)) {
|
||||
$header_content['to'] = $to;
|
||||
} else {
|
||||
|
||||
// We allow the user to use an object name instead of a real address
|
||||
// as a convenience. To build the mail, we build a similar message and
|
||||
// look for a receiver which will accept it.
|
||||
$pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
|
||||
$pseudomail = id(new PhabricatorMetaMTAReceivedMail())
|
||||
->setHeaders(
|
||||
array(
|
||||
'to' => $to.'+1+'.$pseudohash,
|
||||
));
|
||||
|
||||
$receivers = id(new PhutilSymbolLoader())
|
||||
->setAncestorClass('PhabricatorMailReceiver')
|
||||
->loadObjects();
|
||||
|
||||
$receiver = null;
|
||||
foreach ($receivers as $possible_receiver) {
|
||||
if (!$possible_receiver->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
if (!$possible_receiver->canAcceptMail($pseudomail)) {
|
||||
continue;
|
||||
}
|
||||
$receiver = $possible_receiver;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$receiver) {
|
||||
throw new Exception(
|
||||
"No configured mail receiver can accept mail to '{$to}'.");
|
||||
}
|
||||
|
||||
if (!($receiver instanceof PhabricatorObjectMailReceiver)) {
|
||||
$class = get_class($receiver);
|
||||
throw new Exception(
|
||||
"Receiver '{$class}' accepts mail to '{$to}', but is not a ".
|
||||
"subclass of PhabricatorObjectMailReceiver.");
|
||||
}
|
||||
|
||||
$object = $receiver->loadMailReceiverObject($to, $user);
|
||||
if (!$object) {
|
||||
throw new Exception("No such object '{$to}'!");
|
||||
}
|
||||
|
||||
$hash = PhabricatorObjectMailReceiver::computeMailHash(
|
||||
$object->getMailKey(),
|
||||
$user->getPHID());
|
||||
|
||||
$header_content['to'] = $to.'+'.$user->getID().'+'.$hash.'@test.com';
|
||||
}
|
||||
|
||||
$received->setHeaders($header_content);
|
||||
$received->setBodies(
|
||||
array(
|
||||
'text' => $request->getStr('body'),
|
||||
));
|
||||
|
||||
$received->save();
|
||||
|
||||
$received->processReceivedMail();
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form->setUser($request->getUser());
|
||||
$form->setAction($this->getApplicationURI('/receive/'));
|
||||
$form
|
||||
->appendChild(hsprintf(
|
||||
'<p class="aphront-form-instructions">%s</p>',
|
||||
pht(
|
||||
'This form will simulate sending mail to an object '.
|
||||
'or an email address.')))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('From'))
|
||||
->setName('sender'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('To'))
|
||||
->setName('receiver')
|
||||
->setCaption(pht(
|
||||
'e.g. %s or %s',
|
||||
phutil_tag('tt', array(), 'D1234'),
|
||||
phutil_tag('tt', array(), 'bugs@example.com'))))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel(pht('Body'))
|
||||
->setName('body'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Receive Mail')));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setHeader(pht('Receive Email'));
|
||||
$panel->appendChild($form);
|
||||
$panel->setNoBackground();
|
||||
|
||||
$nav = $this->buildSideNavView();
|
||||
$nav->selectFilter('receive');
|
||||
$nav->appendChild($panel);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => pht('Receive Test'),
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorMailManagementReceiveTestWorkflow
|
||||
extends PhabricatorSearchManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('receive-test')
|
||||
->setSynopsis(
|
||||
pht(
|
||||
'Simulate receiving mail. This is primarily useful if you are '.
|
||||
'developing new mail receivers.'))
|
||||
->setExamples(
|
||||
"**receive-test** --as alincoln --to D123 < body.txt")
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'as',
|
||||
'param' => 'user',
|
||||
'help' => 'Act as the specified user.',
|
||||
),
|
||||
array(
|
||||
'name' => 'from',
|
||||
'param' => 'email',
|
||||
'help' => 'Simulate mail delivery "From:" the given user.',
|
||||
),
|
||||
array(
|
||||
'name' => 'to',
|
||||
'param' => 'object',
|
||||
'help' => 'Simulate mail delivery "To:" the given object.',
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
|
||||
$as = $args->getArg('as');
|
||||
if (!$as) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht("Use '--as' to specify the acting user."));
|
||||
}
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withUsernames(array($as))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht("No such user '%s' exists.", $as));
|
||||
}
|
||||
|
||||
$to = $args->getArg('to');
|
||||
if (!$to) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
"Use '--to' to specify the receiving object or email address.");
|
||||
}
|
||||
|
||||
$from = $args->getArg('from');
|
||||
if (!$from) {
|
||||
$from = $user->loadPrimaryEmail()->getAddress();
|
||||
}
|
||||
|
||||
$console->writeErr("%s\n", pht('Reading message body from stdin...'));
|
||||
$body = file_get_contents('php://stdin');
|
||||
|
||||
$received = new PhabricatorMetaMTAReceivedMail();
|
||||
$header_content = array(
|
||||
'Message-ID' => Filesystem::readRandomCharacters(12),
|
||||
'From' => $from,
|
||||
);
|
||||
|
||||
if (preg_match('/.+@.+/', $to)) {
|
||||
$header_content['to'] = $to;
|
||||
} else {
|
||||
// We allow the user to use an object name instead of a real address
|
||||
// as a convenience. To build the mail, we build a similar message and
|
||||
// look for a receiver which will accept it.
|
||||
$pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
|
||||
$pseudomail = id(new PhabricatorMetaMTAReceivedMail())
|
||||
->setHeaders(
|
||||
array(
|
||||
'to' => $to.'+1+'.$pseudohash,
|
||||
));
|
||||
|
||||
$receivers = id(new PhutilSymbolLoader())
|
||||
->setAncestorClass('PhabricatorMailReceiver')
|
||||
->loadObjects();
|
||||
|
||||
$receiver = null;
|
||||
foreach ($receivers as $possible_receiver) {
|
||||
if (!$possible_receiver->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
if (!$possible_receiver->canAcceptMail($pseudomail)) {
|
||||
continue;
|
||||
}
|
||||
$receiver = $possible_receiver;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$receiver) {
|
||||
throw new Exception(
|
||||
pht("No configured mail receiver can accept mail to '%s'.", $to));
|
||||
}
|
||||
|
||||
if (!($receiver instanceof PhabricatorObjectMailReceiver)) {
|
||||
$class = get_class($receiver);
|
||||
throw new Exception(
|
||||
"Receiver '%s' accepts mail to '%s', but is not a ".
|
||||
"subclass of PhabricatorObjectMailReceiver.",
|
||||
$class,
|
||||
$to);
|
||||
}
|
||||
|
||||
$object = $receiver->loadMailReceiverObject($to, $user);
|
||||
if (!$object) {
|
||||
throw new Exception(pht("No such object '%s'!", $to));
|
||||
}
|
||||
|
||||
$hash = PhabricatorObjectMailReceiver::computeMailHash(
|
||||
$object->getMailKey(),
|
||||
$user->getPHID());
|
||||
|
||||
$header_content['to'] = $to.'+'.$user->getID().'+'.$hash.'@test.com';
|
||||
}
|
||||
|
||||
$received->setHeaders($header_content);
|
||||
$received->setBodies(
|
||||
array(
|
||||
'text' => $body,
|
||||
));
|
||||
|
||||
$received->save();
|
||||
$received->processReceivedMail();
|
||||
|
||||
$console->writeErr(
|
||||
"%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n",
|
||||
pht("Mail received! You can view details by running this command:"),
|
||||
$received->getID());
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue