| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-20 08:41:14 +00:00
										 |  |  | require_once dirname(__DIR__, 3) . '/app/classes/database.php'; | 
					
						
							|  |  |  | require_once dirname(__DIR__, 3) . '/app/classes/ratelimiter.php'; | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  | require_once dirname(__DIR__, 3) . '/app/classes/log.php'; | 
					
						
							| 
									
										
										
										
											2025-02-20 08:41:14 +00:00
										 |  |  | require_once dirname(__DIR__, 3) . '/app/includes/rate_limit_middleware.php'; | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | use PHPUnit\Framework\TestCase; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RateLimitMiddlewareTest extends TestCase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     private $db; | 
					
						
							|  |  |  |     private $rateLimiter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function setUp(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::setUp(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Set global IP for rate limiting
 | 
					
						
							|  |  |  |         global $user_IP; | 
					
						
							|  |  |  |         $user_IP = '8.8.8.8'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Prepare DB for Github CI
 | 
					
						
							|  |  |  |         $host = defined('CI_DB_HOST') ? CI_DB_HOST : '127.0.0.1'; | 
					
						
							|  |  |  |         $password = defined('CI_DB_PASSWORD') ? CI_DB_PASSWORD : ''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         // Set up test database
 | 
					
						
							|  |  |  |         $this->db = new Database([ | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             'type' => 'mariadb', | 
					
						
							|  |  |  |             'host' => $host, | 
					
						
							|  |  |  |             'port' => '3306', | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  |             'dbname' => 'jilo_test', | 
					
						
							|  |  |  |             'user' => 'test_jilo', | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             'password' => $password | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Create rate limiter instance
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         $this->rateLimiter = new RateLimiter($this->db); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Drop tables if they exist
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS security_rate_auth"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS security_rate_page"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS security_ip_blacklist"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS security_ip_whitelist"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS log"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Create required tables with correct names from RateLimiter class
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             CREATE TABLE IF NOT EXISTS security_rate_auth ( | 
					
						
							|  |  |  |                 id INT PRIMARY KEY AUTO_INCREMENT, | 
					
						
							|  |  |  |                 ip_address VARCHAR(45) NOT NULL, | 
					
						
							|  |  |  |                 username VARCHAR(255) NOT NULL, | 
					
						
							|  |  |  |                 attempted_at DATETIME DEFAULT CURRENT_TIMESTAMP, | 
					
						
							|  |  |  |                 INDEX idx_ip_username (ip_address, username) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             CREATE TABLE IF NOT EXISTS security_rate_page ( | 
					
						
							|  |  |  |                 id INT PRIMARY KEY AUTO_INCREMENT, | 
					
						
							|  |  |  |                 ip_address VARCHAR(45) NOT NULL, | 
					
						
							|  |  |  |                 endpoint VARCHAR(255) NOT NULL, | 
					
						
							|  |  |  |                 request_time DATETIME DEFAULT CURRENT_TIMESTAMP, | 
					
						
							|  |  |  |                 INDEX idx_ip_endpoint (ip_address, endpoint), | 
					
						
							|  |  |  |                 INDEX idx_request_time (request_time) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             CREATE TABLE IF NOT EXISTS security_ip_blacklist ( | 
					
						
							|  |  |  |                 id INT PRIMARY KEY AUTO_INCREMENT, | 
					
						
							|  |  |  |                 ip_address VARCHAR(45) NOT NULL, | 
					
						
							|  |  |  |                 is_network BOOLEAN DEFAULT FALSE, | 
					
						
							|  |  |  |                 reason VARCHAR(255), | 
					
						
							|  |  |  |                 expiry_time TIMESTAMP NULL, | 
					
						
							|  |  |  |                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | 
					
						
							|  |  |  |                 created_by VARCHAR(255), | 
					
						
							|  |  |  |                 UNIQUE KEY unique_ip (ip_address) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             CREATE TABLE IF NOT EXISTS security_ip_whitelist ( | 
					
						
							|  |  |  |                 id INT PRIMARY KEY AUTO_INCREMENT, | 
					
						
							|  |  |  |                 ip_address VARCHAR(45) NOT NULL, | 
					
						
							|  |  |  |                 is_network BOOLEAN DEFAULT FALSE, | 
					
						
							|  |  |  |                 description VARCHAR(255), | 
					
						
							|  |  |  |                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | 
					
						
							|  |  |  |                 created_by VARCHAR(255), | 
					
						
							|  |  |  |                 UNIQUE KEY unique_ip (ip_address) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Create log table
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             CREATE TABLE IF NOT EXISTS log ( | 
					
						
							|  |  |  |                 id INT PRIMARY KEY AUTO_INCREMENT, | 
					
						
							|  |  |  |                 user_id INT, | 
					
						
							|  |  |  |                 scope VARCHAR(50) NOT NULL, | 
					
						
							|  |  |  |                 message TEXT NOT NULL, | 
					
						
							|  |  |  |                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Mock $_SERVER['REMOTE_ADDR'] with a non-whitelisted IP
 | 
					
						
							|  |  |  |         $_SERVER['REMOTE_ADDR'] = '8.8.8.8'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Define PHPUNIT_RUNNING constant
 | 
					
						
							|  |  |  |         if (!defined('PHPUNIT_RUNNING')) { | 
					
						
							|  |  |  |             define('PHPUNIT_RUNNING', true); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function tearDown(): void | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean up all rate limit records
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_ip_blacklist"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_ip_whitelist"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_auth"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE log"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         parent::tearDown(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRateLimitMiddleware() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean any existing rate limit records
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Make 60 requests to reach the limit
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 60; $i++) { | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             $this->assertTrue($result, "Request $i should be allowed"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             // Verify request was recorded
 | 
					
						
							|  |  |  |             $stmt = $this->db->getConnection()->prepare("
 | 
					
						
							|  |  |  |                 SELECT COUNT(*) as count | 
					
						
							|  |  |  |                 FROM security_rate_page | 
					
						
							|  |  |  |                 WHERE ip_address = ? | 
					
						
							|  |  |  |                 AND endpoint = ? | 
					
						
							|  |  |  |                 AND request_time >= DATE_SUB(NOW(), INTERVAL 1 MINUTE) | 
					
						
							|  |  |  |             ");
 | 
					
						
							|  |  |  |             $stmt->execute(['8.8.8.8', '/login']); | 
					
						
							|  |  |  |             $count = $stmt->fetch(PDO::FETCH_ASSOC)['count']; | 
					
						
							|  |  |  |             $this->assertEquals($i + 1, $count, "Expected " . ($i + 1) . " requests to be recorded, got {$count}"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // The 61st request should be blocked
 | 
					
						
							|  |  |  |         $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |         $this->assertFalse($result, "Request should be blocked after 60 requests"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRateLimitBypass() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean any existing rate limit records and lists
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_ip_whitelist"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_ip_blacklist"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add IP to whitelist and verify it was added
 | 
					
						
							|  |  |  |         $stmt = $this->db->getConnection()->prepare("INSERT INTO security_ip_whitelist (ip_address, is_network, description, created_by) VALUES (?, 0, ?, 'PHPUnit')"); | 
					
						
							|  |  |  |         $stmt->execute(['8.8.8.8', 'Test whitelist']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Verify IP is in whitelist
 | 
					
						
							|  |  |  |         $stmt = $this->db->getConnection()->prepare("SELECT COUNT(*) as count FROM security_ip_whitelist WHERE ip_address = ?"); | 
					
						
							|  |  |  |         $stmt->execute(['8.8.8.8']); | 
					
						
							|  |  |  |         $count = $stmt->fetch(PDO::FETCH_ASSOC)['count']; | 
					
						
							|  |  |  |         $this->assertEquals(1, $count, "IP should be in whitelist"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Should be able to make more requests than limit
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 100; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |             $this->assertTrue($result, "Request $i should be allowed for whitelisted IP"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRateLimitReset() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean any existing rate limit records
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Make some requests
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 15; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Manually expire old requests
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             DELETE FROM security_rate_page | 
					
						
							|  |  |  |             WHERE request_time < DATE_SUB(NOW(), INTERVAL 1 MINUTE) | 
					
						
							|  |  |  |         ");
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Should be able to make requests again
 | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |         $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         $this->assertTrue($result); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testDifferentEndpoints() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean any existing rate limit records
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Make requests to login endpoint (default limit: 60)
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 30; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |             $this->assertTrue($result, "Request $i to /login should be allowed"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Clean up between endpoint tests
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Make requests to register endpoint (limit: 5)
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         for ($i = 0; $i < 5; $i++) { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             $result = checkRateLimit($this->db, '/register'); | 
					
						
							|  |  |  |             $this->assertTrue($result, "Request $i to /register should be allowed"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // The 6th request to register should be blocked
 | 
					
						
							|  |  |  |         $result = checkRateLimit($this->db, '/register'); | 
					
						
							|  |  |  |         $this->assertFalse($result, "Request should be blocked after 5 requests to /register"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testDifferentIpAddresses() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Make requests from first IP
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 30; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |             $this->assertTrue($result); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Change IP
 | 
					
						
							|  |  |  |         $_SERVER['REMOTE_ADDR'] = '8.8.4.4'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Should be able to make requests from different IP
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 30; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |             $this->assertTrue($result); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testWhitelistedIp() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Add IP to whitelist
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->rateLimiter->addToWhitelist('8.8.8.8', false, 'Test whitelist', 'PHPUnit'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Should be able to make more requests than limit
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         for ($i = 0; $i < 50; $i++) { | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |             $this->assertTrue($result); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testBlacklistedIp() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add IP to blacklist and verify it was added
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("INSERT INTO security_ip_blacklist (ip_address, is_network, reason, created_by) VALUES ('8.8.8.8', 0, 'Test blacklist', 'system')"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Request should be blocked
 | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |         $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->assertFalse($result, "Blacklisted IP should be blocked"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testRateLimitPersistence() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Clean any existing rate limit records
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("TRUNCATE TABLE security_rate_page"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Make 60 requests to reach the limit
 | 
					
						
							|  |  |  |         for ($i = 0; $i < 60; $i++) { | 
					
						
							|  |  |  |             $result = checkRateLimit($this->db, '/login'); | 
					
						
							|  |  |  |             $this->assertTrue($result, "Request $i should be allowed"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             // Verify request was recorded
 | 
					
						
							|  |  |  |             $stmt = $this->db->getConnection()->prepare("
 | 
					
						
							|  |  |  |                 SELECT COUNT(*) as count | 
					
						
							|  |  |  |                 FROM security_rate_page | 
					
						
							|  |  |  |                 WHERE ip_address = ? | 
					
						
							|  |  |  |                 AND endpoint = ? | 
					
						
							|  |  |  |                 AND request_time >= DATE_SUB(NOW(), INTERVAL 1 MINUTE) | 
					
						
							|  |  |  |             ");
 | 
					
						
							|  |  |  |             $stmt->execute(['8.8.8.8', '/login']); | 
					
						
							|  |  |  |             $count = $stmt->fetch(PDO::FETCH_ASSOC)['count']; | 
					
						
							|  |  |  |             $this->assertEquals($i + 1, $count, "Expected " . ($i + 1) . " requests to be recorded, got {$count}"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // The 61st request should be blocked
 | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |         $result = checkRateLimit($this->db, '/login'); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->assertFalse($result, "Request should be blocked after 60 requests"); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } |