-
Notifications
You must be signed in to change notification settings - Fork 21
INTPYTHON-527 Add Queryable Encryption support #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
||
# Build a map of encrypted fields | ||
encrypted_fields = { | ||
"fields": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add query conditions
return ClientEncryption(kms_providers, key_vault_namespace, encrypted_connection, codec_options) | ||
|
||
|
||
def get_auto_encryption_opts(crypt_shared_lib_path=None, kms_providers=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crypt_shared
library is in the pymongocrypt
wheel, which is much easier than downloading separately and telling MongoClient
where it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More to this story:
libmongocrypt
is in thepymongocrypt
wheel, notcrypt_shared
which must always be downloaded and configured manually.libmongocrypt
works becausemongocryptd
is running on enterprise.
We should document this.
(via @ShaneHarvey, thanks!)
django_mongodb_backend/schema.py
Outdated
self.connection.features.supports_encryption | ||
and self.connection._settings_dict.get("OPTIONS", {}).get("auto_encryption_opts") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want encrypted models to silently fallback to working as unencrypted models.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we don't but I'm not sure why you are making that comment here … as of 65bd15a I'm creating two connections and using the encrypted_connection
only when needed. Is there a fallback scenario I'm missing? Seems like with two connections we're going to have to check every use of self.connection
to make sure we're using the right one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In _create_collection()
you're guarding the creation of an encrypted model based on this method, so if features.supports_encryption = False
but the model has encrypted fields, it's going to incorrectly use create_collection()
instead.
class EncryptedCharField(models.CharField): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.encrypted = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd think this could be a class-level variable.
django_mongodb_backend/schema.py
Outdated
# Use the encrypted connection and auto_encryption_opts to create an encrypted client | ||
encrypted_client = get_encrypted_client(auto_encryption_opts, encrypted_connection) | ||
|
||
with contextlib.suppress(EncryptedCollectionError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a comment about why the error should be suppressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be a case where we're trying to create a collection that already exists. It would be correct to surface that error to the user because their migrations are out of sync with their database.
Wrong commit message for 65bd15a and I don't want to force push yet. It should have said:
I'm aware that
|
It's not working as you think it is. As I said elsewhere, Does this fix the "command not supported for auto encryption: buildinfo" error? If so, it's perhaps because I'd suggest to use my patch is as a starting point for maintaining two connections. |
I don't disagree, but it feels a lot like
Yes it works by design, not a side effect. I'm
I'd make a few passes at it but did not get anywhere, I'll try again though. |
Your "stumble" theory of how it's working isn't correct. |
Copy that, thanks! I've removed
Still working on an unencrypted connection, but perhaps the only time we need it is for the version check. |
(see previous attempts in #318, #319 and #323 for additional context)
With this PR I am able to get Django to create an encrypted collection when the schema code is running
create_model
on anEncryptedModel
containing anEncryptedCharField
e.g. seedb.enxcol_.encryption__person.ecoc
belowQuestions
_nodb_cursor
functionality in this PR or do something ininit_connection_state
as @timgraham suggests, or do something else?command not supported for auto encryption: buildinfo
which happens when Django attempts to get the server version via encrypted connection, thus necessitating the need to manage both encrypted and unencrypted connections. Are most commands supported for auto encryption or not?EncryptedModel
support forEmbeddedModel
look like? What are the specific use cases for integration ofEncryptedModel
andEmbeddedModel
? Should we be able to mixinEncryptedModel
andEmbeddedModel
then include that model in anEmbeddedModelField
?Todo
pymongocrypt
wheel includescrypt_shared
library!Helpers
Included helpers are also used by the test runner e.g.