0

I've got a Listener that decrypts certain fields at postLoad event. It's working great except for the issue that the related entities to the main one don't work.

I tried to edit my entities so the associations have the fetch="EAGER" but that only solves half of the issue, as if the app has to load two entities with the same relation, it fails again. Example:

Entity1 has id_company of 2. in this case, fetch EAGER works great.

Entity1 has id_company of 2 Entity2 has id_company of 2 in this case, the decryption fails.

Here's my relevant code of the Listener:

class EntityEncryptionListener implements EventSubscriber
{
    private $secret;
    private $secret_original;
    private $request;


    public function __construct($secret,  RequestStack $request)
    {
        $this->secret = $secret;
        $this->secret_original = $secret;
        $this->request = $request;
    }
    
    public function getSubscribedEvents()
    {
        return [Events::prePersist, Events::preUpdate, Events::postLoad];
    }

    public function prePersist(LifecycleEventArgs $args)
    {
        $this->getSecret();
        $this->encryptEntity($args);
    }

    public function preUpdate(LifecycleEventArgs $args)
    {
        $this->getSecret();
        $this->encryptEntity($args);
    }

    public function postLoad(LifecycleEventArgs $args)
    {
        $this->getSecret();
        $this->decryptEntity($args);
    }

    private function decryptEntity(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        // Obtén el lector de anotaciones de Doctrine
        $annotationReader = new AnnotationReader();

        // Recorre todas las propiedades de la entidad
        $reflectionClass = new \ReflectionClass(get_class($entity));
        $properties = $reflectionClass->getProperties();
        
        $unitOfWork = $args->getEntityManager()->getUnitOfWork();
        $originalData = $unitOfWork->getOriginalEntityData($entity);

        foreach ($properties as $property) {
            $encriptado = false;
            $annotationEnc = $annotationReader->getPropertyAnnotation($property, 'App\Annotation\Encrypted');
            $annotationEncOrig = $annotationReader->getPropertyAnnotation($property, 'App\Annotation\EncryptedOriginal');

            if ($annotationEnc !== null) {
                $encriptado = true; 
                $secret = $this->secret;
            }
            if ($annotationEncOrig !== null){
                $encriptado = true;
                $secret = $this->secret_original;
            }

            $property->setAccessible(true);
            if ($encriptado && $property->getValue($entity)){    
                $encryptedValue = $property->getValue($entity);

                try{
                    $key = Key::loadFromAsciiSafeString($secret);
                    
                    if ($encryptedValue && $key){
                        $decryptedValue = Crypto::decrypt($encryptedValue, $key);
                    }
                    $property->setValue($entity, $decryptedValue);
                    $originalData[$property->getName()] = $decryptedValue;
                }catch(Exception $e){

                }
                    
            }
        }
        $unitOfWork->setOriginalEntityData($entity, $originalData);
    }

0 Answers0