diff --git a/composer.json b/composer.json index 166c595..cffb404 100644 --- a/composer.json +++ b/composer.json @@ -23,23 +23,24 @@ "doctrine/annotations": "^2.0", "doctrine/orm": "^2.7", "paragonie/ciphersweet": "^3.0 || ^4.0", - "symfony/config": "^4.4 || ^5.1 || ^6.0", - "symfony/console": "^4.4 || ^5.1 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.1 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.1 || ^6.0", - "symfony/process": "^4.4 || ^5.1 || ^6.0", - "symfony/property-access": "^4.4 || ^5.1 || ^6.0", - "symfony/property-info": "^4.4 || ^5.1 || ^6.0", - "symfony/yaml": "^4.4 || ^5.1 || ^6.0" + "symfony/config": "^5.4 || ^6.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/deprecation-contracts": "^2.5 || ^3.2", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/process": "^5.4 || ^6.0", + "symfony/property-access": "^5.4 || ^6.0", + "symfony/property-info": "^5.4 || ^6.0", + "symfony/yaml": "^5.4 || ^6.0" }, "require-dev": { "doctrine/doctrine-bundle": "^2.7", + "phpunit/phpunit": "^9.5", "roave/security-advisories": "dev-latest", - "symfony/doctrine-bridge": "^5.1 || ^6.0", - "symfony/dotenv": "^5.1 || ^6.0", - "symfony/framework-bundle": "^5.1 || ^6.0", - "symfony/phpunit-bridge": "^5.1 || ^6.0", - "symfony/test-pack": "^1.0" + "symfony/doctrine-bridge": "^5.4 || ^6.0", + "symfony/dotenv": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc" diff --git a/src/Command/EncryptionKeyStringProviderGenerator.php b/src/Command/EncryptionKeyStringProviderGenerator.php index bb46123..4d15eae 100644 --- a/src/Command/EncryptionKeyStringProviderGenerator.php +++ b/src/Command/EncryptionKeyStringProviderGenerator.php @@ -6,20 +6,25 @@ namespace Odandb\DoctrineCiphersweetEncryptionBundle\Command; use ParagonIE\ConstantTime\Hex; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand(name: 'odb:enc:generate-string-key', description: 'Generate default encryption key for StringProvider (one of the different key provider managed by Ciphersweet library).')] class EncryptionKeyStringProviderGenerator extends Command { + /** @deprecated */ protected static $defaultName = 'odb:enc:generate-string-key'; - protected static $defaultAlias = 'o:e:g'; + /** @deprecated */ + protected static $defaultDescription = 'Generate default encryption key for StringProvider (one of the different key provider managed by Ciphersweet library).'; + + protected static string $defaultAlias = 'o:e:g'; protected function configure(): void { $this - ->setDescription('Generate default encryption key for StringProvider (one of the different key provider managed by Ciphersweet library).') ->setAliases([self::$defaultAlias]) ; } diff --git a/src/Command/FieldIndexPlannerCommand.php b/src/Command/FieldIndexPlannerCommand.php index ebdeace..973b9fd 100644 --- a/src/Command/FieldIndexPlannerCommand.php +++ b/src/Command/FieldIndexPlannerCommand.php @@ -7,20 +7,25 @@ use ParagonIE\CipherSweet\Planner\FieldIndexPlanner; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand(name: 'odb:enc:planner', description: 'Determine the Blind Index plan for a given field.')] class FieldIndexPlannerCommand extends Command { + /** @deprecated */ protected static $defaultName = 'odb:enc:planner'; - protected static $defaultAlias = 'o:e:pl'; + /** @deprecated */ + protected static $defaultDescription = 'Determine the Blind Index plan for a given field.'; + + protected static string $defaultAlias = 'o:e:pl'; protected function configure(): void { $this - ->setDescription('Determine the Blind Index plan for a given field.') ->setAliases([self::$defaultAlias]) ; } diff --git a/src/Command/GenerateIndexesCommand.php b/src/Command/GenerateIndexesCommand.php index a44d4df..4b2e2d0 100644 --- a/src/Command/GenerateIndexesCommand.php +++ b/src/Command/GenerateIndexesCommand.php @@ -6,6 +6,7 @@ namespace Odandb\DoctrineCiphersweetEncryptionBundle\Command; use Odandb\DoctrineCiphersweetEncryptionBundle\Services\IndexableFieldsService; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -15,10 +16,15 @@ use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; +#[AsCommand(name: 'odb:enc:indexes', description: 'Determine the Blind Index plan for a given field.')] class GenerateIndexesCommand extends Command { + /** @deprecated */ protected static $defaultName = 'odb:enc:indexes'; - protected static $defaultAlias = 'o:e:i'; + /** @deprecated */ + protected static $defaultDescription = 'Determine the Blind Index plan for a given field.'; + + protected static string $defaultAlias = 'o:e:i'; protected const CONSOLE_ENTRYPOINT = 'bin/console'; protected const NB_RUNNING_PROCESSES = 5; @@ -39,7 +45,6 @@ public function __construct(IndexableFieldsService $indexableFieldsService, stri protected function configure(): void { $this - ->setDescription('Determine the Blind Index plan for a given field.') ->setAliases([self::$defaultAlias]) ->addArgument('class', InputArgument::REQUIRED, 'The entity class having fields that need a complete indexes recalculation.') diff --git a/src/Configuration/EncryptedField.php b/src/Configuration/EncryptedField.php index 33e0b6c..4cd82de 100644 --- a/src/Configuration/EncryptedField.php +++ b/src/Configuration/EncryptedField.php @@ -5,18 +5,35 @@ namespace Odandb\DoctrineCiphersweetEncryptionBundle\Configuration; +use Attribute; +use Odandb\DoctrineCiphersweetEncryptionBundle\Encryptors\EncryptorInterface; + /** * The Encrypted class handles the @EncryptedField annotation. * * @Annotation + * @NamedArgumentConstructor + * @Target({"PROPERTY","ANNOTATION"}) */ +#[Attribute(Attribute::TARGET_PROPERTY)] class EncryptedField { - /** @var int */ - public int $filterBits = 32; + /** @readonly */ + public int $filterBits = EncryptorInterface::DEFAULT_FILTER_BITS; - public string $mappedTypedProperty; + /** @readonly */ + public ?string $mappedTypedProperty = null; - /** @var bool */ + /** @readonly */ public bool $indexable = true; + + public function __construct( + int $filterBits = EncryptorInterface::DEFAULT_FILTER_BITS, + ?string $mappedTypedProperty = null, + bool $indexable = true + ) { + $this->filterBits = $filterBits; + $this->mappedTypedProperty = $mappedTypedProperty; + $this->indexable = $indexable; + } } diff --git a/src/Configuration/IndexableField.php b/src/Configuration/IndexableField.php index 29010d5..5e0c421 100644 --- a/src/Configuration/IndexableField.php +++ b/src/Configuration/IndexableField.php @@ -5,18 +5,45 @@ namespace Odandb\DoctrineCiphersweetEncryptionBundle\Configuration; +use Attribute; use Odandb\DoctrineCiphersweetEncryptionBundle\Encryptors\EncryptorInterface; /** * The Encrypted class handles the @IndexableField annotation. * * @Annotation + * @NamedArgumentConstructor + * @Target({"PROPERTY","ANNOTATION"}) */ +#[Attribute(Attribute::TARGET_PROPERTY)] class IndexableField { - public bool $autoRefresh = true; + /** @readonly */ public string $indexesEntityClass; - public array $indexesGenerationMethods; - public string $valuePreprocessMethod; + + /** @readonly */ + public bool $autoRefresh = true; + + /** @readonly */ + public array $indexesGenerationMethods = []; + + /** @readonly */ + public ?string $valuePreprocessMethod = null; + + /** @readonly */ public bool $fastIndexing = EncryptorInterface::DEFAULT_FAST_INDEXING; + + public function __construct( + string $indexesEntityClass, + bool $autoRefresh = true, + array $indexesGenerationMethods = [], + ?string $valuePreprocessMethod = null, + bool $fastIndexing = EncryptorInterface::DEFAULT_FAST_INDEXING + ) { + $this->indexesEntityClass = $indexesEntityClass; + $this->autoRefresh = $autoRefresh; + $this->indexesGenerationMethods = $indexesGenerationMethods; + $this->valuePreprocessMethod = $valuePreprocessMethod; + $this->fastIndexing = $fastIndexing; + } } diff --git a/src/Entity/IndexedEntityAttributeTrait.php b/src/Entity/IndexedEntityAttributeTrait.php new file mode 100644 index 0000000..502868b --- /dev/null +++ b/src/Entity/IndexedEntityAttributeTrait.php @@ -0,0 +1,66 @@ + If we delete $targetEntity, we need to delete cascade to the list EntityFilters + */ + #[ORM\JoinColumn(name: 'target_entity_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + protected object $targetEntity; + + #[ORM\Column(type: 'string', length: 10)] + protected string $indexBi; + + public function getId(): ?int + { + return $this->id; + } + + public function getFieldname(): string + { + return $this->fieldname; + } + + public function setFieldname(string $fieldname): self + { + $this->fieldname = $fieldname; + return $this; + } + + public function getTargetEntity(): object + { + return $this->targetEntity; + } + + public function setTargetEntity(?object $targetEntity): self + { + $this->targetEntity = $targetEntity; + return $this; + } + + public function getIndexBi(): string + { + return $this->indexBi; + } + + public function setIndexBi(string $indexBi): self + { + $this->indexBi = $indexBi; + return $this; + } +} diff --git a/src/Entity/IndexedEntityTrait.php b/src/Entity/IndexedEntityTrait.php index c8a08e2..bb6a583 100644 --- a/src/Entity/IndexedEntityTrait.php +++ b/src/Entity/IndexedEntityTrait.php @@ -22,10 +22,9 @@ trait IndexedEntityTrait protected string $fieldname; /** - * @var object + * onDeleteCascade -> If we delete $targetEntity, we need to delete cascade to the list EntityFilters * * @ORM\JoinColumn(name="target_entity_id", referencedColumnName="id", onDelete="CASCADE") - * onDeleteCascade -> si on supprime $targetEntity, on cascade la suppression jusqu'à la liste de EntityFilters */ protected object $targetEntity; @@ -34,62 +33,38 @@ trait IndexedEntityTrait */ protected string $indexBi; - /** - * @return int - */ public function getId(): ?int { return $this->id; } - /** - * @return string - */ public function getFieldname(): string { return $this->fieldname; } - /** - * @param string $fieldname - * @return IndexedEntityTrait - */ public function setFieldname(string $fieldname): self { $this->fieldname = $fieldname; return $this; } - /** - * @return object - */ public function getTargetEntity(): object { return $this->targetEntity; } - /** - * @param object|null $targetEntity - * @return $this - */ public function setTargetEntity(?object $targetEntity): self { $this->targetEntity = $targetEntity; return $this; } - /** - * @return string - */ public function getIndexBi(): string { return $this->indexBi; } - /** - * @param string $indexBi - * @return self - */ public function setIndexBi(string $indexBi): self { $this->indexBi = $indexBi; diff --git a/src/Services/IndexableFieldsService.php b/src/Services/IndexableFieldsService.php index ea080bc..0a89f16 100644 --- a/src/Services/IndexableFieldsService.php +++ b/src/Services/IndexableFieldsService.php @@ -17,7 +17,6 @@ class IndexableFieldsService { - public const ENCRYPTED_ANN_NAME = EncryptedField::class; public const INDEXABLE_ANN_NAME = IndexableField::class; private Reader $annReader; @@ -33,7 +32,6 @@ public function __construct(Reader $annReader, EntityManagerInterface $em, Index public function getChunksForMultiThread(string $className, int $chuncksLength): array { - /** @var EntityRepository $repo */ $repo = $this->em->getRepository($className); $result = $repo->createQueryBuilder('c') ->select('c.id') @@ -63,7 +61,21 @@ static function (\ReflectionProperty $refProperty): string {return $refProperty- throw new MissingPropertyFromReflectionException(sprintf("No refProperty found for fieldname %s", $fieldname)); } - $indexableAnnotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::INDEXABLE_ANN_NAME); + $indexableAnnotationConfig = null; + if (PHP_VERSION_ID >= 80000 && null !== $refAttribute = $refProperty->getAttributes(self::INDEXABLE_ANN_NAME)[0] ?? null) { + $indexableAnnotationConfig = $refAttribute->newInstance(); + } + + if (null === $indexableAnnotationConfig) { + $indexableAnnotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::INDEXABLE_ANN_NAME); + if (PHP_VERSION_ID >= 80000) { + trigger_deprecation( + 'odandb/doctrine-ciphersweet-encryption-bundle', + '0.10.5', + 'The support of annotation is deprecated and will be remove in doctrine-ciphersweet-encryption-bundle 1.0' + ); + } + } if ($indexableAnnotationConfig instanceof IndexableField) { $contexts []= ['refProperty' => $refProperty, 'indexableConfig' => $indexableAnnotationConfig]; @@ -128,7 +140,7 @@ public function generateIndexableValuesForEntity(object $entity, array $fieldsCo } $cleanValue = $value; - $valueCleanerMethod = $indexableAnnotationConfig->valuePreprocessMethod ?? null; + $valueCleanerMethod = $indexableAnnotationConfig->valuePreprocessMethod; if ($valueCleanerMethod !== null && (method_exists($entity, $valueCleanerMethod) || method_exists(get_class($entity), $valueCleanerMethod))) { $cleanValue = $entity->$valueCleanerMethod($value); } @@ -136,7 +148,7 @@ public function generateIndexableValuesForEntity(object $entity, array $fieldsCo // On appelle le service de génération des index de filtre qui va créer la collection de pattern possibles // en fonction de la ou des méthodes renseignées en annotation // Puis récupérer chaque "blind_index" associé à enregistrer en base - $indexesMethods = $indexableAnnotationConfig->indexesGenerationMethods ?? []; + $indexesMethods = $indexableAnnotationConfig->indexesGenerationMethods; $indexesToEncrypt = $this->indexesGenerator->generateAndEncryptFilters($cleanValue, $indexesMethods); $indexesToEncrypt [] = $value; @@ -150,7 +162,7 @@ public function generateIndexableValuesForEntity(object $entity, array $fieldsCo /** * @param object $entity - * @param array['refProperty' => \ReflectionProperty, 'indexableConfig' => IndexableField] $fieldsContexts + * @param array{'refProperty': \ReflectionProperty, 'indexableConfig': IndexableField} $fieldsContexts * @param bool $needsToComputeChangeset * * @throws \Odandb\DoctrineCiphersweetEncryptionBundle\Exception\UndefinedGeneratorException @@ -172,7 +184,7 @@ public function handleIndexableFieldsForEntity(object $entity, array $fieldsCont $indexesToEncrypt = $searchIndexes[$refProperty->getName()]; - $indexes = $this->indexesGenerator->generateBlindIndexesFromPossibleValues(get_class($entity), $refProperty->getName(), $indexesToEncrypt, $indexableAnnotationConfig->fastIndexing ?? EncryptorInterface::DEFAULT_FAST_INDEXING); + $indexes = $this->indexesGenerator->generateBlindIndexesFromPossibleValues(get_class($entity), $refProperty->getName(), $indexesToEncrypt, $indexableAnnotationConfig->fastIndexing); // On crée les instances d'objet filtre et on les associe à l'entité parente $indexEntities = []; diff --git a/src/Subscribers/DoctrineCiphersweetSubscriber.php b/src/Subscribers/DoctrineCiphersweetSubscriber.php index 850ffc6..2410f79 100644 --- a/src/Subscribers/DoctrineCiphersweetSubscriber.php +++ b/src/Subscribers/DoctrineCiphersweetSubscriber.php @@ -149,10 +149,25 @@ private function getEncryptedFields(object $entity, EntityManagerInterface $em): $encryptedFields = []; foreach ($meta->getReflectionProperties() as $refProperty) { + if (PHP_VERSION_ID >= 80000 && isset($refProperty->getAttributes(self::ENCRYPTED_ANN_NAME)[0])) { + $refProperty->setAccessible(true); + $encryptedFields[] = $refProperty; + + continue; + } + /** @var \ReflectionProperty $refProperty */ if ($this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME)) { $refProperty->setAccessible(true); $encryptedFields[] = $refProperty; + + if (PHP_VERSION_ID >= 80000) { + trigger_deprecation( + 'odandb/doctrine-ciphersweet-encryption-bundle', + '0.10.5', + 'The support of annotation is deprecated and will be remove in doctrine-ciphersweet-encryption-bundle 1.0' + ); + } } } @@ -210,8 +225,32 @@ public function processFields(object $entity, EntityManagerInterface $em, $isEnc private function buildContext(string $entityClassName, \ReflectionProperty $refProperty): array { - $annotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME); - $indexableAnnotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::INDEXABLE_ANN_NAME); + $annotationConfig = null; + $indexableAnnotationConfig = null; + if (PHP_VERSION_ID >= 80000) { + $refEncryptedAttributes = $refProperty->getAttributes(self::ENCRYPTED_ANN_NAME); + $refIndexableAttributes = $refProperty->getAttributes(self::INDEXABLE_ANN_NAME); + + if (isset($refEncryptedAttributes[0])) { + $annotationConfig = $refEncryptedAttributes[0]->newInstance(); + } + if (isset($refIndexableAttributes[0])) { + $indexableAnnotationConfig = $refIndexableAttributes[0]->newInstance(); + } + } + + if (null === $annotationConfig && null === $indexableAnnotationConfig) { + $annotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME); + $indexableAnnotationConfig = $this->annReader->getPropertyAnnotation($refProperty, self::INDEXABLE_ANN_NAME); + + if (PHP_VERSION_ID >= 80000) { + trigger_deprecation( + 'odandb/doctrine-ciphersweet-encryption-bundle', + '0.10.5', + 'The support of annotation is deprecated and will be remove in doctrine-ciphersweet-encryption-bundle 1.0' + ); + } + } $storeBlindIndex = true; $filterBits = EncryptorInterface::DEFAULT_FILTER_BITS; @@ -220,7 +259,7 @@ private function buildContext(string $entityClassName, \ReflectionProperty $refP if ($annotationConfig instanceof EncryptedField) { $storeBlindIndex = $annotationConfig->indexable; $filterBits = $annotationConfig->filterBits; - $mappedTypedProperty = $annotationConfig->mappedTypedProperty ?? null; + $mappedTypedProperty = $annotationConfig->mappedTypedProperty; } return [ @@ -249,7 +288,7 @@ private function buildContext(string $entityClassName, \ReflectionProperty $refP private function handleEncryptOperation(object $entity, int $oid, $value, \ReflectionProperty $refProperty, array $context, ?string $force = null) { /** - * @var IndexableField $indexableAnnotationConfig + * @var null|IndexableField $indexableAnnotationConfig */ [ 'annotationConfig' => [ @@ -262,6 +301,9 @@ private function handleEncryptOperation(object $entity, int $oid, $value, \Refle ] = $context; $value = $this->propertyHydratorService->getMappedFieldValueAsString($entity, $mappedTypedProperty, $value); + if ('' === $value) { + return null; + } if ('encrypt' === $force) { $originalValue = $value; @@ -369,7 +411,7 @@ private function storeIndexes(object $entity, \ReflectionProperty $refProperty, return; } - $autoRefresh = $indexableAnnotationConfig->autoRefresh ?? false; + $autoRefresh = $indexableAnnotationConfig->autoRefresh; if ($autoRefresh === false) { return; } diff --git a/tests/App/Kernel.php b/tests/App/Kernel.php index 15e6b94..fde2026 100644 --- a/tests/App/Kernel.php +++ b/tests/App/Kernel.php @@ -15,7 +15,7 @@ class Kernel extends BaseKernel { use MicroKernelTrait; - private const CONFIG_EXTS = '.{php,xml,yaml,yml}'; + private const CONFIG_EXTS = '.{yaml,yml}'; public function registerBundles(): iterable { @@ -41,6 +41,12 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa $loader->load($this->getProjectDir().'/config/services'.self::CONFIG_EXTS, 'glob'); $loader->load($this->getProjectDir().'/config/{packages}/*'.self::CONFIG_EXTS, 'glob'); + if (PHP_VERSION_ID >= 80000) { + $loader->load($this->getProjectDir().'/config/doctrine80'.self::CONFIG_EXTS, 'glob'); + } else { + $loader->load($this->getProjectDir().'/config/doctrine74'.self::CONFIG_EXTS, 'glob'); + } + $confDir = $this->getProjectDir().'/../../src/Resources/config'; $loader->load($confDir.'/encryption-services'.self::CONFIG_EXTS, 'glob'); } diff --git a/tests/App/config/packages/doctrine.yaml b/tests/App/config/doctrine74.yaml similarity index 84% rename from tests/App/config/packages/doctrine.yaml rename to tests/App/config/doctrine74.yaml index 48c0d0e..3e3419e 100644 --- a/tests/App/config/packages/doctrine.yaml +++ b/tests/App/config/doctrine74.yaml @@ -19,9 +19,9 @@ doctrine: naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware auto_mapping: true mappings: - App: + Annotation: is_bundle: false type: annotation - dir: '%kernel.project_dir%/../Model' - prefix: 'Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\MyEntity' - alias: App + dir: '%kernel.project_dir%/../Model/Annotations' + prefix: 'Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\Annotations' + alias: Annotation diff --git a/tests/App/config/doctrine80.yaml b/tests/App/config/doctrine80.yaml new file mode 100644 index 0000000..c388fb0 --- /dev/null +++ b/tests/App/config/doctrine80.yaml @@ -0,0 +1,33 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + # configure these for your database server + driver: 'pdo_sqlite' + charset: utf8mb4 + default_table_options: + charset: utf8mb4 + collate: utf8mb4_unicode_ci + url: 'sqlite:///%kernel.project_dir%/var/data.db' + orm: + default_entity_manager: default + auto_generate_proxy_classes: true + entity_managers: + default: + connection: default + naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware + auto_mapping: true + mappings: + Annotation: + is_bundle: false + type: annotation + dir: '%kernel.project_dir%/../Model/Annotations' + prefix: 'Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\Annotations' + alias: Annotation + Attribute: + is_bundle: false + type: attribute + dir: '%kernel.project_dir%/../Model/Attributes' + prefix: 'Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\Attributes' + alias: Attribute diff --git a/tests/Model/MyEntity.php b/tests/Model/Annotations/MyEntity.php similarity index 94% rename from tests/Model/MyEntity.php rename to tests/Model/Annotations/MyEntity.php index ea1d43c..d312f3b 100644 --- a/tests/Model/MyEntity.php +++ b/tests/Model/Annotations/MyEntity.php @@ -3,7 +3,7 @@ declare(strict_types=1); -namespace Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model; +namespace Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\Annotations; use Doctrine\ORM\Mapping as ORM; @@ -24,8 +24,6 @@ class MyEntity /** * @ORM\Column(type="string") * @EncryptedField() - * - * @var string $accountName */ private string $accountName; @@ -39,9 +37,6 @@ public function __construct(string $accountName) $this->accountName = $accountName; } - /** - * @return int|null - */ public function getId(): ?int { return $this->id; diff --git a/tests/Model/Attributes/MyEntityAttribute.php b/tests/Model/Attributes/MyEntityAttribute.php new file mode 100644 index 0000000..98c65a6 --- /dev/null +++ b/tests/Model/Attributes/MyEntityAttribute.php @@ -0,0 +1,59 @@ +accountName = $accountName; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getAccountName(): string + { + return $this->accountName; + } + + public function setAccountName(string $accountName): void + { + $this->accountName = $accountName; + } + + public function getAccountNameBi(): string + { + return $this->accountNameBi; + } + + public function setAccountNameBi(string $accountNameBi): self + { + $this->accountNameBi = $accountNameBi; + + return $this; + } +} diff --git a/tests/Repository/MyEntityRepository.php b/tests/Repository/MyEntityRepository.php index 4b2b7e3..f4fd165 100644 --- a/tests/Repository/MyEntityRepository.php +++ b/tests/Repository/MyEntityRepository.php @@ -8,7 +8,7 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; -use Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\MyEntity; +use Odandb\DoctrineCiphersweetEncryptionBundle\Tests\Model\Annotations\MyEntity; class MyEntityRepository extends ServiceEntityRepository { diff --git a/tests/Repository/MyEntityRepositoryAttribute.php b/tests/Repository/MyEntityRepositoryAttribute.php new file mode 100644 index 0000000..4a0d228 --- /dev/null +++ b/tests/Repository/MyEntityRepositoryAttribute.php @@ -0,0 +1,19 @@ +get(EntityManagerInterface::class); - $encryptor = static::getContainer()->get(EncryptorInterface::class); - $service = static::getContainer()->get(DoctrineCiphersweetSubscriber::class); - $this->assertNotNull($service); + $this->em = static::getContainer()->get(EntityManagerInterface::class); + $this->encryptor = static::getContainer()->get(EncryptorInterface::class); + $this->service = static::getContainer()->get(DoctrineCiphersweetSubscriber::class); + } + /** + * @group legacy + */ + public function testProcessFieldsAnnotations() + { $entity = new MyEntity('test'); - $service->processFields($entity, $em); + $this->service->processFields($entity, $this->em); + + $this->assertStringStartsWith($this->encryptor->getPrefix(), $entity->getAccountName()); + + $this->service->processFields($entity, $this->em, false); + $this->assertSame('test', $entity->getAccountName()); + } + + public function testProcessFieldsAttributes() + { + if (PHP_VERSION_ID < 80000) { + $this->markTestSkipped('require PHP 8.0'); + } + + $entity = new MyEntityAttribute('test'); + $this->service->processFields($entity, $this->em); - $this->assertStringStartsWith($encryptor->getPrefix(), $entity->getAccountName()); + $this->assertStringStartsWith($this->encryptor->getPrefix(), $entity->getAccountName()); - $service->processFields($entity, $em, false); + $this->service->processFields($entity, $this->em, false); $this->assertSame('test', $entity->getAccountName()); } }