/**
  * Although this function actually does the filtering, as this is a singleton pattern
  * we only want one instance actually using it.
  *
  * @return bool false if we should stop processing
  */
 private function filter()
 {
     $user_ip = $this->gateway_adapter->getData_Unstaged_Escaped('user_ip');
     // Determine IP status before doing anything complex
     $wl = DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPWhitelist'));
     $bl = DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPBlacklist'));
     if ($wl) {
         $this->gateway_adapter->debugarray[] = "SessionVelocity: IP present in whitelist.";
         return true;
     }
     if ($bl) {
         $this->gateway_adapter->debugarray[] = "SessionVelocity: IP present in blacklist.";
         return false;
     }
     // Open a session if it doesn't already exist
     $this->gateway_adapter->session_ensure();
     // Obtain some useful information
     $gateway = $this->gateway_adapter->getIdentifier();
     $transaction = $this->gateway_adapter->getCurrentTransaction();
     $cRequestTime = $_SERVER['REQUEST_TIME'];
     $decayRate = $this->getVar('DecayRate', $transaction);
     $threshold = $this->getVar('Threshold', $transaction);
     $multiplier = $this->getVar('Multiplier', $transaction);
     // Initialize the filter
     $sessionData = WmfFramework::getSessionValue(self::SESS_ROOT);
     if (!is_array($sessionData)) {
         $sessionData = array();
     }
     if (!array_key_exists($gateway, $sessionData)) {
         $sessionData[$gateway] = array();
     }
     if (!array_key_exists($transaction, $sessionData[$gateway])) {
         $sessionData[$gateway][$transaction] = array($this::SESS_SCORE => 0, $this::SESS_TIME => $cRequestTime, $this::SESS_MULTIPLIER => 1);
     }
     $lastTime = $sessionData[$gateway][$transaction][self::SESS_TIME];
     $score = $sessionData[$gateway][$transaction][self::SESS_SCORE];
     $lastMultiplier = $sessionData[$gateway][$transaction][self::SESS_MULTIPLIER];
     // Update the filter if it's stale
     if ($cRequestTime != $lastTime) {
         $score = max(0, $score - ($cRequestTime - $lastTime) * $decayRate);
         $score += $this->getVar('HitScore', $transaction) * $lastMultiplier;
         $sessionData[$gateway][$transaction][$this::SESS_SCORE] = $score;
         $sessionData[$gateway][$transaction][$this::SESS_TIME] = $cRequestTime;
         $sessionData[$gateway][$transaction][$this::SESS_MULTIPLIER] = $lastMultiplier * $multiplier;
     }
     // Store the results
     WmfFramework::setSessionValue(self::SESS_ROOT, $sessionData);
     // Analyze the filter results
     if ($score >= $threshold) {
         // Ahh!!! Failure!!! Sloooooooow doooowwwwnnnn
         $this->fraud_logger->alert("SessionVelocity: Rejecting request due to score of {$score}");
         $this->sendAntifraudMessage('reject', $score, array('SessionVelocity' => $score));
         $retval = false;
     } else {
         $retval = true;
     }
     $this->fraud_logger->debug("SessionVelocity: ({$gateway}, {$transaction}) Score: {$score}, " . "AllowAction: {$retval}, DecayRate: {$decayRate}, " . "Threshold: {$threshold}, Multiplier: {$lastMultiplier}");
     return $retval;
 }
 protected function filter()
 {
     $user_ip = $this->gateway_adapter->getData_Unstaged_Escaped('user_ip');
     //first, handle the whitelist / blacklist before you do anything else.
     if (DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPWhitelist'))) {
         $this->gateway_adapter->debugarray[] = "IP present in whitelist.";
         $this->cfo->addRiskScore(0, 'IPWhitelist');
         return true;
     }
     // TODO: this blacklist business should happen elsewhere, and on every hit.
     if (DataValidator::ip_is_listed($user_ip, $this->gateway_adapter->getGlobal('IPBlacklist'))) {
         $this->gateway_adapter->debugarray[] = "IP present in blacklist.";
         $this->cfo->addRiskScore($this->gateway_adapter->getGlobal('IPVelocityFailScore'), 'IPBlacklist');
         return true;
     }
     //if the user ip was in neither list, check the velocity.
     if ($this->connectToMemcache()) {
         $stored = $this->getMemcachedValue();
         if (!$stored) {
             //we don't have anything in memcache for this dude yet.
             $this->gateway_adapter->debugarray[] = "Found no memcached data for {$user_ip}";
             $this->cfo->addRiskScore(0, 'IPVelocityFilter');
             //want to see the explicit zero
             return true;
         } else {
             $count = count($stored);
             $this->gateway_adapter->debugarray[] = "Found a memcached bit of data for {$user_ip}: " . print_r($stored, true);
             $this->gateway_logger->info("IPVelocityFilter: {$user_ip} has {$count} hits");
             if ($count >= $this->gateway_adapter->getGlobal('IPVelocityThreshhold')) {
                 $this->cfo->addRiskScore($this->gateway_adapter->getGlobal('IPVelocityFailScore'), 'IPVelocityFilter');
                 //cool off, sucker. Muahahaha.
                 $this->addNowToMemcachedValue($stored, true);
             } else {
                 $this->cfo->addRiskScore(0, 'IPVelocityFilter');
                 //want to see the explicit zero here, too.
             }
         }
     }
     //fail open, in case memcached doesn't work.
     return true;
 }