protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $title = $mail->getSubject();
     if (!$title) {
         $title = pht('Email Paste');
     }
     $file = PhabricatorPasteEditor::initializeFileForPaste($sender, $title, $mail->getCleanTextBody());
     $xactions = array();
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)->setNewValue($file->getPHID());
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)->setNewValue($title);
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)->setNewValue('');
     // auto-detect
     $paste = PhabricatorPaste::initializeNewPaste($sender);
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new PhabricatorPasteEditor())->setActor($sender)->setContentSource($content_source)->setContinueOnNoEffect(true);
     $xactions = $editor->applyTransactions($paste, $xactions);
     $mail->setRelatedPHID($paste->getPHID());
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.paste.subject-prefix');
     $subject = pht('You successfully created a paste.');
     $paste_uri = PhabricatorEnv::getProductionURI($paste->getURI());
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     $body->addTextSection(pht('PASTE LINK'), $paste_uri);
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setRelatedPHID($paste->getPHID())->setBody($body->render())->saveAndSend();
 }
 protected function processReceivedObjectMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorLiskDAO $object, PhabricatorUser $sender)
 {
     $handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit($object);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs());
     $handler->processEmail($mail);
 }
 protected function collectGarbage()
 {
     $table = new PhabricatorMetaMTAReceivedMail();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'DELETE FROM %T WHERE dateCreated < %d LIMIT 100', $table->getTableName(), $this->getGarbageEpoch());
     return $conn_w->getAffectedRows() == 100;
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $actor = $this->getActor();
     $document = $this->getMailReceiver();
     $body_data = $mail->parseBody();
     $body = $body_data['body'];
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $xactions = array();
     $command = $body_data['command'];
     switch ($command) {
         case 'unsubscribe':
             $xaction = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('-' => array($actor->getPHID())));
             $xactions[] = $xaction;
             break;
     }
     $xactions[] = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new LegalpadTransactionComment())->setDocumentID($document->getID())->setLineNumber(0)->setLineLength(0)->setContent($body));
     $editor = id(new LegalpadDocumentEditor())->setActor($actor)->setContentSource($content_source)->setContinueOnNoEffect(true)->setIsPreview(false);
     try {
         $xactions = $editor->applyTransactions($document, $xactions);
     } catch (PhabricatorApplicationTransactionNoEffectException $ex) {
         // just do nothing, though unclear why you're sending a blank email
         return true;
     }
     $head_xaction = head($xactions);
     return $head_xaction->getID();
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($request->isFormPost()) {
         $receiver = PhabricatorMetaMTAReceivedMail::loadReceiverObject($request->getStr('obj'));
         if (!$receiver) {
             throw new Exception("No such task or revision!");
         }
         $hash = PhabricatorMetaMTAReceivedMail::computeMailHash($receiver->getMailKey(), $user->getPHID());
         $received = new PhabricatorMetaMTAReceivedMail();
         $received->setHeaders(array('to' => $request->getStr('obj') . '+' . $user->getID() . '+' . $hash . '@'));
         $received->setBodies(array('text' => $request->getStr('body')));
         $received->save();
         $received->processReceivedMail();
         $phid = $receiver->getPHID();
         $handles = $this->loadViewerHandles(array($phid));
         $uri = $handles[$phid]->getURI();
         return id(new AphrontRedirectResponse())->setURI($uri);
     }
     $form = new AphrontFormView();
     $form->setUser($request->getUser());
     $form->setAction($this->getApplicationURI('/receive/'));
     $form->appendChild('<p class="aphront-form-instructions">This form will simulate ' . 'sending mail to an object.</p>')->appendChild(id(new AphrontFormTextControl())->setLabel('To')->setName('obj')->setCaption('e.g. <tt>D1234</tt> or <tt>T1234</tt>'))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Body')->setName('body'))->appendChild(id(new AphrontFormSubmitControl())->setValue('Receive Mail'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Receive Email');
     $panel->appendChild($form);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $nav = $this->buildSideNavView();
     $nav->selectFilter('receive');
     $nav->appendChild($panel);
     return $this->buildApplicationPage($nav, array('title' => 'Receive Test'));
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $conpherence = $this->getMailReceiver();
     $user = $this->getActor();
     if (!$conpherence->getPHID()) {
         $conpherence->attachParticipants(array())->attachFilePHIDs(array());
     } else {
         $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
         $file_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($conpherence->getPHID(), $edge_type);
         $conpherence->attachFilePHIDs($file_phids);
         $participants = id(new ConpherenceParticipant())->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID());
         $participants = mpull($participants, null, 'getParticipantPHID');
         $conpherence->attachParticipants($participants);
     }
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new ConpherenceEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = array();
     if ($this->getMailAddedParticipantPHIDs()) {
         $xactions[] = id(new ConpherenceTransaction())->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)->setNewValue(array('+' => $this->getMailAddedParticipantPHIDs()));
     }
     $xactions = array_merge($xactions, $editor->generateTransactionsFromText($user, $conpherence, $body));
     $editor->applyTransactions($conpherence, $xactions);
     return $conpherence;
 }
 private function buildMail($style)
 {
     $user = $this->generateNewTestUser();
     $task = id(new PhabricatorManiphestTaskTestDataGenerator())->setViewer($user)->generateObject();
     $is_public = $style === 'public';
     $is_bad_hash = $style == 'badhash';
     $is_bad_user = $style == 'baduser';
     $is_404_object = $style == '404';
     if ($is_public) {
         $user_identifier = 'public';
     } else {
         if ($is_bad_user) {
             $user_identifier = $user->getID() + 1;
         } else {
             $user_identifier = $user->getID();
         }
     }
     if ($is_bad_hash) {
         $hash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
     } else {
         $hash = PhabricatorObjectMailReceiver::computeMailHash($task->getMailKey(), $is_public ? $task->getPHID() : $user->getPHID());
     }
     if ($is_404_object) {
         $task_identifier = 'T' . ($task->getID() + 1);
     } else {
         $task_identifier = 'T' . $task->getID();
     }
     $to = $task_identifier . '+' . $user_identifier . '+' . $hash . '@example.com';
     $mail = new PhabricatorMetaMTAReceivedMail();
     $mail->setHeaders(array('Message-ID' => '*****@*****.**', 'From' => $user->loadPrimaryEmail()->getAddress(), 'To' => $to));
     return array($task, $user, $mail);
 }
 protected function processReceivedObjectMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorLiskDAO $object, PhabricatorUser $sender)
 {
     $handler = id(new ConpherenceReplyHandler())->setMailReceiver($object);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs());
     $handler->processEmail($mail);
 }
 protected function processReceivedObjectMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorLiskDAO $object, PhabricatorUser $sender)
 {
     $handler = DifferentialMail::newReplyHandlerForRevision($object);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs());
     $handler->processEmail($mail);
 }
 protected function processReceivedObjectMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorLiskDAO $object, PhabricatorUser $sender)
 {
     $handler = PhabricatorEnv::newObjectFromConfig('metamta.maniphest.reply-handler');
     $handler->setMailReceiver($object);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs());
     $handler->processEmail($mail);
 }
 public function collectGarbage()
 {
     $ttl = phutil_units('90 days in seconds');
     $table = new PhabricatorMetaMTAReceivedMail();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'DELETE FROM %T WHERE dateCreated < %d LIMIT 100', $table->getTableName(), time() - $ttl);
     return $conn_w->getAffectedRows() == 100;
 }
 private function getMailUsernames(PhabricatorMetaMTAReceivedMail $mail)
 {
     $usernames = array();
     foreach ($mail->getToAddresses() as $to_address) {
         $address = self::stripMailboxPrefix($to_address);
         $usernames[] = id(new PhutilEmailAddress($address))->getLocalPart();
     }
     return array_unique($usernames);
 }
 private function matchObjectAddressInMail(PhabricatorMetaMTAReceivedMail $mail)
 {
     foreach ($mail->getToAddresses() as $address) {
         $parts = $this->matchObjectAddress($address);
         if ($parts) {
             return $parts;
         }
     }
     return null;
 }
 public function testDropDisabledSenderMail()
 {
     $this->setManiphestCreateEmail();
     $user = $this->generateNewTestUser()->setIsDisabled(true)->save();
     $mail = new PhabricatorMetaMTAReceivedMail();
     $mail->setHeaders(array('Message-ID' => '*****@*****.**', 'From' => $user->loadPrimaryEmail()->getAddress(), 'To' => '*****@*****.**'));
     $mail->save();
     $mail->processReceivedMail();
     $this->assertEqual(MetaMTAReceivedMailStatus::STATUS_DISABLED_SENDER, $mail->getStatus());
 }
 /**
  * Identifies the sender's user account for a piece of received mail. Note
  * that this method does not validate that the sender is who they say they
  * are, just that they've presented some credential which corresponds to a
  * recognizable user.
  */
 public function loadSender(PhabricatorMetaMTAReceivedMail $mail)
 {
     $raw_from = $mail->getHeader('From');
     $from = self::getRawAddress($raw_from);
     $reasons = array();
     // Try to find a user with this email address.
     $user = PhabricatorUser::loadOneWithEmailAddress($from);
     if ($user) {
         return $user;
     } else {
         $reasons[] = pht('This email was sent from "%s", but that address is not recognized by ' . 'Phabricator and does not correspond to any known user account.', $raw_from);
     }
     // If we missed on "From", try "Reply-To" if we're configured for it.
     $raw_reply_to = $mail->getHeader('Reply-To');
     if (strlen($raw_reply_to)) {
         $reply_to_key = 'metamta.insecure-auth-with-reply-to';
         $allow_reply_to = PhabricatorEnv::getEnvConfig($reply_to_key);
         if ($allow_reply_to) {
             $reply_to = self::getRawAddress($raw_reply_to);
             $user = PhabricatorUser::loadOneWithEmailAddress($reply_to);
             if ($user) {
                 return $user;
             } else {
                 $reasons[] = pht('Phabricator is configured to authenticate users using the ' . '"Reply-To" header, but the reply address ("%s") on this ' . 'message does not correspond to any known user account.', $raw_reply_to);
             }
         } else {
             $reasons[] = pht('(Phabricator is not configured to authenticate users using the ' . '"Reply-To" header, so it was ignored.)');
         }
     }
     // If we don't know who this user is, load or create an external user
     // account for them if we're configured for it.
     $email_key = 'phabricator.allow-email-users';
     $allow_email_users = PhabricatorEnv::getEnvConfig($email_key);
     if ($allow_email_users) {
         $from_obj = new PhutilEmailAddress($from);
         $xuser = id(new PhabricatorExternalAccountQuery())->setViewer($this->getViewer())->withAccountTypes(array('email'))->withAccountDomains(array($from_obj->getDomainName(), 'self'))->withAccountIDs(array($from_obj->getAddress()))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->loadOneOrCreate();
         return $xuser->getPhabricatorUser();
     } else {
         $reasons[] = pht('Phabricator is also not configured to allow unknown external users ' . 'to send mail to the system using just an email address.');
         $reasons[] = pht('To interact with Phabricator, add this address ("%s") to your ' . 'account.', $raw_from);
     }
     if ($this->getApplicationEmail()) {
         $application_email = $this->getApplicationEmail();
         $default_user_phid = $application_email->getConfigValue(PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR);
         if ($default_user_phid) {
             $user = id(new PhabricatorUser())->loadOneWhere('phid = %s', $default_user_phid);
             if ($user) {
                 return $user;
             }
         }
         $reasons[] = pht("Phabricator is misconfigured, the application email " . "'%s' is set to user '%s' but that user does not exist.", $application_email->getAddress(), $default_user_phid);
     }
     $reasons = implode("\n\n", $reasons);
     throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_UNKNOWN_SENDER, $reasons);
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $commit = $this->getMailReceiver();
     $actor = $this->getActor();
     $message = $mail->getCleanTextBody();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     // TODO: Support !raise, !accept, etc.
     $xactions = array();
     $xactions[] = id(new PhabricatorAuditTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new PhabricatorAuditTransactionComment())->setCommitPHID($commit->getPHID())->setContent($message));
     $editor = id(new PhabricatorAuditEditor())->setActor($actor)->setContentSource($content_source)->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())->setContinueOnMissingFields(true)->applyTransactions($commit, $xactions);
 }
 public function testDropDisabledSenderMail()
 {
     $env = PhabricatorEnv::beginScopedEnv();
     $env->overrideEnvConfig('metamta.maniphest.public-create-email', '*****@*****.**');
     $user = $this->generateNewTestUser()->setIsDisabled(true)->save();
     $mail = new PhabricatorMetaMTAReceivedMail();
     $mail->setHeaders(array('Message-ID' => '*****@*****.**', 'From' => $user->loadPrimaryEmail()->getAddress(), 'To' => '*****@*****.**'));
     $mail->save();
     $mail->processReceivedMail();
     $this->assertEqual(MetaMTAReceivedMailStatus::STATUS_DISABLED_SENDER, $mail->getStatus());
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $task = ManiphestTask::initializeNewTask($sender);
     $task->setOriginalEmailSource($mail->getHeader('From'));
     $handler = PhabricatorEnv::newObjectFromConfig('metamta.maniphest.reply-handler');
     $handler->setMailReceiver($task);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs());
     $handler->processEmail($mail);
     $mail->setRelatedPHID($task->getPHID());
 }
 protected function didReceiveMail(PhabricatorMetaMTAReceivedMail $mail, $body)
 {
     $object = $this->getMailReceiver();
     $is_new = !$object->getID();
     $xactions = array();
     if ($is_new) {
         $xactions[] = $object->getApplicationTransactionTemplate()->setTransactionType(ManiphestTransaction::TYPE_TITLE)->setNewValue(nonempty($mail->getSubject(), pht('Untitled Task')));
         $xactions[] = $object->getApplicationTransactionTemplate()->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)->setNewValue($body);
     }
     return $xactions;
 }
 public function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $commit = $this->getMailReceiver();
     $actor = $this->getActor();
     // TODO: Support !raise, !accept, etc.
     // TODO: Content sources.
     $comment = id(new PhabricatorAuditComment())->setAction(PhabricatorAuditActionConstants::COMMENT)->setContent($mail->getCleanTextBody());
     $editor = new PhabricatorAuditCommentEditor($commit);
     $editor->setUser($actor);
     $editor->addComment($comment);
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $rq = $this->getMailReceiver();
     $user = $this->getActor();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new ReleephRequestTransactionalEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $xactions = array();
     $xactions[] = id(new ReleephRequestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment($body);
     $editor->applyTransactions($rq, $xactions);
     return $rq;
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $task = ManiphestTask::initializeNewTask($sender);
     $task->setOriginalEmailSource($mail->getHeader('From'));
     $handler = new ManiphestReplyHandler();
     $handler->setMailReceiver($task);
     $handler->setActor($sender);
     $handler->setExcludeMailRecipientPHIDs($mail->loadAllRecipientPHIDs());
     if ($this->getApplicationEmail()) {
         $handler->setApplicationEmail($this->getApplicationEmail());
     }
     $handler->processEmail($mail);
     $mail->setRelatedPHID($task->getPHID());
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $title = $mail->getSubject();
     if (!strlen($title)) {
         $title = pht('New Question');
     }
     $xactions = array();
     $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PonderQuestionTransaction::TYPE_TITLE)->setNewValue($title);
     $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT)->setNewValue($mail->getCleanTextBody());
     $question = PonderQuestion::initializeNewQuestion($sender);
     $content_source = $mail->newContentSource();
     $editor = id(new PonderQuestionEditor())->setActor($sender)->setContentSource($content_source)->setContinueOnNoEffect(true);
     $xactions = $editor->applyTransactions($question, $xactions);
     $mail->setRelatedPHID($question->getPHID());
 }
 protected function didReceiveMail(PhabricatorMetaMTAReceivedMail $mail, $body)
 {
     $object = $this->getMailReceiver();
     $is_new = !$object->getID();
     $actor = $this->getActor();
     $xactions = array();
     if ($is_new) {
         $xactions[] = $this->newTransaction()->setTransactionType(ManiphestTransaction::TYPE_TITLE)->setNewValue(nonempty($mail->getSubject(), pht('Untitled Task')));
         $xactions[] = $this->newTransaction()->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)->setNewValue($body);
         $actor_phid = $actor->getPHID();
         if ($actor_phid) {
             $xactions[] = $this->newTransaction()->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('+' => array($actor_phid)));
         }
     }
     return $xactions;
 }
 private function dropEmptyMail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $body = $mail->getCleanTextBody();
     $attachments = $mail->getAttachments();
     if (strlen($body) || $attachments) {
         return;
     }
     // Only send an error email if the user is talking to just Phabricator.
     // We can assume if there is only one "To" address it is a Phabricator
     // address since this code is running and everything.
     $is_direct_mail = count($mail->getToAddresses()) == 1 && count($mail->getCCAddresses()) == 0;
     if ($is_direct_mail) {
         $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY;
     } else {
         $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY_IGNORED;
     }
     throw new PhabricatorMetaMTAReceivedMailProcessingException($status_code, pht('Your message does not contain any body text or attachments, so ' . 'Phabricator can not do anything useful with it. Make sure comment ' . 'text appears at the top of your message: quoted replies, inline ' . 'text, and signatures are discarded and ignored.'));
 }
 public function processRequest()
 {
     // No CSRF for SendGrid.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $request = $this->getRequest();
     $user = $request->getUser();
     $raw_headers = $request->getStr('headers');
     $raw_headers = explode("\n", rtrim($raw_headers));
     $raw_dict = array();
     foreach (array_filter($raw_headers) as $header) {
         list($name, $value) = explode(':', $header, 2);
         $raw_dict[$name] = ltrim($value);
     }
     $headers = array('to' => $request->getStr('to'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict;
     $received = new PhabricatorMetaMTAReceivedMail();
     $received->setHeaders($headers);
     $received->setBodies(array('text' => $request->getStr('text'), 'html' => $request->getStr('from')));
     $file_phids = array();
     foreach ($_FILES as $file_raw) {
         try {
             $file = PhabricatorFile::newFromPHPUpload($file_raw, array('authorPHID' => $user->getPHID()));
             $file_phids[] = $file->getPHID();
         } catch (Exception $ex) {
             phlog($ex);
         }
     }
     $received->setAttachments($file_phids);
     $received->save();
     $received->processReceivedMail();
     $response = new AphrontWebpageResponse();
     $response->setContent("Got it! Thanks, SendGrid!\n");
     return $response;
 }
 public function handleRequest(AphrontRequest $request)
 {
     // No CSRF for Mailgun.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     if (!$this->verifyMessage()) {
         throw new Exception(pht('Mail signature is not valid. Check your Mailgun API key.'));
     }
     $user = $request->getUser();
     $raw_headers = $request->getStr('headers');
     $raw_headers = explode("\n", rtrim($raw_headers));
     $raw_dict = array();
     foreach (array_filter($raw_headers) as $header) {
         list($name, $value) = explode(':', $header, 2);
         $raw_dict[$name] = ltrim($value);
     }
     $headers = array('to' => $request->getStr('recipient'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict;
     $received = new PhabricatorMetaMTAReceivedMail();
     $received->setHeaders($headers);
     $received->setBodies(array('text' => $request->getStr('stripped-text'), 'html' => $request->getStr('stripped-html')));
     $file_phids = array();
     foreach ($_FILES as $file_raw) {
         try {
             $file = PhabricatorFile::newFromPHPUpload($file_raw, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
             $file_phids[] = $file->getPHID();
         } catch (Exception $ex) {
             phlog($ex);
         }
     }
     $received->setAttachments($file_phids);
     $received->save();
     $received->processReceivedMail();
     $response = new AphrontWebpageResponse();
     $response->setContent(pht("Got it! Thanks, Mailgun!\n"));
     return $response;
 }
 protected final function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $viewer = $this->getActor();
     $object = $this->getMailReceiver();
     $app_email = $this->getApplicationEmail();
     $is_new = !$object->getID();
     // If this is a new object which implements the Spaces interface and was
     // created by sending mail to an ApplicationEmail address, put the object
     // in the same Space the address is in.
     if ($is_new) {
         if ($object instanceof PhabricatorSpacesInterface) {
             if ($app_email) {
                 $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($app_email);
                 $object->setSpacePHID($space_phid);
             }
         }
     }
     $body_data = $mail->parseBody();
     $body = $body_data['body'];
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = $this->didReceiveMail($mail, $body);
     // If this object is subscribable, subscribe all the users who were
     // recipients on the message.
     if ($object instanceof PhabricatorSubscribableInterface) {
         $subscriber_phids = $mail->loadAllRecipientPHIDs();
         if ($subscriber_phids) {
             $xactions[] = $this->newTransaction()->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('+' => $subscriber_phids));
         }
     }
     $command_xactions = $this->processMailCommands($mail, $body_data['commands']);
     foreach ($command_xactions as $xaction) {
         $xactions[] = $xaction;
     }
     if ($this->shouldCreateCommentFromMailBody()) {
         $comment = $this->newTransaction()->getApplicationTransactionCommentObject()->setContent($body);
         $xactions[] = $this->newTransaction()->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment($comment);
     }
     $target = $object->getApplicationTransactionObject();
     $this->newEditor($mail)->setContinueOnNoEffect(true)->applyTransactions($target, $xactions);
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $conpherence = $this->getMailReceiver();
     $user = $this->getActor();
     if (!$conpherence->getPHID()) {
         $conpherence->attachParticipants(array());
     } else {
         $participants = id(new ConpherenceParticipant())->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID());
         $participants = mpull($participants, null, 'getParticipantPHID');
         $conpherence->attachParticipants($participants);
     }
     $content_source = $mail->newContentSource();
     $editor = id(new ConpherenceEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = array();
     if ($this->getMailAddedParticipantPHIDs()) {
         $xactions[] = id(new ConpherenceTransaction())->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)->setNewValue(array('+' => $this->getMailAddedParticipantPHIDs()));
     }
     $xactions = array_merge($xactions, $editor->generateTransactionsFromText($user, $conpherence, $body));
     $editor->applyTransactions($conpherence, $xactions);
     return $conpherence;
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $attachment_phids = $mail->getAttachments();
     if (empty($attachment_phids)) {
         throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_UNHANDLED_EXCEPTION, pht('Ignoring email to create files that did not include attachments.'));
     }
     $first_phid = head($attachment_phids);
     $mail->setRelatedPHID($first_phid);
     $attachment_count = count($attachment_phids);
     if ($attachment_count > 1) {
         $subject = pht('You successfully uploaded %d files.', $attachment_count);
     } else {
         $subject = pht('You successfully uploaded a file.');
     }
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.files.subject-prefix');
     $file_uris = array();
     foreach ($attachment_phids as $phid) {
         $file_uris[] = PhabricatorEnv::getProductionURI('/file/info/' . $phid . '/');
     }
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     $body->addTextSection(pht('FILE LINKS'), implode("\n", $file_uris));
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setRelatedPHID($first_phid)->setBody($body->render())->saveAndSend();
 }