jilo-web/tests/Unit/Classes/RateLimiterTest.php

107 lines
3.8 KiB
PHP
Raw Normal View History

2025-02-18 14:36:31 +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';
require_once dirname(__DIR__, 3) . '/app/classes/log.php';
2025-02-18 14:36:31 +00:00
use PHPUnit\Framework\TestCase;
class RateLimiterTest extends TestCase
{
private $db;
2025-04-25 14:15:56 +00:00
private $rateLimiter;
2025-02-18 14:36:31 +00:00
protected function setUp(): void
{
parent::setUp();
2025-04-25 14:15:56 +00:00
// 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 : '';
// Set up test database
2025-02-18 14:36:31 +00:00
$this->db = new Database([
2025-04-25 14:15:56 +00:00
'type' => 'mariadb',
'host' => $host,
'port' => '3306',
'dbname' => 'totalmeet_test',
'user' => 'test_totalmeet',
'password' => $password
2025-02-18 14:36:31 +00:00
]);
2025-04-25 14:15:56 +00:00
// The RateLimiter constructor will create all necessary tables
2025-02-18 14:36:31 +00:00
$this->rateLimiter = new RateLimiter($this->db);
}
2025-04-25 14:15:56 +00:00
protected function tearDown(): void
2025-02-18 14:36:31 +00:00
{
2025-04-25 14:15:56 +00:00
// Drop tables in correct order
$this->db->getConnection()->exec("DROP TABLE IF EXISTS {$this->rateLimiter->authRatelimitTable}");
$this->db->getConnection()->exec("DROP TABLE IF EXISTS {$this->rateLimiter->pagesRatelimitTable}");
$this->db->getConnection()->exec("DROP TABLE IF EXISTS {$this->rateLimiter->blacklistTable}");
$this->db->getConnection()->exec("DROP TABLE IF EXISTS {$this->rateLimiter->whitelistTable}");
parent::tearDown();
}
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
public function testGetRecentAttempts()
{
$ip = '8.8.8.8';
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// Record some login attempts
$stmt = $this->db->getConnection()->prepare("INSERT INTO {$this->rateLimiter->authRatelimitTable}
(ip_address, username, attempted_at) VALUES (?, ?, NOW())");
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// Add 3 attempts
for ($i = 0; $i < 3; $i++) {
$stmt->execute([$ip, 'testuser']);
}
2025-02-18 14:36:31 +00:00
$attempts = $this->rateLimiter->getRecentAttempts($ip);
2025-04-25 14:15:56 +00:00
$this->assertEquals(3, $attempts);
2025-02-18 14:36:31 +00:00
}
2025-04-25 14:15:56 +00:00
public function testIsIpBlacklisted()
2025-02-18 14:36:31 +00:00
{
2025-04-25 14:15:56 +00:00
$ip = '8.8.8.8';
2025-02-18 14:36:31 +00:00
// Add IP to blacklist
2025-04-25 14:15:56 +00:00
$stmt = $this->db->getConnection()->prepare("INSERT INTO {$this->rateLimiter->blacklistTable}
(ip_address, is_network, reason) VALUES (?, ?, ?)");
$stmt->execute([$ip, 0, 'Test blacklist']); // Explicitly set is_network to 0 (false)
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
$this->assertTrue($this->rateLimiter->isIpBlacklisted($ip));
$this->assertFalse($this->rateLimiter->isIpBlacklisted('8.8.4.4'));
2025-02-18 14:36:31 +00:00
}
2025-04-25 14:15:56 +00:00
public function testIsIpWhitelisted()
2025-02-18 14:36:31 +00:00
{
2025-04-25 14:15:56 +00:00
// Test with an IP that's not in the default whitelisted ranges
$ip = '8.8.8.8'; // Google's DNS, definitely not in private ranges
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// Add IP to whitelist
$stmt = $this->db->getConnection()->prepare("INSERT INTO {$this->rateLimiter->whitelistTable}
(ip_address, is_network, description) VALUES (?, ?, ?)");
$stmt->execute([$ip, 0, 'Test whitelist']); // Explicitly set is_network to 0 (false)
2025-02-18 14:36:31 +00:00
$this->assertTrue($this->rateLimiter->isIpWhitelisted($ip));
2025-04-25 14:15:56 +00:00
$this->assertFalse($this->rateLimiter->isIpWhitelisted('8.8.4.4')); // Another IP not in private ranges
2025-02-18 14:36:31 +00:00
}
2025-04-25 14:15:56 +00:00
public function testRateLimitCheck()
2025-02-18 14:36:31 +00:00
{
2025-04-25 14:15:56 +00:00
$ip = '8.8.8.8'; // Use non-whitelisted IP
$endpoint = '/test';
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// First request should be allowed
$this->assertTrue($this->rateLimiter->isPageRequestAllowed($ip, $endpoint));
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// Add requests up to the limit
for ($i = 0; $i < 60; $i++) { // Default limit is 60 per minute
$this->rateLimiter->recordPageRequest($ip, $endpoint);
}
2025-02-18 14:36:31 +00:00
2025-04-25 14:15:56 +00:00
// The next request should be rate limited
$this->assertFalse($this->rateLimiter->isPageRequestAllowed($ip, $endpoint));
2025-02-18 14:36:31 +00:00
}
}