- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
147 lines
4.7 KiB
PHP
147 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Security\RequestSigning;
|
|
|
|
use App\Framework\Security\RequestSigning\SigningAlgorithm;
|
|
use App\Framework\Security\RequestSigning\SigningKey;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class SigningKeyTest extends TestCase
|
|
{
|
|
#[Test]
|
|
public function it_can_create_hmac_key(): void
|
|
{
|
|
$key = SigningKey::createHmac('test-key', 'my-secret-that-is-long-enough-for-security');
|
|
|
|
$this->assertEquals('test-key', $key->keyId);
|
|
$this->assertEquals('my-secret-that-is-long-enough-for-security', $key->keyMaterial);
|
|
$this->assertEquals(SigningAlgorithm::HMAC_SHA256, $key->algorithm);
|
|
$this->assertTrue($key->isActive);
|
|
$this->assertNull($key->expiresAt);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_can_create_hmac_key_with_expiration(): void
|
|
{
|
|
$expiresAt = new \DateTimeImmutable('+1 hour');
|
|
$key = SigningKey::createHmac(
|
|
'test-key',
|
|
'my-secret-that-is-long-enough-for-security',
|
|
SigningAlgorithm::HMAC_SHA512,
|
|
$expiresAt
|
|
);
|
|
|
|
$this->assertEquals(SigningAlgorithm::HMAC_SHA512, $key->algorithm);
|
|
$this->assertEquals($expiresAt, $key->expiresAt);
|
|
$this->assertFalse($key->isExpired());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_can_generate_random_hmac_key(): void
|
|
{
|
|
$key = SigningKey::generateHmac('random-key');
|
|
|
|
$this->assertEquals('random-key', $key->keyId);
|
|
$this->assertEquals(SigningAlgorithm::HMAC_SHA256, $key->algorithm);
|
|
$this->assertGreaterThanOrEqual(64, strlen($key->keyMaterial)); // 32 bytes = 64 hex chars
|
|
$this->assertTrue($key->isValid());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_can_create_rsa_key(): void
|
|
{
|
|
// Generate test RSA key pair
|
|
$keyPair = openssl_pkey_new([
|
|
'digest_alg' => 'sha256',
|
|
'private_key_bits' => 2048,
|
|
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
|
]);
|
|
|
|
openssl_pkey_export($keyPair, $privateKey);
|
|
|
|
$key = SigningKey::createRsa('rsa-key', $privateKey);
|
|
|
|
$this->assertEquals('rsa-key', $key->keyId);
|
|
$this->assertEquals(SigningAlgorithm::RSA_SHA256, $key->algorithm);
|
|
$this->assertEquals($privateKey, $key->keyMaterial);
|
|
$this->assertTrue($key->isValid());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_throws_exception_for_short_key_material(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Key material must be at least 32 bytes long');
|
|
|
|
new SigningKey('test', 'short-key', SigningAlgorithm::HMAC_SHA256);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_throws_exception_for_invalid_rsa_key(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Invalid RSA private key');
|
|
|
|
SigningKey::createRsa('invalid-rsa', 'not-a-valid-rsa-key');
|
|
}
|
|
|
|
#[Test]
|
|
public function it_detects_expired_keys(): void
|
|
{
|
|
$expiredKey = SigningKey::createHmac(
|
|
'expired-key',
|
|
'my-secret-that-is-long-enough-for-security',
|
|
expiresAt: new \DateTimeImmutable('2020-01-01')
|
|
);
|
|
|
|
$this->assertTrue($expiredKey->isExpired());
|
|
$this->assertFalse($expiredKey->isValid());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_validates_non_expired_keys(): void
|
|
{
|
|
$futureKey = SigningKey::createHmac(
|
|
'future-key',
|
|
'my-secret-that-is-long-enough-for-security',
|
|
expiresAt: new \DateTimeImmutable('+1 hour')
|
|
);
|
|
|
|
$this->assertFalse($futureKey->isExpired());
|
|
$this->assertTrue($futureKey->isValid());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_handles_keys_without_expiration(): void
|
|
{
|
|
$permanentKey = SigningKey::createHmac(
|
|
'permanent-key',
|
|
'my-secret-that-is-long-enough-for-security'
|
|
);
|
|
|
|
$this->assertFalse($permanentKey->isExpired());
|
|
$this->assertTrue($permanentKey->isValid());
|
|
}
|
|
|
|
#[Test]
|
|
public function it_throws_exception_for_asymmetric_algorithm_with_hmac_factory(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Algorithm must be symmetric for HMAC keys');
|
|
|
|
SigningKey::createHmac('test', 'my-secret-that-is-long-enough-for-security', SigningAlgorithm::RSA_SHA256);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_throws_exception_for_asymmetric_algorithm_with_generate_factory(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Algorithm must be symmetric for HMAC keys');
|
|
|
|
SigningKey::generateHmac('test', SigningAlgorithm::RSA_SHA256);
|
|
}
|
|
}
|