Skip to content

Commit

Permalink
Merge pull request absolute-quantum#48 from phansys/sca
Browse files Browse the repository at this point in the history
Fix compatibility with "doctrine/orm" 3.x
  • Loading branch information
r3hp1c authored Dec 16, 2024
2 parents a0d32a2 + bab65a6 commit aa75652
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 76 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.0"
php-version: "8.4"
extensions: pdo, pdo_sqlite

- name: "Validate composer.json"
Expand All @@ -37,6 +37,9 @@ jobs:
composer-options: "--prefer-stable"
dependency-versions: 'highest'

- name: "Trigger install for PHPUnit dependencies"
run: "vendor/bin/simple-phpunit --version"

- name: "PHPStan"
run: "vendor/bin/phpstan analyze"

Expand Down
31 changes: 31 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
parameters:
ignoreErrors:
-
message: "#^Class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo not found\\.$#"
count: 1
path: src/Command/AbstractCommand.php

-
message: "#^Class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo not found\\.$#"
count: 1
path: src/Command/DoctrineDecryptDatabaseCommand.php

-
message: "#^Class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo not found\\.$#"
count: 1
path: src/Command/DoctrineEncryptStatusCommand.php

-
message: "#^Call to an undefined static method Doctrine\\\\ORM\\\\EntityManager\\:\\:create\\(\\)\\.$#"
count: 1
path: tests/Functional/AbstractFunctionalTestCase.php

-
message: "#^Call to static method createAnnotationMetadataConfiguration\\(\\) on an unknown class Doctrine\\\\ORM\\\\Tools\\\\Setup\\.$#"
count: 1
path: tests/Functional/AbstractFunctionalTestCase.php

-
message: "#^Instantiated class Doctrine\\\\DBAL\\\\Logging\\\\DebugStack not found\\.$#"
count: 1
path: tests/Functional/AbstractFunctionalTestCase.php
5 changes: 4 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
includes:
- phpstan-baseline.neon

parameters:
level: 0
paths:
- src
#- tests
- tests
tmpDir: .phpstan-cache
3 changes: 2 additions & 1 deletion src/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Common\Annotations\Reader;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Symfony\Component\Console\Command\Command;

Expand Down Expand Up @@ -81,7 +82,7 @@ protected function getEncryptionableEntityMetaData(): array
$metaDataArray = $this->entityManager->getMetadataFactory()->getAllMetadata();

foreach ($metaDataArray as $entityMetaData) {
if ($entityMetaData instanceof ClassMetadataInfo and $entityMetaData->isMappedSuperclass) {
if (($entityMetaData instanceof ClassMetadataInfo || $entityMetaData instanceof ClassMetadata) && $entityMetaData->isMappedSuperclass) {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Command/DoctrineDecryptDatabaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Ambta\DoctrineEncryptBundle\Command;

use Ambta\DoctrineEncryptBundle\DependencyInjection\DoctrineEncryptExtension;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
Expand Down Expand Up @@ -63,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
// Set counter and loop through entity manager meta data
$propertyCount = 0;
foreach ($metaDataArray as $metaData) {
if ($metaData instanceof ClassMetadataInfo and $metaData->isMappedSuperclass) {
if (($metaData instanceof ClassMetadataInfo || $metaData instanceof ClassMetadata) && $metaData->isMappedSuperclass) {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Command/DoctrineEncryptStatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Ambta\DoctrineEncryptBundle\Command;

use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -27,7 +28,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$totalCount = 0;
foreach ($metaDataArray as $metaData) {
if ($metaData instanceof ClassMetadataInfo && $metaData->isMappedSuperclass) {
if (($metaData instanceof ClassMetadataInfo || $metaData instanceof ClassMetadata) && $metaData->isMappedSuperclass) {
continue;
}

Expand Down
6 changes: 3 additions & 3 deletions tests/Functional/AbstractFunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ protected function resetQueryStack(): void
*/
public function assertStringDoesNotContain($needle, $string, $ignoreCase = false, $message = ''): void
{
$this->assertIsString($needle, $message);
$this->assertIsString($string, $message);
$this->assertIsBool($ignoreCase, $message);
static::assertIsString($needle, $message);
static::assertIsString($string, $message);
static::assertIsBool($ignoreCase, $message);

$constraint = new LogicalNot(new StringContains(
$needle,
Expand Down
26 changes: 13 additions & 13 deletions tests/Functional/BasicQueryTest/AbstractBasicQueryTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,44 @@ public function testPersistEntity(): void
$this->entityManager->flush();

// Start transaction; insert; commit
$this->assertEquals('top secret information', $user->getSecret());
$this->assertEquals(3, $this->getCurrentQueryCount());
static::assertEquals('top secret information', $user->getSecret());
static::assertEquals(3, $this->getCurrentQueryCount());
}

public function testNoUpdateOnReadEncrypted(): void
{
$this->entityManager->beginTransaction();
$this->assertEquals(1, $this->getCurrentQueryCount());
static::assertEquals(1, $this->getCurrentQueryCount());

$user = new CascadeTarget();
$user->setNotSecret('My public information');
$user->setSecret('top secret information');
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->assertEquals(2, $this->getCurrentQueryCount());
static::assertEquals(2, $this->getCurrentQueryCount());

// Test if no query is executed when doing nothing
$this->entityManager->flush();
$this->assertEquals(2, $this->getCurrentQueryCount());
static::assertEquals(2, $this->getCurrentQueryCount());

// Test if no query is executed when reading unrelated field
$user->getNotSecret();
$this->entityManager->flush();
$this->assertEquals(2, $this->getCurrentQueryCount());
static::assertEquals(2, $this->getCurrentQueryCount());

// Test if no query is executed when reading related field and if field is valid
$this->assertEquals('top secret information', $user->getSecret());
static::assertEquals('top secret information', $user->getSecret());
$this->entityManager->flush();
$this->assertEquals(2, $this->getCurrentQueryCount());
static::assertEquals(2, $this->getCurrentQueryCount());

// Test if 1 query is executed when updating entity
$user->setSecret('top secret information change');
$this->entityManager->flush();
$this->assertEquals(3, $this->getCurrentQueryCount());
$this->assertEquals('top secret information change', $user->getSecret());
static::assertEquals(3, $this->getCurrentQueryCount());
static::assertEquals('top secret information change', $user->getSecret());

$this->entityManager->rollback();
$this->assertEquals(4, $this->getCurrentQueryCount());
static::assertEquals(4, $this->getCurrentQueryCount());
}

public function testStoredDataIsEncrypted(): void
Expand Down Expand Up @@ -92,7 +92,7 @@ public function testNoUpdateForUnalteredChildrenOfAbstractEntities()
$this->entityManager->flush();

// start transaction, insert, commit
$this->assertEquals(3, $this->getCurrentQueryCount());
static::assertEquals(3, $this->getCurrentQueryCount());

// Remove all logged queries
$this->resetQueryStack();
Expand All @@ -103,6 +103,6 @@ public function testNoUpdateForUnalteredChildrenOfAbstractEntities()

// Verify there are no queries executed
$this->assertNull($this->getLatestUpdateQuery());
$this->assertEquals(0, $this->getCurrentQueryCount());
static::assertEquals(0, $this->getCurrentQueryCount());
}
}
2 changes: 1 addition & 1 deletion tests/Functional/BasicQueryTest/BasicQueryHaliteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protected function getEncryptor(): EncryptorInterface
public function setUp(): void
{
if (!extension_loaded('sodium') && !class_exists('ParagonIE_Sodium_Compat')) {
$this->markTestSkipped('This test only runs when the sodium extension is enabled.');
static::markTestSkipped('This test only runs when the sodium extension is enabled.');

return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ public function testEncryptionHappensOnOnlyAnnotatedFields(): void
$connection = $em->getConnection();
$stmt = $connection->prepare('SELECT * from owner WHERE id = ?');
$owners = $em->getRepository(Owner::class)->findAll();
$this->assertCount(1, $owners);
static::assertCount(1, $owners);
/** @var Owner $owner */
$owner = $owners[0];
$this->assertEquals($secret, $owner->getSecret());
$this->assertEquals($notSecret, $owner->getNotSecret());
static::assertEquals($secret, $owner->getSecret());
static::assertEquals($notSecret, $owner->getNotSecret());
$stmt->bindValue(1, $owner->getId());
$results = $this->executeStatementFetchAll($stmt);
$this->assertCount(1, $results);
$result = $results[0];
$this->assertEquals($notSecret, $result['notSecret']);
static::assertEquals($notSecret, $result['notSecret']);
$this->assertNotEquals($secret, $result['secret']);
$this->assertStringEndsWith('<ENC>', $result['secret']);
$decrypted = $this->encryptor->decrypt(str_replace('<ENC>', '', $result['secret']));
$this->assertEquals($secret, $decrypted);
static::assertEquals($secret, $decrypted);
}

public function testEncryptionCascades(): void
Expand All @@ -73,17 +73,17 @@ public function testEncryptionCascades(): void
$this->assertCount(1, $cascadeTargets);
/** @var CascadeTarget $cascadeTarget */
$cascadeTarget = $cascadeTargets[0];
$this->assertEquals($secret, $cascadeTarget->getSecret());
$this->assertEquals($notSecret, $cascadeTarget->getNotSecret());
static::assertEquals($secret, $cascadeTarget->getSecret());
static::assertEquals($notSecret, $cascadeTarget->getNotSecret());
$stmt->bindValue(1, $cascadeTarget->getId());
$results = $this->executeStatementFetchAll($stmt);
$this->assertCount(1, $results);
$result = $results[0];
$this->assertEquals($notSecret, $result['notSecret']);
static::assertEquals($notSecret, $result['notSecret']);
$this->assertNotEquals($secret, $result['secret']);
$this->assertStringEndsWith('<ENC>', $result['secret']);
$decrypted = $this->encryptor->decrypt(str_replace('<ENC>', '', $result['secret']));
$this->assertEquals($secret, $decrypted);
static::assertEquals($secret, $decrypted);
}

public function testEncryptionClassTableInheritance(): void
Expand Down Expand Up @@ -171,16 +171,16 @@ public function testEncryptionDoesNotHappenWhenThereIsNoChange(): void
$owners = $em->getRepository(Owner::class)->findAll();
/** @var Owner $owner */
foreach ($owners as $owner) {
$this->assertEquals($secret, $owner->getSecret());
$this->assertEquals($notSecret, $owner->getNotSecret());
static::assertEquals($secret, $owner->getSecret());
static::assertEquals($notSecret, $owner->getNotSecret());
}
$this->resetQueryStack();
$this->assertCount(0, $this->getDebugQueries());
$beforeFlush = $this->subscriber->encryptCounter;
$em->flush();
$afterFlush = $this->subscriber->encryptCounter;
// No encryption should have happened because we didn't change anything.
$this->assertEquals($beforeFlush, $afterFlush);
static::assertEquals($beforeFlush, $afterFlush);
// No queries happened because we didn't change anything.
$this->assertCount(0, $this->getDebugQueries(), "Unexpected queries:\n".var_export($this->getDebugQueries(), true));

Expand All @@ -189,7 +189,7 @@ public function testEncryptionDoesNotHappenWhenThereIsNoChange(): void
$em->flush();
$afterFlush = $this->subscriber->encryptCounter;
// No encryption should have happened because we didn't change anything.
$this->assertEquals($beforeFlush, $afterFlush);
static::assertEquals($beforeFlush, $afterFlush);
// No queries happened because we didn't change anything.
$this->assertCount(0, $this->getDebugQueries(), "Unexpected queries:\n".var_export($this->getDebugQueries(), true));

Expand All @@ -199,7 +199,7 @@ public function testEncryptionDoesNotHappenWhenThereIsNoChange(): void
$result = $results[0];
$shouldBeTheSameAsBefore = $result['secret'];
$this->assertStringEndsWith('<ENC>', $shouldBeTheSameAsBefore); // is encrypted
$this->assertEquals($originalEncryption, $shouldBeTheSameAsBefore);
static::assertEquals($originalEncryption, $shouldBeTheSameAsBefore);
}

public function testEncryptionDoesNotHappenWhenThereIsNoChangeClassInheritance(): void
Expand Down Expand Up @@ -332,7 +332,7 @@ public function testEntitySetterUseStrtoupper()

$this->assertStringEndsWith(DoctrineEncryptSubscriber::ENCRYPTION_MARKER, $passwordData);
$this->assertStringDoesNotContain('my secret', $passwordData);
$this->assertEquals('MY SECRET', $secret);
static::assertEquals('MY SECRET', $secret);
}

public function testEntityWithDateTimeJsonAndArrayProperties()
Expand Down Expand Up @@ -361,7 +361,7 @@ public function testEntityWithDateTimeJsonAndArrayProperties()
// Doctrine datetime type is only for date and time. milliseconds and timezone is not stored.
// We only test the date and time accordingly
// https://www.doctrine-project.org/projects/doctrine-dbal/en/3.7/reference/types.html#datetime
$this->assertEquals($datetime->format('Y-m-d\\TH:i:s'), $entityDate->format('Y-m-d\\TH:i:s'));
$this->assertEquals($jsonArray, $entityJson);
static::assertEquals($datetime->format('Y-m-d\\TH:i:s'), $entityDate->format('Y-m-d\\TH:i:s'));
static::assertEquals($jsonArray, $entityJson);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protected function getEncryptor(): EncryptorInterface
public function setUp(): void
{
if (!extension_loaded('sodium') && !class_exists('ParagonIE_Sodium_Compat')) {
$this->markTestSkipped('This test only runs when the sodium extension is enabled.');
static::markTestSkipped('This test only runs when the sodium extension is enabled.');

return;
}
Expand Down
Loading

0 comments on commit aa75652

Please sign in to comment.