Adds rate limiting to the user class

main
Yasen Pramatarov 2024-12-07 15:32:28 +02:00
parent 626fc4ba2b
commit fee0616ca4
1 changed files with 21 additions and 3 deletions

View File

@ -10,6 +10,7 @@ class User {
* @var PDO|null $db The database connection instance. * @var PDO|null $db The database connection instance.
*/ */
private $db; private $db;
private $ratelimiter;
/** /**
* User constructor. * User constructor.
@ -19,6 +20,7 @@ class User {
*/ */
public function __construct($database) { public function __construct($database) {
$this->db = $database->getConnection(); $this->db = $database->getConnection();
$this->ratelimiter = new RateLimiter($database);
} }
@ -88,6 +90,15 @@ class User {
* @return bool True if login is successful, false otherwise. * @return bool True if login is successful, false otherwise.
*/ */
public function login($username, $password) { public function login($username, $password) {
// get client IP address
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
// check rate limiting
if (!$this->rateLimiter->attempt($username, $ipAddress)) {
$remainingTime = $this->rateLimiter->getDecayMinutes();
throw new Exception("Too many login attempts. Please try again in {$remainingTime} minutes.");
}
$query = $this->db->prepare("SELECT * FROM users WHERE username = :username"); $query = $this->db->prepare("SELECT * FROM users WHERE username = :username");
$query->bindParam(':username', $username); $query->bindParam(':username', $username);
$query->execute(); $query->execute();
@ -97,8 +108,15 @@ class User {
$_SESSION['user_id'] = $user['id']; $_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username']; $_SESSION['username'] = $user['username'];
return true; return true;
}
// Login failed, return remaining attempts info
$remainingAttempts = $this->rateLimiter->getRemainingAttempts($username, $ipAddress);
if ($remainingAttempts > 0) {
throw new Exception("Invalid credentials. {$remainingAttempts} attempts remaining.");
} else { } else {
return false; $remainingTime = $this->rateLimiter->getDecayMinutes();
throw new Exception("Too many login attempts. Please try again in {$remainingTime} minutes.");
} }
} }