51 lines
2.2 KiB
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');
|
|
}
|
|
}
|