commit fde83c581d8bb257b1d96f3a5303cc13ba4ae04d Author: root Date: Thu May 25 19:27:35 2017 -0400 initial commit diff --git a/redirect.php b/redirect.php new file mode 100644 index 0000000..cc43641 --- /dev/null +++ b/redirect.php @@ -0,0 +1,378 @@ +#!/usr/bin/php + 'https://hq.palantetech.coop', + 'key' => 'ddGq1iMK1aGMluHVxQu2', + 'unknown-user' => 'create', + 'allow-override' => 'tracker,priority,category,status,project,assigned_to,start_date,due_date,estimated_hours,done_ratio', + 'project' => 'catch', + 'tracker' => 'support', +); + + + +// read from stdin +$fd = fopen("php://stdin", "r"); + +// Loop through the incoming message, one line at a time. +while (!feof($fd)) { + + $line = fgets($fd); + + //if this line is the "delivered-to", extract the subaddress, if there is one. + if(preg_match("/^delivered-to: (.*)/i", $line, $matches)) { + $deliveredTo = $matches[1]; + if(preg_match("/tickets\+(\S*)@/i", $deliveredTo, $matches)) { + $project = $matches[1]; + } + } + + //also extract the "From" address. + if(preg_match("/^from: (.*)/i", $line, $matches)) { + $from = $matches[1]; + } + + //Alter the Subject if this is a test. + $subjectAlterTo = substr($deliveredTo, 1, 12); + if(substr($deliveredTo, 1, 12) == 'tickets-test' && + preg_match("/^Subject:(.*)/i", $line)) { + $line = $subject = str_replace('Subject: ', 'Subject: [TEST] ', $line); + } + + //build the email variable, which is output to Redmine. + $email .= $line; +} +fclose($fd); + +//Handle special cases +//Strip out "auto-generated" from GCal notifications +if($from == 'Google Calendar ') { + $params['unknown-user'] = 'accept'; + $email = str_replace("Auto-Submitted: auto-generated\n", '', $email); +} +//Linode alerts from ramen +if($from == 'Linode Alerts ') { + if(strpos($email, 'Subject: Linode Alert - disk io rate - ramen_ALP')) { + die; + } +} +//Linode alerts from gravy +if($from == 'Linode Alerts ') { + if(strpos($email, 'Subject: Linode Alert - disk io rate - gravy_HQ')) { + die; + } +} +//Any e-mails to tickets+fromwebsite@palantetech.com automatically get sent to tickets+prospecting, but no account is created +if(strpos($deliveredTo, 'tickets+fromwebsite') !== FALSE) { + $project = 'prospecting'; + $params['unknown-user'] = 'accept'; +} +//Any e-mails to tickets+hiring don't get an account created +if(strpos($from, 'tickets+hiring' !== FALSE)) { + $params['unknown-user'] = 'accept'; +} + +// If we don't know the project yet, attempt to determine it from the complete email address. +if(!$project) { + $project = ParseSenderEmail($from); +} +// Still no project? Check the domain of the sender. +if(!$project) { + $project = ParseSenderDomain($from); +} +//Add the project code (if applicable). +if($project) { + $params['project'] = $project; +} + +if($debugMode) { + // debug code + $email .= "\n\nDelivered To - $deliveredTo\n"; + $email .= "Project - $project\n"; + $email .= "From - $from\n"; + $email .= "Subject - $subject\n"; + $email .= "Params:\n"; + $email .= print_r($params, TRUE); + $debugFileName = '/tmp/EmailProcessing' . time(); + echo "$debugFileName"; + $debugFile = fopen($debugFileName, 'w'); + fwrite($debugFile, $email); + fclose($debugFile); + // also print to stdout, in case we're running manually + echo $email; +} + +if(!$dryRun) { + SendToMailHandler($email, $params); +} + +// Send to Ruby mailhandler. +function SendToMailHandler($input, $params) { + + $descriptorspec = array( + 0 => array("pipe", "r"), // stdin is a pipe that the child will read from + 1 => array("pipe", "w"), // stdout is a pipe that the child will write to + 2 => array("pipe", "w"), // stderr is a pipe that the child will write to + ); + $process = proc_open("/usr/local/bin/rdm-mailhandler.rb --url={$params['url']} --key={$params['key']} --unknown-user={$params['unknown-user']} --no-permission-check --allow-override={$params['allow-override']} --project {$params['project']} --tracker {$params['tracker']}", $descriptorspec, $pipes); + + if (is_resource($process)) { + // $pipes now looks like this: + // 0 => writeable handle connected to child stdin + // 1 => readable handle connected to child stdout + // Any error output will be appended to /tmp/error-output.txt + + fwrite($pipes[0], $input); + fclose($pipes[0]); + + echo stream_get_contents($pipes[1]); + $errorMessage = stream_get_contents($pipes[2]); + fclose($pipes[1]); + fclose($pipes[2]); + + // It is important that you close any pipes before calling + // proc_close in order to avoid a deadlock + $return_value = proc_close($process); + + // Log errors, also display on screen and send an email + if($return_value) { + echo $errorMessage; + $log = "Redmine redirect error: $errorMessage"; + syslog(LOG_ERR, $log); + + $to = "team@lists.palantetech.coop"; + $subject = "Redmine email routing failure"; + $message = $log . "\n\n"; + $message .= $input; + mail($to, $subject, $message); + } + + echo "command returned $return_value\n"; + } + +} + +//See if this email address is associated with a particular project +function ParseSenderEmail($from) { + $project = $email = NULL; + if(preg_match("/\b([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b/i", $from, $matches)) { + $email = $matches[1]; + } + switch($email) { + case "ezra.berkley.nepon@gmail.com ": + $project = "astraea"; + break; + case "larryg601@gmail.com": + $project = "nwu"; + break; + case "director.npap@nlg.org": + $project = "npap"; + break; + case "jgazis@legalmomentum.org": + $project = "lm"; + break; + case "stephenrshalom@gmail.com": + $project = "newpolitics-web"; + break; + case "ari.gardeningmatters@gmail.com": + case "mallory.gardeningmatters@gmail.com": + case "susan.gardeningmatters@gmail.com": + case "heimsteadlenief@gmail.com": + $project = "gm-civi"; + break; + //the following emails will not go into Redmine, and will cause an NDR to go to the sender. + case "postmaster@urbanjustice.org": + case "billing@linode.com": + echo "dying"; + die; + } + return $project; +} + +function ParseSenderDomain($email) { + $domain = $project = NULL; + if(preg_match("/@(.*)\b/", $email, $matches)) { + $domain = $matches[1]; + } + switch($domain) { + case "legalmomentum.org": + $project = "lm-tech"; + break; + case "nlg.org": + $project = "nlg"; + break; + case "furee.org": + $project = "furee"; + break; + case "opencenter.org": + $project = "opencenter-tech"; + break; + case "vocal-ny.org": + $project = "vocal"; + break; + case "rffny.org": + $project = "rff"; + break; + case "domesticworkersunited.org": + $project = "dwu-tech"; + break; + case "thirdwavefoundation.org": + $project = "twf-tech"; + break; + case "picturethehomeless.org": + $project = "pth"; + break; + case "changethenypd.org": + $project = "cpr"; + break; + case "neweconomynyc.org": + $project = "nedap-tech"; + break; + case "cpehn.org": + $project = "cpehn-civi"; + break; + case "streetwiseandsafe.org": + $project = "sas-tech"; + break; + case "nwu.org": + $project = "nwu-civi"; + break; + case "tandn.org": + $project = "tan"; + break; + case "foodlabdetroit.com": + $project = "foodlab"; + break; + case "urbanjustice.org": + $project = "ujc"; + break; + case "healthcare-now.org": + $project = "hcn-civi"; + break; + case "global-action.org": + $project = "gap"; + break; + case "aclusandiego.org": + $project = "aclusdic-civi"; + break; + case "madre.org": + $project = "madre-tech"; + break; + case "goles.org": + $project = "goles-tech"; + break; + case "srlp.org": + $project = "srlp"; + break; + case "ppnorcal.org": + $project = "ppsp"; + break; + case "caeny.org": + $project = "cae-tech"; + break; + case "ccrjustice.org": + $project = "ccr-civi"; + break; + case "rainforestfund.org": + $project = "rfu-tech"; + break; + case "nlgsf.org": + $project = "nlgsf-civi"; + break; + case "warresisters.org": + $project = "wrl"; + break; + case "gender.town": + $project = "msp"; + break; + case "gsanetwork.org": + $project = "gsa"; + break; + case "culturestrike.org": + $project = "cs-dmp"; + break; + case "lawyerscommittee.org": + $project = "lccr-civi"; + break; + case "ppnyc.org": + $project = "ppnyc"; + break; + case "lavabrooklyn.org": + $project = "lava-civi"; + break; + case "soex.org": + $project = "soex"; + break; + case "woolman.org": + $project = "woolman"; + break; + case "bikesnotbombs.org": + $project = "bnb"; + break; + case "labornotes.org": + $project = "labor-notes"; + break; + case "cbadley.com": + $project = "sm"; + break; + case "lamama.org": + $project = "lamama-tech"; + break; + case "populardemocracy.org": + $project = "cpd"; + break; + case "searac.org": + $project = "searac-d6"; + break; + case "pprm.org": + $project = "pprm-adap"; + break; + case "africans.us": + $project = "act"; + break; + case "campaignlegalcenter.org": + $project = "clc"; + break; + case "advancingjustice-aajc.org": + $project = "aajc-drupal-support"; + break; + case "bikeeastbay.org": + $project = "beb-dcvmp"; + break; + case "movetoamend.org": + $project = "mta-drupal"; + break; + case "raceforward.org": + $project = "race-forward-drupal-support"; + break; + case "gardeningmatters.org": + $project = "gm-civi"; + break; + case "eastbaymeditation.org": + $project = "ebmc-cvwmp"; + break; + case "aorta.coop": + $project = "aorta-tech"; + break; + //put spam domain entries here + case "allverbia.xyz": + case "tandn.org": + echo "dying"; + die; + } + return $project; +} + +?>