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:
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.');
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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'),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user