diff --git a/scripts/mail/manage_mail.php b/scripts/mail/manage_mail.php index 4b87a38fca..a64ce6dbec 100755 --- a/scripts/mail/manage_mail.php +++ b/scripts/mail/manage_mail.php @@ -19,6 +19,7 @@ $workflows = array( new PhutilHelpArgumentWorkflow(), new PhabricatorMailManagementShowOutboundWorkflow(), new PhabricatorMailManagementShowInboundWorkflow(), + new PhabricatorMailManagementSendTestWorkflow(), new PhabricatorMailManagementReceiveTestWorkflow(), ); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e1bd968d3b..fccee3c83c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1213,6 +1213,7 @@ phutil_register_library_map(array( 'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php', 'PhabricatorMailManagementReceiveTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php', 'PhabricatorMailManagementResendWorkflow' => 'applications/metamta/management/PhabricatorMailManagementResendWorkflow.php', + 'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php', 'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php', 'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php', 'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php', @@ -1251,7 +1252,6 @@ phutil_register_library_map(array( 'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php', 'PhabricatorMetaMTAReceivedMailProcessingException' => 'applications/metamta/exception/PhabricatorMetaMTAReceivedMailProcessingException.php', 'PhabricatorMetaMTAReceivedMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAReceivedMailTestCase.php', - 'PhabricatorMetaMTASendController' => 'applications/metamta/controller/PhabricatorMetaMTASendController.php', 'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php', 'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/PhabricatorMetaMTAViewController.php', 'PhabricatorMetaMTAWorker' => 'applications/metamta/PhabricatorMetaMTAWorker.php', @@ -3170,6 +3170,7 @@ phutil_register_library_map(array( 'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMailManagementReceiveTestWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorMailManagementResendWorkflow' => 'PhabricatorSearchManagementWorkflow', + 'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorSearchManagementWorkflow', 'PhabricatorMailManagementWorkflow' => 'PhutilArgumentWorkflow', @@ -3199,7 +3200,6 @@ phutil_register_library_map(array( 'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAReceivedMailProcessingException' => 'Exception', 'PhabricatorMetaMTAReceivedMailTestCase' => 'PhabricatorTestCase', - 'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAWorker' => 'PhabricatorWorker', diff --git a/src/applications/metamta/application/PhabricatorApplicationMetaMTA.php b/src/applications/metamta/application/PhabricatorApplicationMetaMTA.php index 17beb4f606..4e114a1acc 100644 --- a/src/applications/metamta/application/PhabricatorApplicationMetaMTA.php +++ b/src/applications/metamta/application/PhabricatorApplicationMetaMTA.php @@ -30,7 +30,6 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication { return array( $this->getBaseURI() => array( '' => 'PhabricatorMetaMTAListController', - 'send/' => 'PhabricatorMetaMTASendController', 'view/(?P[1-9]\d*)/' => 'PhabricatorMetaMTAViewController', 'received/' => 'PhabricatorMetaMTAReceivedListController', 'sendgrid/' => 'PhabricatorMetaMTASendGridReceiveController', diff --git a/src/applications/metamta/controller/PhabricatorMetaMTAController.php b/src/applications/metamta/controller/PhabricatorMetaMTAController.php index 18b84f75a8..ac3d174bf1 100644 --- a/src/applications/metamta/controller/PhabricatorMetaMTAController.php +++ b/src/applications/metamta/controller/PhabricatorMetaMTAController.php @@ -14,11 +14,6 @@ abstract class PhabricatorMetaMTAController extends PhabricatorController { $nav->addFilter('sent', pht('Sent Mail'), $this->getApplicationURI()); $nav->addFilter('received', pht('Received Mail')); - if ($this->getRequest()->getUser()->getIsAdmin()) { - $nav->addLabel(pht('Diagnostics')); - $nav->addFilter('send', pht('Send Test')); - } - return $nav; } diff --git a/src/applications/metamta/controller/PhabricatorMetaMTASendController.php b/src/applications/metamta/controller/PhabricatorMetaMTASendController.php deleted file mode 100644 index 2008b0ffe3..0000000000 --- a/src/applications/metamta/controller/PhabricatorMetaMTASendController.php +++ /dev/null @@ -1,185 +0,0 @@ -getRequest(); - - if ($request->isFormPost()) { - - $mail = new PhabricatorMetaMTAMail(); - $mail->addTos($request->getArr('to')); - $mail->addCCs($request->getArr('cc')); - $mail->setSubject($request->getStr('subject')); - $mail->setBody($request->getStr('body')); - - $files = $request->getArr('files'); - if ($files) { - foreach ($files as $phid) { - $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $phid); - $mail->addAttachment(new PhabricatorMetaMTAAttachment( - $file->loadFileData(), - $file->getName(), - $file->getMimeType() - )); - } - } - - $mail->setFrom($request->getUser()->getPHID()); - $mail->setSimulatedFailureCount($request->getInt('failures')); - $mail->setIsHTML($request->getInt('html')); - $mail->setIsBulk($request->getInt('bulk')); - $mail->setMailTags($request->getStrList('mailtags')); - $mail->setOverrideNoSelfMailPreference(true); - $mail->save(); - if ($request->getInt('immediately')) { - $mail->sendNow(); - } - - return id(new AphrontRedirectResponse()) - ->setURI($this->getApplicationURI('/view/'.$mail->getID().'/')); - } - - $failure_caption = - pht("Enter a number to simulate that many consecutive send failures ". - "brefore really attempting to deliver via the underlying MTA."); - - $doclink_href = PhabricatorEnv::getDoclink( - 'article/Configuring_Outbound_Email.html'); - - $doclink = phutil_tag( - 'a', - array( - 'href' => $doclink_href, - 'target' => '_blank', - ), - pht('Configuring Outbound Email')); - $instructions = hsprintf( - '

%s

', - pht( - 'This form will send a normal email using the settings you have '. - 'configured for Phabricator. For more information, see %s.', - $doclink)); - - $adapter = PhabricatorEnv::getEnvConfig('metamta.mail-adapter'); - $warning = null; - if ($adapter == 'PhabricatorMailImplementationTestAdapter') { - $warning = new AphrontErrorView(); - $warning->setTitle('Email is Disabled'); - $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING); - $warning->appendChild(phutil_tag( - 'p', - array(), - pht( - 'This installation of Phabricator is currently set to use %s to '. - 'deliver outbound email. This completely disables outbound email! '. - 'All outbound email will be thrown in a deep, dark hole until you '. - 'configure a real adapter.', - phutil_tag( - 'tt', - array(), - 'PhabricatorMailImplementationTestAdapter')))); - } - - $phdlink_href = PhabricatorEnv::getDoclink( - 'article/Managing_Daemons_with_phd.html'); - - $phdlink = phutil_tag( - 'a', - array( - 'href' => $phdlink_href, - 'target' => '_blank', - ), - '"phd start"'); - - $form = new AphrontFormView(); - $form->setUser($request->getUser()); - $form - ->appendChild($instructions) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Adapter')) - ->setValue($adapter)) - ->appendChild( - id(new AphrontFormTokenizerControl()) - ->setLabel(pht('To')) - ->setName('to') - ->setDatasource('/typeahead/common/mailable/')) - ->appendChild( - id(new AphrontFormTokenizerControl()) - ->setLabel(pht('CC')) - ->setName('cc') - ->setDatasource('/typeahead/common/mailable/')) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Subject')) - ->setName('subject')) - ->appendChild( - id(new AphrontFormTextAreaControl()) - ->setLabel(pht('Body')) - ->setName('body')) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Mail Tags')) - ->setName('mailtags') - ->setCaption(pht( - 'Example: %s', - phutil_tag( - 'tt', - array(), - 'differential-cc, differential-comment')))) - ->appendChild( - id(new AphrontFormDragAndDropUploadControl()) - ->setLabel(pht('Attach Files')) - ->setName('files') - ->setActivatedClass('aphront-panel-view-drag-and-drop')) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Simulate Failures')) - ->setName('failures') - ->setCaption($failure_caption)) - ->appendChild( - id(new AphrontFormCheckboxControl()) - ->setLabel(pht('HTML')) - ->addCheckbox('html', '1', 'Send as HTML email.')) - ->appendChild( - id(new AphrontFormCheckboxControl()) - ->setLabel(pht('Bulk')) - ->addCheckbox('bulk', '1', 'Send with bulk email headers.')) - ->appendChild( - id(new AphrontFormCheckboxControl()) - ->setLabel('Send Now') - ->addCheckbox( - 'immediately', - '1', - pht('Send immediately. (Do not enqueue for daemons.)'), - PhabricatorEnv::getEnvConfig('metamta.send-immediately')) - ->setCaption(pht('Daemons can be started with %s.', $phdlink))) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Send Mail'))); - - $panel = new AphrontPanelView(); - $panel->setHeader(pht('Send Email')); - $panel->appendChild($form); - $panel->setNoBackground(); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('send'); - $nav->appendChild( - array( - $warning, - $panel, - )); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => pht('Send Test'), - 'device' => true, - )); - } - -} diff --git a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php new file mode 100644 index 0000000000..a61a785e33 --- /dev/null +++ b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php @@ -0,0 +1,138 @@ +setName('send-test') + ->setSynopsis( + pht( + 'Simulate sending mail. This may be useful to test your mail '. + 'configuration, or while developing new mail adapters.')) + ->setExamples( + "**send-test** --to alincoln --subject hi < body.txt") + ->setArguments( + array( + array( + 'name' => 'from', + 'param' => 'user', + 'help' => 'Send mail from the specified user.', + ), + array( + 'name' => 'to', + 'param' => 'user', + 'help' => 'Send mail "To:" the specified users.', + 'repeat' => true, + ), + array( + 'name' => 'cc', + 'param' => 'user', + 'help' => 'Send mail which "Cc:"s the specified users.', + 'repeat' => true, + ), + array( + 'name' => 'subject', + 'param' => 'text', + 'help' => 'Use the provided subject.', + ), + array( + 'name' => 'tag', + 'param' => 'text', + 'help' => 'Add the given mail tags.', + 'repeat' => true, + ), + array( + 'name' => 'attach', + 'param' => 'file', + 'help' => 'Attach a file.', + 'repeat' => true, + ), + array( + 'name' => 'html', + 'help' => 'Send as HTML mail.', + ), + array( + 'name' => 'bulk', + 'help' => 'Send with bulk headers.', + ), + )); + } + + public function execute(PhutilArgumentParser $args) { + $console = PhutilConsole::getConsole(); + $viewer = PhabricatorUser::getOmnipotentUser(); + + $from = $args->getArg('from'); + if ($from) { + $user = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withUsernames(array($from)) + ->executeOne(); + if (!$user) { + throw new PhutilArgumentUsageException( + pht("No such user '%s' exists.", $from)); + } + $from = $user; + } + + $tos = $args->getArg('to'); + $ccs = $args->getArg('cc'); + + $names = array_merge($tos, $ccs); + $users = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withUsernames($names) + ->execute(); + $users = mpull($users, null, 'getUsername'); + + foreach ($tos as $key => $username) { + if (empty($users[$username])) { + throw new PhutilArgumentUsageException( + pht("No such user '%s' exists.", $username)); + } + $tos[$key] = $users[$username]->getPHID(); + } + + foreach ($ccs as $key => $username) { + if (empty($users[$username])) { + throw new PhutilArgumentUsageException( + pht("No such user '%s' exists.", $username)); + } + $ccs[$key] = $users[$username]->getPHID(); + } + + $subject = $args->getArg('subject'); + $tags = $args->getArg('tag'); + $attach = $args->getArg('attach'); + $is_html = $args->getArg('html'); + $is_bulk = $args->getArg('bulk'); + + $console->writeErr("%s\n", pht('Reading message body from stdin...')); + $body = file_get_contents('php://stdin'); + + + $mail = id(new PhabricatorMetaMTAMail()) + ->addTos($tos) + ->addCCs($ccs) + ->setSubject($subject) + ->setBody($body) + ->setOverrideNoSelfMailPreference(true) + ->setIsHTML($is_html) + ->setIsBulk($is_bulk) + ->setMailTags($tags); + + if ($from) { + $mail->setFrom($from->getPHID()); + } + + $mail->save(); + $mail->sendNow(); + + $console->writeErr( + "%s\n\n phabricator/ $ ./bin/mail show-outbound --id %d\n\n", + pht("Mail sent! You can view details by running this command:"), + $mail->getID()); + } + +}