LogoKolab Groupware OBS > Projects
Log In

View File 0011-Create-user-account-on-inbound-email.patch of Package phabricator (Project Infrastructure)

From 69f7bda38840dac3915f5577e9a393463c02bb9d Mon Sep 17 00:00:00 2001
From: "Jeroen van Meeuwen (Kolab Systems)" <vanmeeuwen@kolabsys.com>
Date: Wed, 10 Aug 2016 11:11:56 +0200
Subject: [PATCH 11/15] Create user account on inbound email.

This patch allows an inbound email to create a full, new user account.

This way, Phabricator triggers the initial response ('Maniphest task created'),
and actual subsequent comments and changes to the Maniphest task are sent to the
author of the inbound email that created the ticket.

Create the user account only if there is not a default user account associated with the inbound email address
---
 .../metamta/receiver/PhabricatorMailReceiver.php   | 144 ++++++++++++++++-----
 1 file changed, 114 insertions(+), 30 deletions(-)

diff --git a/src/applications/metamta/receiver/PhabricatorMailReceiver.php b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
index 07d364b..0ec9a6c 100644
--- a/src/applications/metamta/receiver/PhabricatorMailReceiver.php
+++ b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
@@ -94,12 +94,14 @@ abstract class PhabricatorMailReceiver extends Phobject {
    */
   public function loadSender(PhabricatorMetaMTAReceivedMail $mail) {
     $raw_from = $mail->getHeader('From');
-    $from = self::getRawAddress($raw_from);
+    $from = id(new PhutilEmailAddress($raw_from))
+      ->getAddress();
 
     $reasons = array();
 
     // Try to find a user with this email address.
     $user = PhabricatorUser::loadOneWithEmailAddress($from);
+
     if ($user) {
       return $user;
     } else {
@@ -115,9 +117,11 @@ abstract class PhabricatorMailReceiver extends Phobject {
       $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);
+        $reply_to = id(new PhutilEmailAddress($raw_reply_to))
+          ->getAddress();
 
         $user = PhabricatorUser::loadOneWithEmailAddress($reply_to);
+
         if ($user) {
           return $user;
         } else {
@@ -134,34 +138,6 @@ abstract class PhabricatorMailReceiver extends Phobject {
       }
     }
 
-    // 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(
@@ -183,6 +159,53 @@ abstract class PhabricatorMailReceiver extends Phobject {
         $default_user_phid);
     }
 
+    // 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) {
+      if (empty($raw_from) && !empty($raw_reply_to)) {
+        $raw_from = $raw_reply_to;
+      }
+
+      $from = new PhutilEmailAddress($raw_from);
+      $email_address = $from->getAddress();
+      $realname = $from->getDisplayName();
+
+      if (empty($realname)) {
+        $realname = $this->generateRealname();
+      }
+
+      $username = $this->generateUsername($realname);
+
+      $admin = PhabricatorUser::getOmnipotentUser();
+      $user = new PhabricatorUser();
+      $user->setUsername($username);
+      $user->setRealname($realname);
+      $user->setIsApproved(1);
+
+      $email_object = id(new PhabricatorUserEmail())
+        ->setAddress($email_address)
+        ->setIsVerified(1);
+
+      id(new PhabricatorUserEditor())
+        ->setActor($admin)
+        ->createNewUser($user, $email_object);
+
+      //$user->sendWelcomeEmail($admin);
+
+      return $user;
+    } 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);
+    }
+
     $reasons = implode("\n\n", $reasons);
 
     throw new PhabricatorMetaMTAReceivedMailProcessingException(
@@ -268,4 +291,65 @@ abstract class PhabricatorMailReceiver extends Phobject {
     return trim(phutil_utf8_strtolower($address));
   }
 
+  protected function generateRealname() {
+    $realname_generator = new PhutilRealNameContextFreeGrammar();
+    $random_real_name = $realname_generator->generate();
+    return $random_real_name;
+  }
+
+  protected function generateUsername($random_real_name) {
+    $name = strtolower($random_real_name);
+    $name = preg_replace('/[^a-z]/s'  , ' ', $name);
+    $name = preg_replace('/\s+/', ' ', $name);
+    $words = explode(' ', $name);
+    $random = rand(0, 4);
+    $reduced = '';
+    if ($random == 0) {
+      foreach ($words as $w) {
+         if ($w == end($words)) {
+          $reduced .= $w;
+        } else {
+          $reduced .= $w[0];
+        }
+      }
+    } else if ($random == 1) {
+        foreach ($words as $w) {
+          if ($w == $words[0]) {
+            $reduced .= $w;
+          } else {
+            $reduced .= $w[0];
+          }
+        }
+    } else if ($random == 2) {
+        foreach ($words as $w) {
+          if ($w == $words[0] || $w == end($words)) {
+            $reduced .= $w;
+          } else {
+            $reduced .= $w[0];
+          }
+        }
+    } else if ($random == 3) {
+        foreach ($words as $w) {
+          if ($w == $words[0] || $w == end($words)) {
+            $reduced .= $w;
+          } else {
+            $reduced .= $w[0].'.';
+          }
+        }
+      } else if ($random == 4) {
+        foreach ($words as $w) {
+          if ($w == $words[0] || $w == end($words)) {
+            $reduced .= $w;
+          } else {
+            $reduced .= $w[0].'_';
+          }
+        }
+      }
+      $random1 = rand(0, 4);
+      if ($random1 >= 1) {
+        $reduced = ucfirst($reduced);
+      }
+      $username = $reduced;
+      return $username;
+  }
 }
-- 
2.9.3