diff --git a/src/applications/audit/mail/PhabricatorAuditReplyHandler.php b/src/applications/audit/mail/PhabricatorAuditReplyHandler.php --- a/src/applications/audit/mail/PhabricatorAuditReplyHandler.php +++ b/src/applications/audit/mail/PhabricatorAuditReplyHandler.php @@ -18,7 +18,7 @@ } public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( + return $this->getCustomReplyHandlerDomainIfExists( 'metamta.diffusion.reply-handler-domain'); } diff --git a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php --- a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php +++ b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php @@ -243,10 +243,11 @@ $this->newOption( 'metamta.reply-handler-domain', 'string', - 'phabricator.example.com') + null) ->setDescription(pht( '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) ->setBoolOptions( array( diff --git a/src/applications/differential/mail/DifferentialReplyHandler.php b/src/applications/differential/mail/DifferentialReplyHandler.php --- a/src/applications/differential/mail/DifferentialReplyHandler.php +++ b/src/applications/differential/mail/DifferentialReplyHandler.php @@ -25,7 +25,7 @@ } public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( + return $this->getCustomReplyHandlerDomainIfExists( 'metamta.differential.reply-handler-domain'); } diff --git a/src/applications/fund/mail/FundInitiativeReplyHandler.php b/src/applications/fund/mail/FundInitiativeReplyHandler.php --- a/src/applications/fund/mail/FundInitiativeReplyHandler.php +++ b/src/applications/fund/mail/FundInitiativeReplyHandler.php @@ -17,10 +17,6 @@ return $this->getDefaultPublicReplyHandlerEmailAddress('I'); } - public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain'); - } - public function getReplyHandlerInstructions() { if ($this->supportsReplies()) { // TODO: Implement. diff --git a/src/applications/legalpad/mail/LegalpadReplyHandler.php b/src/applications/legalpad/mail/LegalpadReplyHandler.php --- a/src/applications/legalpad/mail/LegalpadReplyHandler.php +++ b/src/applications/legalpad/mail/LegalpadReplyHandler.php @@ -17,11 +17,6 @@ return $this->getDefaultPublicReplyHandlerEmailAddress('L'); } - public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( - 'metamta.reply-handler-domain'); - } - public function getReplyHandlerInstructions() { if ($this->supportsReplies()) { return pht('Reply to comment or !unsubscribe.'); diff --git a/src/applications/macro/mail/PhabricatorMacroReplyHandler.php b/src/applications/macro/mail/PhabricatorMacroReplyHandler.php --- a/src/applications/macro/mail/PhabricatorMacroReplyHandler.php +++ b/src/applications/macro/mail/PhabricatorMacroReplyHandler.php @@ -18,7 +18,7 @@ } public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( + return $this->getCustomReplyHandlerDomainIfExists( 'metamta.macro.reply-handler-domain'); } diff --git a/src/applications/maniphest/mail/ManiphestReplyHandler.php b/src/applications/maniphest/mail/ManiphestReplyHandler.php --- a/src/applications/maniphest/mail/ManiphestReplyHandler.php +++ b/src/applications/maniphest/mail/ManiphestReplyHandler.php @@ -18,7 +18,7 @@ } public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( + return $this->getCustomReplyHandlerDomainIfExists( 'metamta.maniphest.reply-handler-domain'); } diff --git a/src/applications/meta/query/PhabricatorAppSearchEngine.php b/src/applications/meta/query/PhabricatorAppSearchEngine.php --- a/src/applications/meta/query/PhabricatorAppSearchEngine.php +++ b/src/applications/meta/query/PhabricatorAppSearchEngine.php @@ -32,6 +32,9 @@ $saved->setParameter( 'launchable', $this->readBoolFromRequest($request, 'launchable')); + $saved->setParameter( + 'appemails', + $this->readBoolFromRequest($request, 'appemails')); return $saved; } @@ -73,6 +76,11 @@ $query->withLaunchable($launchable); } + $appemails = $saved->getParameter('appemails'); + if ($appemails !== null) { + $query->withApplicationEmailSupport($appemails); + } + return $query; } @@ -129,6 +137,17 @@ '' => pht('Show All Applications'), 'true' => pht('Show 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'), ))); } diff --git a/src/applications/meta/query/PhabricatorApplicationQuery.php b/src/applications/meta/query/PhabricatorApplicationQuery.php --- a/src/applications/meta/query/PhabricatorApplicationQuery.php +++ b/src/applications/meta/query/PhabricatorApplicationQuery.php @@ -10,6 +10,7 @@ private $unlisted; private $classes; private $launchable; + private $applicationEmailSupport; private $phids; const ORDER_APPLICATION = 'order:application'; @@ -47,6 +48,11 @@ return $this; } + public function withApplicationEmailSupport($appemails) { + $this->applicationEmailSupport = $appemails; + return $this; + } + public function withClasses(array $classes) { $this->classes = $classes; return $this; @@ -131,6 +137,14 @@ } } + if ($this->applicationEmailSupport !== null) { + foreach ($apps as $key => $app) { + if ($app->supportsEmailIntegration() != + $this->applicationEmailSupport) { + unset($apps[$key]); + } + } + } switch ($this->order) { case self::ORDER_NAME: diff --git a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php --- a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php +++ b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php @@ -49,9 +49,20 @@ abstract public function getPrivateReplyHandlerEmailAddress( PhabricatorObjectHandle $handle); 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( 'metamta.reply-handler-domain'); } + abstract public function getReplyHandlerInstructions(); abstract protected function receiveEmail( PhabricatorMetaMTAReceivedMail $mail); diff --git a/src/applications/pholio/mail/PholioReplyHandler.php b/src/applications/pholio/mail/PholioReplyHandler.php --- a/src/applications/pholio/mail/PholioReplyHandler.php +++ b/src/applications/pholio/mail/PholioReplyHandler.php @@ -18,7 +18,7 @@ } public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig( + return $this->getCustomReplyHandlerDomainIfExists( 'metamta.pholio.reply-handler-domain'); } diff --git a/src/applications/phortune/mail/PhortuneCartReplyHandler.php b/src/applications/phortune/mail/PhortuneCartReplyHandler.php --- a/src/applications/phortune/mail/PhortuneCartReplyHandler.php +++ b/src/applications/phortune/mail/PhortuneCartReplyHandler.php @@ -17,10 +17,6 @@ return $this->getDefaultPublicReplyHandlerEmailAddress('CART'); } - public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain'); - } - public function getReplyHandlerInstructions() { if ($this->supportsReplies()) { // TODO: Implement. diff --git a/src/applications/phriction/mail/PhrictionReplyHandler.php b/src/applications/phriction/mail/PhrictionReplyHandler.php --- a/src/applications/phriction/mail/PhrictionReplyHandler.php +++ b/src/applications/phriction/mail/PhrictionReplyHandler.php @@ -20,10 +20,6 @@ PhrictionDocumentPHIDType::TYPECONST); } - public function getReplyHandlerDomain() { - return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain'); - } - public function getReplyHandlerInstructions() { if ($this->supportsReplies()) { // TODO: Implement. diff --git a/src/docs/user/configuration/configuring_inbound_email.diviner b/src/docs/user/configuration/configuring_inbound_email.diviner --- a/src/docs/user/configuration/configuring_inbound_email.diviner +++ b/src/docs/user/configuration/configuring_inbound_email.diviner @@ -2,8 +2,7 @@ @group config This document contains instructions for configuring inbound email, so users -may update Differential and Maniphest by replying to messages and create -Maniphest tasks via email. +may interact with some Phabricator applications via email. = Preamble = @@ -33,20 +32,13 @@ requesting changes to revisions. To change this behavior so that users can interact with objects in Phabricator -over email, set these configuration keys: - - - ##metamta.differential.reply-handler-domain##: enables email replies for - Differential. - - ##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 +over email, change the configuration key `metamta.reply-handler-domain` to some +domain you configure according to the instructions below, e.g. +`phabricator.example.com`. Once you set this key, emails will use a +'Reply-To' like `T123+273+af310f9220ad@phabricator.example.com`, which -- when configured correctly, according to the instructions below -- will parse incoming -email and allow users to interact with Maniphest tasks and Differential -revisions over email. +email and allow users to interact with Differential revisions, Maniphest tasks, +etc. over email. 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 @@ -56,10 +48,15 @@ character in an email-address is considered the receiver, and everything after is essentially ignored. -You can also set up a task creation email address, like `bugs@example.com`, -which will create a Maniphest task out of any email which is set to it. To do -this, set `metamta.maniphest.public-create-email` in your configuration. This -has some mild security implications, see below. +You can also set up application email addresses to allow users to create +application objects via email. For example, you could configure +`bugs@phabricator.example.com` to create a Maniphest task out of any email +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 = @@ -93,8 +90,8 @@ 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. -If you enable `metamta.maniphest.public-create-email`, that address also uses -the weaker "From" authentication mechanism. +If you enable application email addresses, those addresses also use the weaker +"From" authentication mechanism. NOTE: Phabricator does not currently attempt to verify "From" addresses because this is technically complex, seems unreasonably difficult in the general case,