/** * Returns true if we must fail fast and return an error message. * * @param string $username * @param string $ip * @param string $action * @return bool */ public function failFast(string $username, string $ip, string $action = self::ACTION_LOGIN) : bool { if (!$this->getFastExit()) { return false; } // Get the current time and the anticipated delay. $date = new \DateTime('NOW'); $delay = $this->getDelay($username, $ip, $action); if ($delay === 0) { return false; } $delay = \intdiv($delay, 1000); // Returns TRUE if the user hasn't waited long enough. return $this->db->exists('SELECT count(*) FROM airship_failed_logins WHERE action = ? AND ( username = ? OR subnet = ? ) AND occurred > ? ', $action, $username, $this->getSubnet($ip), $date->sub($this->getCutoff($delay))->format(\AIRSHIP_DATE_FORMAT)); }