@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 110 lines 3.3 kB view raw
1<?php 2 3final class PhabricatorMetaMTAMailgunReceiveController 4 extends PhabricatorMetaMTAController { 5 6 public function shouldRequireLogin() { 7 return false; 8 } 9 10 private function verifyMessage() { 11 $request = $this->getRequest(); 12 $timestamp = $request->getStr('timestamp'); 13 $token = $request->getStr('token'); 14 $sig = $request->getStr('signature'); 15 16 // An install may configure multiple Mailgun mailers, and we might receive 17 // inbound mail from any of them. Test the signature to see if it matches 18 // any configured Mailgun mailer. 19 20 $mailers = PhabricatorMetaMTAMail::newMailers( 21 array( 22 'inbound' => true, 23 'types' => array( 24 PhabricatorMailMailgunAdapter::ADAPTERTYPE, 25 ), 26 )); 27 foreach ($mailers as $mailer) { 28 $api_key = $mailer->getOption('api-key'); 29 $hash = hash_hmac('sha256', $timestamp.$token, $api_key); 30 if (phutil_hashes_are_identical($sig, $hash)) { 31 return true; 32 } 33 } 34 35 return false; 36 } 37 38 public function handleRequest(AphrontRequest $request) { 39 40 // No CSRF for Mailgun. 41 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 42 43 if (!$this->verifyMessage()) { 44 throw new Exception( 45 pht('Mail signature is not valid. Check your Mailgun API key.')); 46 } 47 48 $raw_headers = $request->getStr('message-headers'); 49 $raw_dict = array(); 50 if (strlen($raw_headers)) { 51 $raw_headers = phutil_json_decode($raw_headers); 52 foreach ($raw_headers as $raw_header) { 53 list($name, $value) = $raw_header; 54 $raw_dict[$name] = $value; 55 } 56 } 57 58 $headers = array( 59 'to' => $request->getStr('recipient'), 60 'from' => $request->getStr('from'), 61 'subject' => $request->getStr('subject'), 62 ) + $raw_dict; 63 64 $received = new PhabricatorMetaMTAReceivedMail(); 65 $received->setHeaders($headers); 66 $received->setBodies(array( 67 'text' => $request->getStr('stripped-text'), 68 'html' => $request->getStr('stripped-html'), 69 )); 70 71 $file_phids = array(); 72 foreach ($_FILES as $file_raw) { 73 try { 74 $file = PhabricatorFile::newFromPHPUpload( 75 $file_raw, 76 array( 77 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 78 )); 79 $file_phids[] = $file->getPHID(); 80 } catch (Exception $ex) { 81 phlog($ex); 82 } 83 } 84 $received->setAttachments($file_phids); 85 86 try { 87 $received->save(); 88 $received->processReceivedMail(); 89 } catch (Exception $ex) { 90 // We can get exceptions here in two cases. 91 92 // First, saving the message may throw if we have already received a 93 // message with the same Message ID. In this case, we're declining to 94 // process a duplicate message, so failing silently is correct. 95 96 // Second, processing the message may throw (for example, if it contains 97 // an invalid !command). This will generate an email as a side effect, 98 // so we don't need to explicitly handle the exception here. 99 100 // In these cases, we want to return HTTP 200. If we do not, MailGun will 101 // re-transmit the message later. 102 phlog($ex); 103 } 104 105 $response = new AphrontWebpageResponse(); 106 $response->setContent(pht("Got it! Thanks, Mailgun!\n")); 107 return $response; 108 } 109 110}