Harden quarantine provisioning; enforce strict permissions and update Ansible and docs

This commit is contained in:
2026-02-12 07:47:48 +01:00
parent 037b176892
commit 1768f61da1
44 changed files with 2587 additions and 698 deletions

22
tests/ConfigTest.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
use PHPUnit\Framework\TestCase;
use UploadLogger\Core\Config;
final class ConfigTest extends TestCase
{
public function testDotNotationGetters(): void
{
$data = [
'modules' => ['flood' => true],
'limits' => ['max_size' => 12345, 'nested' => ['x' => 5]],
];
$cfg = new Config($data);
$this->assertTrue($cfg->isModuleEnabled('flood'));
$this->assertEquals(12345, $cfg->get('limits.max_size'));
$this->assertEquals(5, $cfg->get('limits.nested.x'));
$this->assertNull($cfg->get('limits.nonexistent'));
}
}

21
tests/ContextTest.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
use PHPUnit\Framework\TestCase;
use UploadLogger\Core\Context;
final class ContextTest extends TestCase
{
public function testContextAccessors(): void
{
$ctx = new Context('r1', '1.2.3.4', '/u', 'POST', 'application/json', 1000, 'user1', 'ua', '');
$this->assertEquals('r1', $ctx->getRequestId());
$this->assertEquals('1.2.3.4', $ctx->getIp());
$this->assertEquals('/u', $ctx->getUri());
$this->assertEquals('POST', $ctx->getMethod());
$this->assertEquals('application/json', $ctx->getContentType());
$this->assertEquals(1000, $ctx->getContentLength());
$this->assertEquals('user1', $ctx->getUser());
$this->assertEquals('ua', $ctx->getUserAgent());
}
}

40
tests/DetectorsTest.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
use PHPUnit\Framework\TestCase;
use UploadLogger\Detectors\FilenameDetector;
use UploadLogger\Detectors\MimeDetector;
use UploadLogger\Detectors\ContentDetector;
use UploadLogger\Core\Context;
final class DetectorsTest extends TestCase
{
public function testFilenameDetector(): void
{
$det = new FilenameDetector();
$ctx = new Context('r','1.1.1.1','/','POST','',0,'guest','', '');
$res = $det->detect($ctx, ['name' => 'image.php.jpg', 'orig_name' => 'image.php.jpg']);
$this->assertTrue(!empty($res['suspicious']));
}
public function testMimeDetector(): void
{
$det = new MimeDetector();
$ctx = new Context('r','1.1.1.1','/','POST','',0,'guest','', '');
$res = $det->detect($ctx, ['name' => 'file.jpg', 'real_mime' => 'text/plain']);
$this->assertTrue(!empty($res['suspicious']));
}
public function testContentDetectorDetectsPhpTag(): void
{
$tmp = tempnam(sys_get_temp_dir(), 'ul');
file_put_contents($tmp, "<?php echo 'x'; ?>");
$det = new ContentDetector();
$ctx = new Context('r','1.1.1.1','/','POST','text/plain', 10, 'guest','', '');
$res = $det->detect($ctx, ['tmp' => $tmp, 'size' => filesize($tmp), 'real_mime' => 'text/plain']);
unlink($tmp);
$this->assertTrue(!empty($res['suspicious']), 'ContentDetector should flag PHP open tag');
}
}

View File

@@ -0,0 +1,4 @@
# Create sample files for upload smoke tests
Set-Content -Path .\tests\smoke\public\sample.txt -Value "hello world"
Set-Content -Path .\tests\smoke\public\suspicious.php -Value "<?php echo 'bad'; ?>"
Write-Host "Created sample files."

View File

@@ -0,0 +1 @@
hello world

View File

@@ -0,0 +1 @@
<?php echo 'bad'; ?>

View File

@@ -0,0 +1,19 @@
<?php
// Simple endpoint that accepts file uploads; auto_prepend_file will run upload-logger.php
header('Content-Type: text/plain');
if (empty($_FILES)) {
echo "no files\n";
exit;
}
$out = [];
foreach ($_FILES as $k => $v) {
if (is_array($v['name'])) {
$count = count($v['name']);
for ($i = 0; $i < $count; $i++) {
$out[] = $v['name'][$i] . ' -> ' . $v['tmp_name'][$i];
}
} else {
$out[] = $v['name'] . ' -> ' . $v['tmp_name'];
}
}
echo implode("\n", $out) . "\n";