MetaMTA - update documentation and make config a tad easier

Summary: Fixes T7088. Mainly this updates the documentation but I also snuck in tweaking how the domain reply handler is built. This does two main things -- makes the behavior consistent as some applications who didn't override this behavior would send out emails with reply tos AND makes it easier for us to deprecate the custom domain thing on a per application basis, which is just silly. On that note, the main documentation doesn't get into how this can be overridden, though I left in that mini blurb on the config setting itself. We could deprecate this harder and LOCK things if you want as well.

Test Plan: read docs, looked good. reasoned through re-factor

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T7088

Differential Revision: https://secure.phabricator.com/D11725
This commit is contained in:
Bob Trahan
2015-02-12 11:05:39 -08:00
parent 1e94320371
commit d598edc5f3
14 changed files with 70 additions and 45 deletions

View File

@@ -18,7 +18,7 @@ final class PhabricatorAuditReplyHandler extends PhabricatorMailReplyHandler {
} }
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return $this->getCustomReplyHandlerDomainIfExists(
'metamta.diffusion.reply-handler-domain'); 'metamta.diffusion.reply-handler-domain');
} }

View File

@@ -243,10 +243,11 @@ EODOC
$this->newOption( $this->newOption(
'metamta.reply-handler-domain', 'metamta.reply-handler-domain',
'string', 'string',
'phabricator.example.com') null)
->setDescription(pht( ->setDescription(pht(
'Domain used for reply email addresses. Some applications can '. 'Domain used for reply email addresses. Some applications can '.
'configure this domain.')), 'override this configuration with a different domain.'))
->addExample('phabricator.example.com', ''),
$this->newOption('metamta.reply.show-hints', 'bool', true) $this->newOption('metamta.reply.show-hints', 'bool', true)
->setBoolOptions( ->setBoolOptions(
array( array(

View File

@@ -25,7 +25,7 @@ class DifferentialReplyHandler extends PhabricatorMailReplyHandler {
} }
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return $this->getCustomReplyHandlerDomainIfExists(
'metamta.differential.reply-handler-domain'); 'metamta.differential.reply-handler-domain');
} }

View File

@@ -17,10 +17,6 @@ final class FundInitiativeReplyHandler extends PhabricatorMailReplyHandler {
return $this->getDefaultPublicReplyHandlerEmailAddress('I'); return $this->getDefaultPublicReplyHandlerEmailAddress('I');
} }
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
}
public function getReplyHandlerInstructions() { public function getReplyHandlerInstructions() {
if ($this->supportsReplies()) { if ($this->supportsReplies()) {
// TODO: Implement. // TODO: Implement.

View File

@@ -17,11 +17,6 @@ final class LegalpadReplyHandler extends PhabricatorMailReplyHandler {
return $this->getDefaultPublicReplyHandlerEmailAddress('L'); return $this->getDefaultPublicReplyHandlerEmailAddress('L');
} }
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig(
'metamta.reply-handler-domain');
}
public function getReplyHandlerInstructions() { public function getReplyHandlerInstructions() {
if ($this->supportsReplies()) { if ($this->supportsReplies()) {
return pht('Reply to comment or !unsubscribe.'); return pht('Reply to comment or !unsubscribe.');

View File

@@ -18,7 +18,7 @@ final class PhabricatorMacroReplyHandler extends PhabricatorMailReplyHandler {
} }
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return $this->getCustomReplyHandlerDomainIfExists(
'metamta.macro.reply-handler-domain'); 'metamta.macro.reply-handler-domain');
} }

View File

@@ -18,7 +18,7 @@ final class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
} }
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return $this->getCustomReplyHandlerDomainIfExists(
'metamta.maniphest.reply-handler-domain'); 'metamta.maniphest.reply-handler-domain');
} }

View File

@@ -32,6 +32,9 @@ final class PhabricatorAppSearchEngine
$saved->setParameter( $saved->setParameter(
'launchable', 'launchable',
$this->readBoolFromRequest($request, 'launchable')); $this->readBoolFromRequest($request, 'launchable'));
$saved->setParameter(
'appemails',
$this->readBoolFromRequest($request, 'appemails'));
return $saved; return $saved;
} }
@@ -73,6 +76,11 @@ final class PhabricatorAppSearchEngine
$query->withLaunchable($launchable); $query->withLaunchable($launchable);
} }
$appemails = $saved->getParameter('appemails');
if ($appemails !== null) {
$query->withApplicationEmailSupport($appemails);
}
return $query; return $query;
} }
@@ -129,6 +137,17 @@ final class PhabricatorAppSearchEngine
'' => pht('Show All Applications'), '' => pht('Show All Applications'),
'true' => pht('Show Launchable Applications'), 'true' => pht('Show Launchable Applications'),
'false' => pht('Show Non-Launchable Applications'), 'false' => pht('Show Non-Launchable Applications'),
)))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Application Emails'))
->setName('appemails')
->setValue($this->getBoolFromQuery($saved, 'appemails'))
->setOptions(
array(
'' => pht('Show All Applications'),
'true' => pht('Show Applications w/ App Email Support'),
'false' => pht('Show Applications w/o App Email Support'),
))); )));
} }

View File

@@ -10,6 +10,7 @@ final class PhabricatorApplicationQuery
private $unlisted; private $unlisted;
private $classes; private $classes;
private $launchable; private $launchable;
private $applicationEmailSupport;
private $phids; private $phids;
const ORDER_APPLICATION = 'order:application'; const ORDER_APPLICATION = 'order:application';
@@ -47,6 +48,11 @@ final class PhabricatorApplicationQuery
return $this; return $this;
} }
public function withApplicationEmailSupport($appemails) {
$this->applicationEmailSupport = $appemails;
return $this;
}
public function withClasses(array $classes) { public function withClasses(array $classes) {
$this->classes = $classes; $this->classes = $classes;
return $this; return $this;
@@ -131,6 +137,14 @@ final class PhabricatorApplicationQuery
} }
} }
if ($this->applicationEmailSupport !== null) {
foreach ($apps as $key => $app) {
if ($app->supportsEmailIntegration() !=
$this->applicationEmailSupport) {
unset($apps[$key]);
}
}
}
switch ($this->order) { switch ($this->order) {
case self::ORDER_NAME: case self::ORDER_NAME:

View File

@@ -49,9 +49,20 @@ abstract class PhabricatorMailReplyHandler {
abstract public function getPrivateReplyHandlerEmailAddress( abstract public function getPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle); PhabricatorObjectHandle $handle);
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return $this->getDefaultReplyHandlerDomain();
}
protected function getCustomReplyHandlerDomainIfExists($config_key) {
$domain = PhabricatorEnv::getEnvConfig($config_key);
if ($domain) {
return $domain;
}
return $this->getDefaultReplyHandlerDomain();
}
private function getDefaultReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return PhabricatorEnv::getEnvConfig(
'metamta.reply-handler-domain'); 'metamta.reply-handler-domain');
} }
abstract public function getReplyHandlerInstructions(); abstract public function getReplyHandlerInstructions();
abstract protected function receiveEmail( abstract protected function receiveEmail(
PhabricatorMetaMTAReceivedMail $mail); PhabricatorMetaMTAReceivedMail $mail);

View File

@@ -18,7 +18,7 @@ final class PholioReplyHandler extends PhabricatorMailReplyHandler {
} }
public function getReplyHandlerDomain() { public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig( return $this->getCustomReplyHandlerDomainIfExists(
'metamta.pholio.reply-handler-domain'); 'metamta.pholio.reply-handler-domain');
} }

View File

@@ -17,10 +17,6 @@ final class PhortuneCartReplyHandler extends PhabricatorMailReplyHandler {
return $this->getDefaultPublicReplyHandlerEmailAddress('CART'); return $this->getDefaultPublicReplyHandlerEmailAddress('CART');
} }
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
}
public function getReplyHandlerInstructions() { public function getReplyHandlerInstructions() {
if ($this->supportsReplies()) { if ($this->supportsReplies()) {
// TODO: Implement. // TODO: Implement.

View File

@@ -20,10 +20,6 @@ final class PhrictionReplyHandler extends PhabricatorMailReplyHandler {
PhrictionDocumentPHIDType::TYPECONST); PhrictionDocumentPHIDType::TYPECONST);
} }
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
}
public function getReplyHandlerInstructions() { public function getReplyHandlerInstructions() {
if ($this->supportsReplies()) { if ($this->supportsReplies()) {
// TODO: Implement. // TODO: Implement.

View File

@@ -2,8 +2,7 @@
@group config @group config
This document contains instructions for configuring inbound email, so users This document contains instructions for configuring inbound email, so users
may update Differential and Maniphest by replying to messages and create may interact with some Phabricator applications via email.
Maniphest tasks via email.
= Preamble = = Preamble =
@@ -33,20 +32,13 @@ in Phabricator and users will not be able to take actions like claiming tasks or
requesting changes to revisions. requesting changes to revisions.
To change this behavior so that users can interact with objects in Phabricator To change this behavior so that users can interact with objects in Phabricator
over email, set these configuration keys: over email, change the configuration key `metamta.reply-handler-domain` to some
domain you configure according to the instructions below, e.g.
- ##metamta.differential.reply-handler-domain##: enables email replies for `phabricator.example.com`. Once you set this key, emails will use a
Differential. 'Reply-To' like `T123+273+af310f9220ad@phabricator.example.com`, which -- when
- ##metamta.maniphest.reply-handler-domain##: enables email replies for
Maniphest.
Set these keys to some domain which you configure according to the instructions
below, e.g. `phabricator.example.com`. You can set these both to the same
domain, and will generally want to. Once you set these keys, emails will use a
'Reply-To' like `T123+273+af310f9220ad@example.com`, which -- when
configured correctly, according to the instructions below -- will parse incoming configured correctly, according to the instructions below -- will parse incoming
email and allow users to interact with Maniphest tasks and Differential email and allow users to interact with Differential revisions, Maniphest tasks,
revisions over email. etc. over email.
If you don't want Phabricator to take up an entire domain (or subdomain) you If you don't want Phabricator to take up an entire domain (or subdomain) you
can configure a general prefix so you can use a single mailbox to receive mail can configure a general prefix so you can use a single mailbox to receive mail
@@ -56,10 +48,15 @@ mail address. This works because everything up to the first (optional) '+'
character in an email-address is considered the receiver, and everything character in an email-address is considered the receiver, and everything
after is essentially ignored. after is essentially ignored.
You can also set up a task creation email address, like `bugs@example.com`, You can also set up application email addresses to allow users to create
which will create a Maniphest task out of any email which is set to it. To do application objects via email. For example, you could configure
this, set `metamta.maniphest.public-create-email` in your configuration. This `bugs@phabricator.example.com` to create a Maniphest task out of any email
has some mild security implications, see below. which is sent to it. To do this, see application settings for a given
application at
{nav icon=home, name=Home >
name=Applications >
icon=cog, name=Settings}
= Security = = Security =
@@ -93,8 +90,8 @@ practically, is a reasonable setting for many installs. The reply-to address
will still contain a hash unique to the object it represents, so users who have will still contain a hash unique to the object it represents, so users who have
not received an email about an object can not blindly interact with it. not received an email about an object can not blindly interact with it.
If you enable `metamta.maniphest.public-create-email`, that address also uses If you enable application email addresses, those addresses also use the weaker
the weaker "From" authentication mechanism. "From" authentication mechanism.
NOTE: Phabricator does not currently attempt to verify "From" addresses because NOTE: Phabricator does not currently attempt to verify "From" addresses because
this is technically complex, seems unreasonably difficult in the general case, this is technically complex, seems unreasonably difficult in the general case,