mogilvie / EncryptBundle

Encryption bundle
82 stars 27 forks source link

[Question] What do You need `DoctrineEncryptSubscriber::postLoad` for? #19

Closed Volmarg closed 3 years ago

Volmarg commented 3 years ago

Hello,

First of all - this might not be a bug - not sure about this. I just need an info to investigate that further.

You've recently added the event which allows to change the encryption key - that works fine but got a problem related to this now. So I've spent over 1h trying to find out what's going on.

What is the purpose of the block in DoctrineEncryptSubscriber:

    /**
     * Listen a postLoad lifecycle event. Checking and decrypt entities
     * which have @Encrypted annotations
     *
     * @param LifecycleEventArgs $args
     * @throws EncryptException
     */
    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $em = $args->getEntityManager();

        if (!$this->hasInDecodedRegistry($entity)) {
            if ($this->processFields($entity, $em, false)) {
                $this->addToDecodedRegistry($entity);
            }
        }
    }

I believe it's needed in case when You save an entity and You still use it later on, like this:

$this->em->persist($entity);
$this->em->flush();

$entity->getValueForSomeReason();

Am I correct with understanding of this?

mogilvie commented 3 years ago

Hi Volmarg,

Not quite correct, although the postFlush event handles that situation.

The bundle contains a subscriber that catches three of the doctrine triggered events, onFlush, postLoad and postFlush. onFlush is triggered as doctrine prepares to persist the entity to the database. The subscriber intercepts the entity and encodes any fields that are supposed to be encrypted before they go to the db. The postFlush event is then triggered after persistence, and decodes the encrypted fields again, so that you can continue to work with the un-encoded data. For instance if your controller persisted the data (which would encrypt the values) but you then carried on and had to do something else with the data. A common case would be if you persisted something to the DB, then used the same entity to create a flash message notifying the user that the value has been successfully saved. You don't want to display the encrypted value. PostFlush converts the value back to unencrypted so that you can display the message. The postLoad event is triggered by doctrine when you load an entity via doctrine. The postLoad subscriber decrypts any encoded field in the entity. These are Doctrine events, so if you're not using Doctrine to load/persist the entity then they don't fire. For instance, if you're querying the DB directly, or if you're selecting fields, then you need to call the decryption process yourself using the EncoderService, or the twig function.

Volmarg commented 3 years ago

Hey,

Thanks for info. I will get back to it rather later as I'm way out of time for this week. I needed the info due to implementation in my both projects.

In case of Issues I will just come back with them - so for now feel free to close the issue as I won't be able to verify this etc.