CluPilotCloud/tests/Feature/Security/BlockAddressTest.php

70 lines
2.6 KiB
PHP

<?php // tests/Feature/Security/BlockAddressTest.php
use App\Models\Host;
use App\Models\Instance;
use App\Models\SecurityBlock;
use App\Services\Security\BlockAddress;
use Illuminate\Support\Carbon;
it('sperrt beim ersten Mal fuer eine Stunde', function () {
$instance = Instance::factory()->create();
$block = app(BlockAddress::class)->forInstance($instance, '203.0.113.7', 12);
expect($block)->not->toBeNull()
// diffInMinutes ist SIGNED (Carbon 3) — wie App\Models\Incident und
// Host::healthState() schon halten es hier: früher.diffInX(später)
// für ein positives Ergebnis, nicht wortwörtlich wie im Auftragszettel.
->and(now()->diffInMinutes($block->expires_at))->toBeGreaterThan(55)
->and(now()->diffInMinutes($block->expires_at))->toBeLessThan(65)
->and($block->strikes)->toBe(1)
->and($block->attempts)->toBe(12);
});
it('verdoppelt bei Wiederholung und haelt bei 24 Stunden an', function () {
$instance = Instance::factory()->create();
$dienst = app(BlockAddress::class);
$dauern = [];
for ($i = 0; $i < 7; $i++) {
$block = $dienst->forInstance($instance, '203.0.113.7', 10);
$dauern[] = (int) round($block->blocked_at->diffInHours($block->expires_at));
$block->release(null); // freigegeben, aber der Zähler bleibt
}
expect($dauern)->toBe([1, 2, 4, 8, 16, 24, 24]);
});
it('faengt nach 24 Stunden ohne Vorfall wieder bei einer Stunde an', function () {
$instance = Instance::factory()->create();
$dienst = app(BlockAddress::class);
$dienst->forInstance($instance, '203.0.113.7', 10)->release(null);
Carbon::setTestNow(now()->addHours(25));
$zweiter = $dienst->forInstance($instance, '203.0.113.7', 10);
expect($zweiter->strikes)->toBe(1);
});
it('sperrt NIEMALS eine Adresse aus dem Verwaltungsnetz', function () {
// Eine Sperrliste, die sich selbst aussperren kann, ist eine Falle: über
// genau dieses Netz erreicht CluPilot den Host.
$host = Host::factory()->create();
expect(app(BlockAddress::class)->forHost($host, '10.66.0.1', 999))->toBeNull()
->and(app(BlockAddress::class)->forHost($host, '127.0.0.1', 999))->toBeNull()
->and(app(BlockAddress::class)->forHost($host, '::1', 999))->toBeNull()
->and(SecurityBlock::count())->toBe(0);
});
it('haelt eine laufende Sperre nicht zweimal', function () {
$instance = Instance::factory()->create();
$dienst = app(BlockAddress::class);
$dienst->forInstance($instance, '203.0.113.7', 10);
expect($dienst->forInstance($instance, '203.0.113.7', 10))->toBeNull()
->and(SecurityBlock::count())->toBe(1);
});