diff --git a/conf/default.conf.php b/conf/default.conf.php index 4c44ce01cd..9c973f6f13 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -268,6 +268,17 @@ return array( // still **COMPLETELY INSECURE**. 'metamta.insecure-auth-with-reply-to' => false, + // If you enable 'metamta.maniphest.public-create-email' and create an + // email address like "bugs@phabricator.example.com", it will default to + // rejecting mail which doesn't come from a known user. However, you might + // want to let anyone send email to this address; to do so, set a default + // author here (a Phabricator username). A typical use of this might be to + // create a "System Agent" user called "bugs" and use that name here. If you + // specify a valid username, mail will always be accepted and used to create + // a task, even if the sender is not a system user. The original email + // address will be stored in an 'From Email' field on the task. + 'metamta.maniphest.default-public-author' => null, + // -- Auth ------------------------------------------------------------------ // diff --git a/resources/sql/patches/077.originalemail.sql b/resources/sql/patches/077.originalemail.sql new file mode 100644 index 0000000000..0ce5d9f680 --- /dev/null +++ b/resources/sql/patches/077.originalemail.sql @@ -0,0 +1,2 @@ +ALTER TABLE phabricator_maniphest.maniphest_task + ADD originalEmailSource VARCHAR(255); diff --git a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php index a0a1ac1633..96ec82b2ea 100644 --- a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php @@ -115,6 +115,17 @@ class ManiphestTaskDetailController extends ManiphestController { $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink(); + $source = $task->getOriginalEmailSource(); + if ($source) { + $subject = '[T'.$task->getID().'] '.$task->getTitle(); + $dict['From Email'] = phutil_render_tag( + 'a', + array( + 'href' => 'mailto:'.$source.'?subject='.$subject + ), + phutil_escape_html($source)); + } + $projects = $task->getProjectPHIDs(); if ($projects) { $project_links = array(); diff --git a/src/applications/maniphest/storage/task/ManiphestTask.php b/src/applications/maniphest/storage/task/ManiphestTask.php index df5ebdfdf3..0064116177 100644 --- a/src/applications/maniphest/storage/task/ManiphestTask.php +++ b/src/applications/maniphest/storage/task/ManiphestTask.php @@ -31,7 +31,7 @@ class ManiphestTask extends ManiphestDAO { protected $title; protected $description; - + protected $originalEmailSource; protected $mailKey; protected $attached = array(); diff --git a/src/applications/metamta/storage/receivedmail/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/receivedmail/PhabricatorMetaMTAReceivedMail.php index 10ebdf5fd4..6200424577 100644 --- a/src/applications/metamta/storage/receivedmail/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/receivedmail/PhabricatorMetaMTAReceivedMail.php @@ -64,16 +64,34 @@ class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO { 'metamta.maniphest.public-create-email'); if ($create_task && $to == $create_task) { + $receiver = new ManiphestTask(); + $user = $this->lookupPublicUser(); - if (!$user) { - // TODO: We should probably bounce these since from the user's - // perspective their email vanishes into a black hole. - return $this->setMessage("Invalid public user '{$from}'.")->save(); + if ($user) { + $this->setAuthorPHID($user->getPHID()); + } else { + $default_author = PhabricatorEnv::getEnvConfig( + 'metamta.manipest.default-public-author'); + + if ($default_author) { + $user = id(new PhabricatorUser())->loadOneWhere( + 'username = %s', + $default_author); + if ($user) { + $receiver->setOriginalEmailSource($from); + } else { + throw new Exception( + "Phabricator is misconfigured, the configuration key ". + "'metamta.manipest.default-public-author' is set to user ". + "'{$default_author}' but that user does not exist."); + } + } else { + // TODO: We should probably bounce these since from the user's + // perspective their email vanishes into a black hole. + return $this->setMessage("Invalid public user '{$from}'.")->save(); + } } - $this->setAuthorPHID($user->getPHID()); - - $receiver = new ManiphestTask(); $receiver->setAuthorPHID($user->getPHID()); $receiver->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);