Prevent same user to make the same request again

Signed-off-by: Eric Poirier <eric@eclipse.org>
diff --git a/eclipse.org-common/classes/users/siteLogin.class.php b/eclipse.org-common/classes/users/siteLogin.class.php
index d7f5875..364f30d 100644
--- a/eclipse.org-common/classes/users/siteLogin.class.php
+++ b/eclipse.org-common/classes/users/siteLogin.class.php
@@ -426,7 +426,10 @@
   }
 
   private function _confirmAccount() {
-    $sql = "SELECT /* USE MASTER */ COUNT(1) AS RecordCount FROM account_requests WHERE token IN ('TOKEN_FAILED', 'CONFIRM_SUCCESS') AND  ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
+    $sql = "SELECT /* USE MASTER */ COUNT(1) AS RecordCount
+        FROM account_requests
+        WHERE token IN ('TOKEN_FAILED', 'CONFIRM_SUCCESS')
+        AND  ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
     $rs = $this->App->eclipse_sql($sql);
     $myrow = mysql_fetch_assoc($rs);
     if ($myrow['RecordCount'] > 0) {
@@ -505,15 +508,35 @@
         mail('webmaster@eclipse.org', "Denied Account: Possible spammer", $mail, $headers);
         return FALSE;
       }
-      # Create an account.  Check to ensure this IP address hasn't flooded us with requests
-      # or that this email address doesn't already have an account
-      $sql = "SELECT /* USE MASTER */ COUNT(1) AS RecordCount FROM account_requests WHERE ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
+
+      // Select entries that are only created on an account creation
+      $sql = "SELECT /* USE MASTER */ email
+                      FROM account_requests
+                      WHERE ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']) . "
+                      AND fname NOT IN ('MAILCHANGE','RESET')
+                      AND lname NOT IN ('MAILCHANGE','RESET')
+                      AND password = ''
+                      AND new_email = ''
+                      AND token NOT IN ('CLA_SIGNED','CLA_INVALIDATED','TOKEN_FAILED')";
       $rs = $this->App->eclipse_sql($sql);
-      $myrow = mysql_fetch_assoc($rs);
-      if ($myrow['RecordCount'] >= 25) {
+
+      $list_of_emails = array();
+      while ($row = mysql_fetch_array($rs)) {
+        $list_of_emails[] = $row['email'];
+      }
+
+      // Check if there are more than 25 request coming from the same ip address
+      if (count($list_of_emails) >= 25) {
         $this->messages['create']['danger'][] = "You have already submitted a request. Please check your email inbox and spam folders to respond to the previous request. (8723s)";
       }
-      else {
+
+      // Check if there are more than one request from the same email address
+      if (!empty($list_of_emails) && in_array($this->username, $list_of_emails)) {
+        $this->messages['create']['danger'][] = "You have already submitted a request. Please check your email inbox and spam folders to respond to the previous request. (8724s)";
+      }
+
+      // If there are no errors, we can insert in the account_request table
+      if (empty($this->messages['create']['danger'])) {
         # Check LDAP
         if(!$this->Ldapconn->checkEmailAvailable($this->username)) {
           $this->messages['create']['danger'][] = "That account already exists.  If you cannot remember your password, please use the password reset option below.  (8725s)";
@@ -1002,15 +1025,29 @@
               $this->messages['myaccount']['danger'][] = "- Your email address is not formatted correctly<br />";
             }
             else {
-              # Check that someone isn't piling on a bunch of requests for mail changes just to piss everyone off
-              $sql = "SELECT /* USE MASTER */ COUNT(1) AS RecordCount FROM account_requests WHERE ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
-              $sql .= "OR email = " . $this->App->returnQuotedString($oldmail);
+              $sql = "SELECT /* USE MASTER */ email
+                      FROM account_requests
+                      WHERE ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']) . "
+                      AND fname = 'MAILCHANGE'
+                      AND lname = 'MAILCHANGE'";
               $rs = $this->App->eclipse_sql($sql);
-              $myrow = mysql_fetch_assoc($rs);
-              if ($myrow['RecordCount'] > 3) {
+
+              $list_of_emails = array();
+              while ($row = mysql_fetch_array($rs)) {
+                $list_of_emails[] = $row['email'];
+              }
+
+              // Check if there are more than 3 request coming from the same ip address
+              if (count($list_of_emails) > 3) {
                 $this->messages['myaccount']['danger'][] = "<b>You have already submitted a request. Please check your email inbox and spam folders to respond to the previous request.</b>";
               }
-              else {
+
+              // Check if there are more than one request from the same email address
+              if (!empty($list_of_emails) && in_array($this->username, $list_of_emails)) {
+                $this->messages['myaccount']['danger'][] = "<b>You have already submitted a request. Please check your email inbox and spam folders to respond to the previous request.</b>";
+              }
+
+              if (empty($this->messages['myaccount']['danger'])) {
                 # Toss in a request to change the email address
                 $this->messages['myaccount']['success'][] = " Please check your Inbox for a confirmation email with instructions to complete the email address change.  Your email address will not be updated until the process is complete.";
                 $this->t = $this->t = $this->App->getAlphaCode(64);
@@ -1037,7 +1074,8 @@
                 $this->_sendNotice("Email address","from: " . $oldmail . " to: " . $this->username );
               }
             }
-          }  else if ($this->is_committer && $this->changed_employer === "") {
+          }
+          else if ($this->is_committer && $this->changed_employer === "") {
             $this->messages['myaccount']['danger'][] = "You must indicate if you have changed employers in order to save changes to your email address.";
             return;
           }
@@ -1068,53 +1106,73 @@
     # reset stage 1.  We got an email address, create token and email to user
     # make sure someone isn't blasting us.  We disregard "token failed" since a common use-case
     # is to click the reset link after it has expired.
-    $sql = "SELECT /* USE MASTER */ COUNT(1) AS RecordCount FROM account_requests WHERE token <> 'TOKEN_FAILED' AND fname = 'RESET' AND lname = 'RESET' AND ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
+    $sql = "SELECT /* USE MASTER */ email
+        FROM account_requests
+        WHERE token <> 'TOKEN_FAILED'
+        AND fname = 'RESET'
+        AND lname = 'RESET'
+        AND ip = " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']);
     $rs = $this->App->eclipse_sql($sql);
-    $myrow = mysql_fetch_assoc($rs);
-    if ($myrow['RecordCount'] >= 13) {
+
+    $list_of_emails = array();
+    while ($row = mysql_fetch_array($rs)) {
+      $list_of_emails[] = $row['email'];
+    }
+
+    // Check if a valid email has been provided
+    if (!preg_match(SITELOGIN_EMAIL_REGEXP, $this->username)) {
+      $this->messages['reset']['danger'][] = "<b>Your email address is not formatted correctly.</b><br />";
+    }
+
+    // Check if the provided email is in LDAP
+    if ($this->Ldapconn->checkEmailAvailable($this->username)) {
+      $this->messages['reset']['danger'][] = "<b>We were unable to determine your identity with the information you've supplied.</b>  Perhaps you don't have an Eclipse.org account, or your account is under a different email address.(8x27s)";
+    }
+
+    // Check if there are more than 13 request coming from the same ip address
+    if (count($list_of_emails) >= 13) {
       $this->messages['reset']['danger'][] = "<b>We were unable to determine your identity after several attempts. Subsequent inquiries will be ignored for our protection.  Please try later, or contact webmaster@eclipse.org for support.</b>  (8727s)";
     }
-    else {
-      if (!preg_match(SITELOGIN_EMAIL_REGEXP, $this->username)) {
-        $this->messages['reset']['danger'][] = "<b>Your email address is not formatted correctly.</b><br />";
-      }
-      elseif ($this->Ldapconn->checkEmailAvailable($this->username)) {
-        $this->messages['reset']['danger'][] = "<b>We were unable to determine your identity with the information you've supplied.</b>  Perhaps you don't have an Eclipse.org account, or your account is under a different email address.(8x27s)";
-      }
-      else {
-        # Check to see if we're trying to reset the password of a valid account.
-        $this->t = $this->App->getAlphaCode(64);
-        $this->App->eclipse_sql("INSERT IGNORE INTO account_requests VALUES (" . $this->App->returnQuotedString($this->App->sqlSanitize($this->username)) . ",
-        '',
-        " . $this->App->returnQuotedString("RESET") . ",
-        " . $this->App->returnQuotedString("RESET") . ",
-        '',
-        " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']) . ",
-        NOW(),
-        " . $this->App->returnQuotedString($this->t) . ")");
 
-        # Send mail to dest
-        $mail = "You (or someone pretending to be you) has requested a password reset from:\n";
-        $mail .= "    " . $_SERVER['REMOTE_ADDR'] . "\n\n";
-        $mail .= "To change your password, please visit this URL:\nhttps://dev.eclipse.org/site_login/token.php?p=p&t=$this->t\n\n";
-        $mail .= "If you have not requested this change, you can safely let it expire.  If you have any problems signing in please contact webmaster@eclipse.org\n\n";
-        $mail .= " -- Eclipse webmaster\n";
-        $headers = 'From: Eclipse Webmaster (automated) <webmaster@eclipse.org>';
-        mail($this->username, "Eclipse Account Password Reset", $mail, $headers);
-        $this->messages['reset']['success'][] = '<strong>Password Recovery:</strong> A token has been emailed to you to allow
-        you to reset your Eclipse.org password.  Please check your Trash and Junk/Spam
-        folders if you do not see this email in your inbox.';
+    // Check if there are more than one request from the same email address
+    if (!empty($list_of_emails) && in_array($this->username, $list_of_emails)) {
+      $this->messages['reset']['danger'][] = "<b>There's already a reset password request associated to this email address. Please try later, or contact webmaster@eclipse.org for support.</b> (8728s)";
+    }
 
-        # Debug
-        //print $mail;
+    // If there are no errors we can proceed
+    if (empty($this->messages['reset']['danger'])) {
+      # Check to see if we're trying to reset the password of a valid account.
+      $this->t = $this->App->getAlphaCode(64);
+      $this->App->eclipse_sql("INSERT IGNORE INTO account_requests VALUES (" . $this->App->returnQuotedString($this->App->sqlSanitize($this->username)) . ",
+      '',
+      " . $this->App->returnQuotedString("RESET") . ",
+      " . $this->App->returnQuotedString("RESET") . ",
+      '',
+      " . $this->App->returnQuotedString($_SERVER['REMOTE_ADDR']) . ",
+      NOW(),
+      " . $this->App->returnQuotedString($this->t) . ")");
 
-        $EventLog = new EvtLog();
-        $EventLog->setLogTable("__ldap");
-        $EventLog->setPK1($this->t);
-        $EventLog->setPK2($_SERVER['REMOTE_ADDR']);
-        $EventLog->setLogAction("PASSWD_RESET_REQ");
-        $EventLog->insertModLog($this->username);
-      }
+      # Send mail to dest
+      $mail = "You (or someone pretending to be you) has requested a password reset from:\n";
+      $mail .= "    " . $_SERVER['REMOTE_ADDR'] . "\n\n";
+      $mail .= "To change your password, please visit this URL:\nhttps://dev.eclipse.org/site_login/token.php?p=p&t=$this->t\n\n";
+      $mail .= "If you have not requested this change, you can safely let it expire.  If you have any problems signing in please contact webmaster@eclipse.org\n\n";
+      $mail .= " -- Eclipse webmaster\n";
+      $headers = 'From: Eclipse Webmaster (automated) <webmaster@eclipse.org>';
+      mail($this->username, "Eclipse Account Password Reset", $mail, $headers);
+      $this->messages['reset']['success'][] = '<strong>Password Recovery:</strong> A token has been emailed to you to allow
+      you to reset your Eclipse.org password.  Please check your Trash and Junk/Spam
+      folders if you do not see this email in your inbox.';
+
+      # Debug
+      //print $mail;
+
+      $EventLog = new EvtLog();
+      $EventLog->setLogTable("__ldap");
+      $EventLog->setPK1($this->t);
+      $EventLog->setPK2($_SERVER['REMOTE_ADDR']);
+      $EventLog->setLogAction("PASSWD_RESET_REQ");
+      $EventLog->insertModLog($this->username);
     }
   }