Steuerkram/tests/53_LoginThrottleTest.php

51 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
use Steuerkram\Models\User;
class LoginThrottleTest extends TestCase
{
protected string $testName = 'Test 53: Brute-Force-Schutz beim Login (Konto-Lockout)';
public function run(): void
{
User::create('throttletest', 'password123');
$user = User::findByUsername('throttletest');
$id = (int)$user['id'];
$this->assertEquals(0, $user['failed_attempts'], 'Neuer Benutzer startet ohne Fehlversuche');
$this->assert(!User::isLocked($user), 'Neuer Benutzer ist nicht gesperrt');
// 4 Fehlversuche: noch keine Sperre
for ($i = 0; $i < 4; $i++) {
$user = User::findByUsername('throttletest');
User::registerFailedLogin($id, (int)$user['failed_attempts']);
}
$user = User::findByUsername('throttletest');
$this->assertEquals(4, $user['failed_attempts'], 'Nach 4 Fehlversuchen: Zähler steht auf 4');
$this->assert(!User::isLocked($user), 'Nach 4 Fehlversuchen noch keine Sperre');
// 5. Fehlversuch: Konto wird gesperrt
User::registerFailedLogin($id, (int)$user['failed_attempts']);
$user = User::findByUsername('throttletest');
$this->assertEquals(5, $user['failed_attempts'], 'Nach 5 Fehlversuchen: Zähler steht auf 5');
$this->assert(User::isLocked($user), 'Nach 5 Fehlversuchen ist das Konto gesperrt');
$this->assertNotEmpty($user['locked_until'], 'locked_until ist gesetzt');
// Weitere Fehlversuche verlängern die Sperre (steigendes Zeitfenster)
$firstLock = $user['locked_until'];
User::registerFailedLogin($id, (int)$user['failed_attempts']);
$user = User::findByUsername('throttletest');
$this->assert(
strtotime((string)$user['locked_until']) >= strtotime((string)$firstLock),
'Sperrzeitfenster wird bei weiteren Fehlversuchen nicht kürzer'
);
// Erfolgreicher Login-Reset hebt die Sperre auf
User::resetFailedLogins($id);
$user = User::findByUsername('throttletest');
$this->assertEquals(0, $user['failed_attempts'], 'Reset setzt Zähler auf 0');
$this->assert(!User::isLocked($user), 'Nach Reset ist das Konto nicht mehr gesperrt');
}
}