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; }
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')); }
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.')); } $raw_headers = $request->getStr('message-headers'); $raw_dict = array(); if (strlen($raw_headers)) { $raw_headers = phutil_json_decode($raw_headers); foreach ($raw_headers as $raw_header) { list($name, $value) = $raw_header; $raw_dict[$name] = $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); try { $received->save(); $received->processReceivedMail(); } catch (Exception $ex) { // We can get exceptions here in two cases. // First, saving the message may throw if we have already received a // message with the same Message ID. In this case, we're declining to // process a duplicate message, so failing silently is correct. // Second, processing the message may throw (for example, if it contains // an invalid !command). This will generate an email as a side effect, // so we don't need to explicitly handle the exception here. // In these cases, we want to return HTTP 200. If we do not, MailGun will // re-transmit the message later. phlog($ex); } $response = new AphrontWebpageResponse(); $response->setContent(pht("Got it! Thanks, Mailgun!\n")); return $response; }
require_once $root . '/scripts/__init_script__.php'; require_once $root . '/externals/mimemailparser/MimeMailParser.class.php'; $parser = new MimeMailParser(); $parser->setText(file_get_contents('php://stdin')); $text_body = $parser->getMessageBody('text'); $text_body_headers = $parser->getMessageBodyHeaders('text'); $content_type = idx($text_body_headers, 'content-type'); if (!phutil_is_utf8($text_body) && (preg_match('/charset="(.*?)"/', $content_type, $matches) || preg_match('/charset=(\\S+)/', $content_type, $matches))) { $text_body = phutil_utf8_convert($text_body, "UTF-8", $matches[1]); } $headers = $parser->getHeaders(); $headers['subject'] = iconv_mime_decode($headers['subject'], 0, "UTF-8"); $headers['from'] = iconv_mime_decode($headers['from'], 0, "UTF-8"); $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders($headers); $received->setBodies(array('text' => $text_body, 'html' => $parser->getMessageBody('html'))); $attachments = array(); foreach ($parser->getAttachments() as $attachment) { if (preg_match('@text/(plain|html)@', $attachment->getContentType()) && $attachment->getContentDisposition() == 'inline') { // If this is an "inline" attachment with some sort of text content-type, // do not treat it as a file for attachment. MimeMailParser already picked // it up in the getMessageBody() call above. We still want to treat 'inline' // attachments with other content types (e.g., images) as attachments. continue; } $file = PhabricatorFile::newFromFileData($attachment->getContent(), array('name' => $attachment->getFilename())); $attachments[] = $file->getPHID(); } try { $received->setAttachments($attachments); $received->save();
public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $to = $args->getArg('to'); if (!$to) { throw new PhutilArgumentUsageException(pht("Use '%s' to specify the receiving object or email address.", '--to')); } $to_application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())->setViewer($this->getViewer())->withAddresses(array($to))->executeOne(); $as = $args->getArg('as'); if (!$as && $to_application_email) { $default_phid = $to_application_email->getConfigValue(PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR); if ($default_phid) { $default_user = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withPHIDs(array($default_phid))->executeOne(); if ($default_user) { $as = $default_user->getUsername(); } } } if (!$as) { throw new PhutilArgumentUsageException(pht("Use '--as' to specify the acting user.")); } $user = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withUsernames(array($as))->executeOne(); if (!$user) { throw new PhutilArgumentUsageException(pht("No such user '%s' exists.", $as)); } $from = $args->getArg('from'); if (!$from) { $from = $user->loadPrimaryEmail()->getAddress(); } $console->writeErr("%s\n", pht('Reading message body from stdin...')); $body = file_get_contents('php://stdin'); $received = new PhabricatorMetaMTAReceivedMail(); $header_content = array('Message-ID' => Filesystem::readRandomCharacters(12), 'From' => $from); if (preg_match('/.+@.+/', $to)) { $header_content['to'] = $to; } else { // We allow the user to use an object name instead of a real address // as a convenience. To build the mail, we build a similar message and // look for a receiver which will accept it. $pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y'); $pseudomail = id(new PhabricatorMetaMTAReceivedMail())->setHeaders(array('to' => $to . '+1+' . $pseudohash)); $receivers = id(new PhutilClassMapQuery())->setAncestorClass('PhabricatorMailReceiver')->setFilterMethod('isEnabled')->execute(); $receiver = null; foreach ($receivers as $possible_receiver) { if (!$possible_receiver->canAcceptMail($pseudomail)) { continue; } $receiver = $possible_receiver; break; } if (!$receiver) { throw new Exception(pht("No configured mail receiver can accept mail to '%s'.", $to)); } if (!$receiver instanceof PhabricatorObjectMailReceiver) { $class = get_class($receiver); throw new Exception(pht("Receiver '%s' accepts mail to '%s', but is not a " . "subclass of PhabricatorObjectMailReceiver.", $class, $to)); } $object = $receiver->loadMailReceiverObject($to, $user); if (!$object) { throw new Exception(pht("No such object '%s'!", $to)); } $hash = PhabricatorObjectMailReceiver::computeMailHash($object->getMailKey(), $user->getPHID()); $header_content['to'] = $to . '+' . $user->getID() . '+' . $hash . '@test.com'; } $received->setHeaders($header_content); $received->setBodies(array('text' => $body)); $received->save(); $received->processReceivedMail(); $console->writeErr("%s\n\n phabricator/ \$ ./bin/mail show-inbound --id %d\n\n", pht('Mail received! You can view details by running this command:'), $received->getID()); }