From 5d14e1175c4c6d177be96d3f46b4b6a871a518b6 Mon Sep 17 00:00:00 2001 From: Robin Keet Date: Thu, 29 Mar 2018 11:49:51 +0200 Subject: [PATCH 1/2] Added type property to Encrypted Annotation class - marks the type the value should be before and after en-/decrypt service. --- src/Annotation/Encrypted.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Annotation/Encrypted.php b/src/Annotation/Encrypted.php index 5e428e9..a7c1975 100644 --- a/src/Annotation/Encrypted.php +++ b/src/Annotation/Encrypted.php @@ -30,6 +30,11 @@ class Encrypted */ public $pepper; + /** + * @var string type that the encrypted/decrypted string should be + */ + public $type = 'string'; + /** * @return string */ @@ -84,4 +89,22 @@ public function setPepper(?string $pepper): Encrypted return $this; } + /** + * @return null|string + */ + public function getType(): ?string + { + return $this->type; + } + + /** + * @param null|string $type + * @return Encrypted + */ + public function setType(string $type): Encrypted + { + $this->type = $type; + return $this; + } + } \ No newline at end of file From 92fdc64cef20ae41687554ef6851fd9697440042 Mon Sep 17 00:00:00 2001 From: Robin Keet Date: Thu, 29 Mar 2018 11:51:48 +0200 Subject: [PATCH 2/2] Added usage of type Encrypted property to set the type of the decrypted value after decryption, or throw an error if it cannot be set to that type. --- src/Subscriber/DoctrineEncryptSubscriber.php | 33 ++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/Subscriber/DoctrineEncryptSubscriber.php b/src/Subscriber/DoctrineEncryptSubscriber.php index f5f5bc0..1aef324 100644 --- a/src/Subscriber/DoctrineEncryptSubscriber.php +++ b/src/Subscriber/DoctrineEncryptSubscriber.php @@ -199,10 +199,12 @@ public static function capitalize(string $word): string /** * Process (encrypt/decrypt) entities fields * - * @param object $entity Some doctrine entity + * @param $entity * @param EntityManager $em * @param bool $isEncryptOperation * @return bool + * @throws \Doctrine\ORM\Mapping\MappingException + * @throws \Exception */ private function processFields($entity, EntityManager $em, $isEncryptOperation = true): bool { @@ -216,14 +218,37 @@ private function processFields($entity, EntityManager $em, $isEncryptOperation = $refProperty = $property['reflection']; /** @var Encrypted $annotationOptions */ $annotationOptions = $property['options']; + /** @var boolean $nullable */ + $nullable = $property['nullable']; $value = $refProperty->getValue($entity); - $value = $value === null ? '' : $value; + // If the value is 'null' && is nullable, don't do anything, just skip it. + if (is_null($value) && $nullable) { + + continue; + } $value = $isEncryptOperation ? $this->encrypt($entity, $value, $annotationOptions) : $this->decrypt($entity, $value, $annotationOptions); + $type = $annotationOptions->getType(); + + // If NOT encrypting, type know to PHP and the value does not match the type. Else error + if ( + !$isEncryptOperation + // We're going to try a cast using settype. Array of types defined at: https://php.net/settype + && in_array($type, ['boolean', 'bool', 'integer', 'int', 'float', 'double', 'string', 'array', 'object', 'null']) + && gettype($value) !== $type + ) { + settype($value, $type); + } else { + + throw new \Exception( + 'Could not convert encrypted value back to mapped value in ' . __CLASS__ . '::' . __FUNCTION__ . PHP_EOL + ); + } + $refProperty->setValue($entity, $value); if (! $isEncryptOperation) { @@ -394,7 +419,8 @@ private function addToDecodedRegistry($entity) /** * @param object $entity * @param EntityManager $em - * @return array|mixed|\ReflectionProperty[] + * @return array|mixed + * @throws \Doctrine\ORM\Mapping\MappingException */ private function getEncryptedFields(object $entity, EntityManager $em) { @@ -419,6 +445,7 @@ private function getEncryptedFields(object $entity, EntityManager $em) $encryptedFields[] = [ 'reflection' => $refProperty, 'options' => $annotationOptions, + 'nullable' => $meta->getFieldMapping($refProperty->getName())['nullable'], ]; } }