fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled

This commit is contained in:
2025-11-24 21:28:25 +01:00
parent 4eb7134853
commit 77abc65cd7
1327 changed files with 91915 additions and 9909 deletions

View File

@@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
use App\Framework\DateTime\SystemClock;
use App\Framework\Http\Session\FileSessionStorage;
use App\Framework\Http\Session\Session;
use App\Framework\Http\Session\SessionId;
use App\Framework\Http\Session\SessionIdGenerator;
use App\Framework\Http\Session\SessionManager;
use App\Framework\Random\SecureRandomGenerator;
use App\Framework\Security\CsrfTokenGenerator;
use App\Framework\Http\Cookies\SessionCookieConfig;
beforeEach(function () {
$this->tempDir = sys_get_temp_dir() . '/php_sessions_test_' . uniqid();
mkdir($this->tempDir, 0700, true);
$this->clock = new SystemClock();
$this->storage = new FileSessionStorage($this->tempDir, $this->clock);
$this->sessionIdGenerator = new SessionIdGenerator(new SecureRandomGenerator());
$this->csrfTokenGenerator = new CsrfTokenGenerator(new SecureRandomGenerator());
$this->cookieConfig = new SessionCookieConfig(
name: 'test_session',
lifetime: 3600,
path: '/',
domain: null,
secure: false,
httpOnly: true,
sameSite: \App\Framework\Http\Cookies\SameSite::LAX
);
$this->sessionManager = new SessionManager(
generator: $this->sessionIdGenerator,
responseManipulator: Mockery::mock(\App\Framework\Http\ResponseManipulator::class),
clock: $this->clock,
csrfTokenGenerator: $this->csrfTokenGenerator,
storage: $this->storage,
cookieConfig: $this->cookieConfig
);
$this->sessionId = $this->sessionIdGenerator->generate();
$this->session = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, []);
});
afterEach(function () {
if (isset($this->tempDir) && is_dir($this->tempDir)) {
array_map('unlink', glob($this->tempDir . '/*'));
rmdir($this->tempDir);
}
});
it('handles concurrent token generation atomically', function () {
$formId = 'test-form';
// Simulate concurrent token generation
$tokens = [];
$updates = [];
// Generate tokens "concurrently" (sequentially in test, but with atomic updates)
for ($i = 0; $i < 5; $i++) {
$token = $this->session->csrf->generateToken($formId);
$tokens[] = $token->toString();
// Save session after each token generation
$this->sessionManager->saveSessionData($this->session);
// Reload session to simulate new request
$data = $this->storage->read($this->sessionId);
$this->session = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $data);
}
// All tokens should be unique
$uniqueTokens = array_unique($tokens);
expect(count($uniqueTokens))->toBe(count($tokens));
// Should have max 3 tokens (cleanup)
$count = $this->session->csrf->getActiveTokenCount($formId);
expect($count)->toBeLessThanOrEqual(3);
});
it('validates tokens correctly after atomic updates', function () {
$formId = 'test-form';
// Generate token
$token = $this->session->csrf->generateToken($formId);
$this->sessionManager->saveSessionData($this->session);
// Reload session
$data = $this->storage->read($this->sessionId);
$this->session = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $data);
// Validate token
$result = $this->session->csrf->validateTokenWithDebug($formId, $token);
expect($result['valid'])->toBeTrue();
// Mark as used and save
$this->sessionManager->saveSessionData($this->session);
// Reload again
$data = $this->storage->read($this->sessionId);
$this->session = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $data);
// Should still be valid within resubmit window
$result2 = $this->session->csrf->validateTokenWithDebug($formId, $token);
expect($result2['valid'])->toBeTrue();
});
it('handles version conflicts with optimistic locking', function () {
$formId = 'test-form';
// Generate token and save
$token1 = $this->session->csrf->generateToken($formId);
$this->sessionManager->saveSessionData($this->session);
// Read session data
$data1 = $this->storage->read($this->sessionId);
$session1 = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $data1);
// Read again (simulating concurrent request)
$data2 = $this->storage->read($this->sessionId);
$session2 = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $data2);
// Generate tokens in both "requests"
$token2 = $session1->csrf->generateToken($formId);
$token3 = $session2->csrf->generateToken($formId);
// Save both (simulating concurrent writes)
$this->sessionManager->saveSessionData($session1);
$this->sessionManager->saveSessionData($session2);
// Final read
$finalData = $this->storage->read($this->sessionId);
$finalSession = Session::fromArray($this->sessionId, $this->clock, $this->csrfTokenGenerator, $finalData);
// Should have valid tokens
$count = $finalSession->csrf->getActiveTokenCount($formId);
expect($count)->toBeGreaterThan(0);
});