]>
git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/security/BanManagerTest.php
4 namespace Shaarli\Security
;
6 use Psr\Log\LoggerInterface
;
7 use Shaarli\Helper\FileUtils
;
11 * Test coverage for BanManager
13 class BanManagerTest
extends TestCase
15 /** @var BanManager Ban Manager instance */
16 protected $banManager;
18 /** @var string Banned IP filename */
19 protected $banFile = 'sandbox/ipbans.php';
21 /** @var string Log filename */
22 protected $logFile = 'sandbox/shaarli.log';
24 /** @var string Local client IP address */
25 protected $ipAddr = '127.0.0.1';
27 /** @var string Trusted proxy IP address */
28 protected $trustedProxy = '10.1.1.100';
30 /** @var array Simulates the $_SERVER array */
31 protected $server = [];
34 * Prepare or reset test resources
36 protected function setUp(): void
38 if (file_exists($this->banFile
)) {
39 unlink($this->banFile
);
42 $this->banManager
= $this->getNewBanManagerInstance();
43 $this->server
['REMOTE_ADDR'] = $this->ipAddr
;
47 * Test constructor with initial file.
49 public function testInstantiateFromFile()
52 FileUtils
::writeFlatDB(
60 $ip2 = '8.8.8.8' => $time,
61 $ip3 = '1.1.1.1' => $time +
1,
65 $this->banManager
= $this->getNewBanManagerInstance();
67 $this->assertCount(2, $this->banManager
->getFailures());
68 $this->assertEquals(2, $this->banManager
->getFailures()[$this->ipAddr
]);
69 $this->assertEquals(1, $this->banManager
->getFailures()[$ip]);
70 $this->assertCount(2, $this->banManager
->getBans());
71 $this->assertEquals($time, $this->banManager
->getBans()[$ip2]);
72 $this->assertEquals($time +
1, $this->banManager
->getBans()[$ip3]);
76 * Test constructor with initial file with invalid values
78 public function testInstantiateFromCrappyFile()
80 FileUtils
::writeFlatDB($this->banFile
, 'plop');
81 $this->banManager
= $this->getNewBanManagerInstance();
83 $this->assertEquals([], $this->banManager
->getFailures());
84 $this->assertEquals([], $this->banManager
->getBans());
88 * Test failed attempt with a direct IP.
90 public function testHandleFailedAttempt()
92 $this->assertCount(0, $this->banManager
->getFailures());
94 $this->banManager
->handleFailedAttempt($this->server
);
95 $this->assertCount(1, $this->banManager
->getFailures());
96 $this->assertEquals(1, $this->banManager
->getFailures()[$this->ipAddr
]);
98 $this->banManager
->handleFailedAttempt($this->server
);
99 $this->assertCount(1, $this->banManager
->getFailures());
100 $this->assertEquals(2, $this->banManager
->getFailures()[$this->ipAddr
]);
104 * Test failed attempt behind a trusted proxy IP (with proper IP forwarding).
106 public function testHandleFailedAttemptBehingProxy()
109 'REMOTE_ADDR' => $this->trustedProxy
,
110 'HTTP_X_FORWARDED_FOR' => $this->ipAddr
,
112 $this->assertCount(0, $this->banManager
->getFailures());
114 $this->banManager
->handleFailedAttempt($server);
115 $this->assertCount(1, $this->banManager
->getFailures());
116 $this->assertEquals(1, $this->banManager
->getFailures()[$this->ipAddr
]);
118 $this->banManager
->handleFailedAttempt($server);
119 $this->assertCount(1, $this->banManager
->getFailures());
120 $this->assertEquals(2, $this->banManager
->getFailures()[$this->ipAddr
]);
124 * Test failed attempt behind a trusted proxy IP but without IP forwarding.
126 public function testHandleFailedAttemptBehindNotConfiguredProxy()
129 'REMOTE_ADDR' => $this->trustedProxy
,
131 $this->assertCount(0, $this->banManager
->getFailures());
133 $this->banManager
->handleFailedAttempt($server);
134 $this->assertCount(0, $this->banManager
->getFailures());
136 $this->banManager
->handleFailedAttempt($server);
137 $this->assertCount(0, $this->banManager
->getFailures());
141 * Test failed attempts with multiple direct IP.
143 public function testHandleFailedAttemptMultipleIp()
145 $this->assertCount(0, $this->banManager
->getFailures());
146 $this->banManager
->handleFailedAttempt($this->server
);
147 $this->server
['REMOTE_ADDR'] = '1.2.3.4';
148 $this->banManager
->handleFailedAttempt($this->server
);
149 $this->banManager
->handleFailedAttempt($this->server
);
150 $this->assertCount(2, $this->banManager
->getFailures());
151 $this->assertEquals(1, $this->banManager
->getFailures()[$this->ipAddr
]);
152 $this->assertEquals(2, $this->banManager
->getFailures()[$this->server
['REMOTE_ADDR']]);
156 * Test clear failure for provided IP without any additional data.
158 public function testClearFailuresEmpty()
160 $this->assertCount(0, $this->banManager
->getFailures());
161 $this->banManager
->clearFailures($this->server
);
162 $this->assertCount(0, $this->banManager
->getFailures());
166 * Test clear failure for provided IP with failed attempts.
168 public function testClearFailuresFromFile()
170 FileUtils
::writeFlatDB(
175 $ip = '1.2.3.4' => 1,
179 $this->banManager
= $this->getNewBanManagerInstance();
181 $this->assertCount(2, $this->banManager
->getFailures());
182 $this->banManager
->clearFailures($this->server
);
183 $this->assertCount(1, $this->banManager
->getFailures());
184 $this->assertEquals(1, $this->banManager
->getFailures()[$ip]);
188 * Test clear failure for provided IP with failed attempts, behind a reverse proxy.
190 public function testClearFailuresFromFileBehindProxy()
193 'REMOTE_ADDR' => $this->trustedProxy
,
194 'HTTP_X_FORWARDED_FOR' => $this->ipAddr
,
197 FileUtils
::writeFlatDB(
202 $ip = '1.2.3.4' => 1,
206 $this->banManager
= $this->getNewBanManagerInstance();
208 $this->assertCount(2, $this->banManager
->getFailures());
209 $this->banManager
->clearFailures($server);
210 $this->assertCount(1, $this->banManager
->getFailures());
211 $this->assertEquals(1, $this->banManager
->getFailures()[$ip]);
215 * Test clear failure for provided IP with failed attempts,
216 * behind a reverse proxy without forwarding.
218 public function testClearFailuresFromFileBehindNotConfiguredProxy()
221 'REMOTE_ADDR' => $this->trustedProxy
,
224 FileUtils
::writeFlatDB(
229 $ip = '1.2.3.4' => 1,
233 $this->banManager
= $this->getNewBanManagerInstance();
235 $this->assertCount(2, $this->banManager
->getFailures());
236 $this->banManager
->clearFailures($server);
237 $this->assertCount(2, $this->banManager
->getFailures());
241 * Test isBanned without any data
243 public function testIsBannedEmpty()
245 $this->assertFalse($this->banManager
->isBanned($this->server
));
249 * Test isBanned with banned IP from file data
251 public function testBannedFromFile()
253 FileUtils
::writeFlatDB(
257 $this->ipAddr
=> time() +
10,
261 $this->banManager
= $this->getNewBanManagerInstance();
263 $this->assertCount(1, $this->banManager
->getBans());
264 $this->assertTrue($this->banManager
->isBanned($this->server
));
268 * Test isBanned with banned IP from file data behind a reverse proxy
270 public function testBannedFromFileBehindProxy()
273 'REMOTE_ADDR' => $this->trustedProxy
,
274 'HTTP_X_FORWARDED_FOR' => $this->ipAddr
,
276 FileUtils
::writeFlatDB(
280 $this->ipAddr
=> time() +
10,
284 $this->banManager
= $this->getNewBanManagerInstance();
286 $this->assertCount(1, $this->banManager
->getBans());
287 $this->assertTrue($this->banManager
->isBanned($server));
291 * Test isBanned with banned IP from file data behind a reverse proxy,
292 * without IP forwarding
294 public function testBannedFromFileBehindNotConfiguredProxy()
297 'REMOTE_ADDR' => $this->trustedProxy
,
299 FileUtils
::writeFlatDB(
303 $this->ipAddr
=> time() +
10,
307 $this->banManager
= $this->getNewBanManagerInstance();
309 $this->assertCount(1, $this->banManager
->getBans());
310 $this->assertFalse($this->banManager
->isBanned($server));
314 * Test isBanned with an expired ban
316 public function testLiftBan()
318 FileUtils
::writeFlatDB(
322 $this->ipAddr
=> time() - 10,
326 $this->banManager
= $this->getNewBanManagerInstance();
328 $this->assertCount(1, $this->banManager
->getBans());
329 $this->assertFalse($this->banManager
->isBanned($this->server
));
333 * Test isBanned with an expired ban behind a reverse proxy
335 public function testLiftBanBehindProxy()
338 'REMOTE_ADDR' => $this->trustedProxy
,
339 'HTTP_X_FORWARDED_FOR' => $this->ipAddr
,
342 FileUtils
::writeFlatDB(
346 $this->ipAddr
=> time() - 10,
350 $this->banManager
= $this->getNewBanManagerInstance();
352 $this->assertCount(1, $this->banManager
->getBans());
353 $this->assertFalse($this->banManager
->isBanned($server));
357 * Test isBanned with an expired ban behind a reverse proxy
359 public function testLiftBanBehindNotConfiguredProxy()
362 'REMOTE_ADDR' => $this->trustedProxy
,
365 FileUtils
::writeFlatDB(
369 $this->ipAddr
=> time() - 10,
373 $this->banManager
= $this->getNewBanManagerInstance();
375 $this->assertCount(1, $this->banManager
->getBans());
376 $this->assertFalse($this->banManager
->isBanned($server));
380 * Build a new instance of BanManager, which will reread the ban file.
382 * @return BanManager instance
384 protected function getNewBanManagerInstance()
386 return new BanManager(
387 [$this->trustedProxy
],
391 $this->createMock(LoggerInterface
::class)