[Encryption] Add support for Field-Level Automatic and Queryable Encryption#2759
[Encryption] Add support for Field-Level Automatic and Queryable Encryption#2759GromNaN merged 29 commits intodoctrine:feature/queryable-encryptionfrom
Conversation
a6ec9ed to
81f3e90
Compare
alcaeus
left a comment
There was a problem hiding this comment.
Left some questions, and phpstan seems to be unhappy about some of the mapping types.
The logic and tests for it look solid.
| <xs:element name="field" type="odm:field" minOccurs="0" maxOccurs="unbounded" /> | ||
| <xs:element name="embed-one" type="odm:embed-one" minOccurs="0" maxOccurs="unbounded" /> | ||
| <xs:element name="embed-many" type="odm:embed-many" minOccurs="0" maxOccurs="unbounded" /> | ||
| <xs:element name="encrypt" type="odm:encrypt-field" minOccurs="0" maxOccurs="1" /> |
There was a problem hiding this comment.
Why is this an element instead of an attribute? Is it to future-proof this in case there will be options for encrypting entire documents in future?
There was a problem hiding this comment.
Yes, I plan to add a "key" attribute to the element.
There was a problem hiding this comment.
As discussed, the "key" don't need to be configured with queryable encryption. I keep the distinct XML attribute for extensibility.
| $this->dm->getClientEncryption(), | ||
| $this->dm->getConfiguration()->getKmsProvider(), | ||
| null, // @todo when is it necessary to set the master key? | ||
| $options, |
There was a problem hiding this comment.
Should you be using $this->getWriteOptions here like below and add the encrypted field config?
tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php
Outdated
Show resolved
Hide resolved
f67e094 to
18d7c18
Compare
| 'min', 'max' => match ($mapping['type']) { | ||
| Type::INT => (int) $encryptValue, | ||
| Type::FLOAT => (float) $encryptValue, | ||
| Type::DECIMAL128 => new Decimal128((string) $encryptValue), | ||
| Type::DATE, Type::DATE_IMMUTABLE => new UTCDateTime(new DateTimeImmutable((string) $encryptValue)), | ||
| default => null, // Invalid | ||
| }, |
There was a problem hiding this comment.
I've added the transformation of values from string to native BSON types here; should use the Type::convertToDatabaseValue() inside EncryptionFieldMap.
…octrine#2773) CommandSucceededEvent|CommandFailedEvent::getServer() has been deprecated in ext-mongodb 1.20 and removed in 2.0.0. For backward compatibility: we keep this method in MongoDB ODM, but throw an exception the extension is not compatible. I'm not adding a trigger_deprecation as this is already triggered by the extension method call. The new methods getPort() and getHost() are added as proxy to extension methods that are always available in the required ext-mongodb 1.21+. This is not covered by tests, I can add tests on CommandLogger before merging.
* CursorInterface always extends Traversable, no need to assert on SPL Iterator * Remove duplicate assert
| $class->getCollection(), | ||
| $this->dm->getClientEncryption(), | ||
| $this->dm->getConfiguration()->getKmsProvider(), | ||
| null, // @todo when is it necessary to set the master key? |
There was a problem hiding this comment.
To leave a quick answer, some KMS providers require a master key (e.g. AWS)
| new Command(['buildInfo' => 1]), | ||
| )->toArray()[0]; | ||
|
|
||
| if (! in_array('enterprise', $buildInfo->modules ?? [])) { |
There was a problem hiding this comment.
I noticed that atlas-local does not expose an enterprise module, so we may want to remove this check before wrapping up the feature.
72ee408
into
doctrine:feature/queryable-encryption
* Add test document classes from tutorial https://github.com/mongodb/docs/blob/master/source/includes/qe-tutorials/node/queryable-encryption-tutorial.js * Create encryption field map * Create encrypted collection * Use promoted properties for encrypted document tests * Revert changes in BaseTestCase * Rename EncryptionFieldMapTest * Create Configuration::getDriverOptions() to create the client * Support class-level #[Encrypt] attribute * Skip QE tests on non-supported server configuration * Add documentation on #[Encrypt] attribute * Add XML mapping for "encrypt" tag * Create specific xsd type for embedded documents to enable <encrypt> tag * Fix import class Throwable * Fix access to $version property before initialization * Use an enum for query type * Make getClientEncryption internal * Improve type of min/max bounds for range queries * Use getWriteOptions with createEncryptedCollection * Use random local master key * Add assertion on non-decrypted data * Ignore all DOCTRINE_MONGODB_DATABASE phpstan errors * Baseline phpstan * Fix CS and skip phpstan issues
Summary
Implementation:
#[Encrypt]attribute with field encryption options.autoEncryptionconfiguration with options to create an encryption client (MongoDB collection that stores encryption keys for each field)The encrypted collection must be created using the schema manager (
odm:schema:createcommand)