Skip to content

Commit 5cdfd0a

Browse files
aclark4lifetimgraham
authored andcommitted
Misc updates
- Add mongocryptd to atlas CI - Doc updates - Remove custom db_type, not needed after mongodb#414 - SupportsQueryableEncryptionTests require MongoDB 8 - Update test model names prefix and suffix
1 parent 2a8e657 commit 5cdfd0a

File tree

10 files changed

+274
-146
lines changed

10 files changed

+274
-146
lines changed

.github/workflows/test-python-atlas.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,27 @@ jobs:
5151
run: cp .github/workflows/runtests.py django_repo/tests/runtests_.py
5252
- name: Start local Atlas
5353
working-directory: .
54-
run: bash .github/workflows/start_local_atlas.sh mongodb/mongodb-atlas-local:7
54+
run: bash .github/workflows/start_local_atlas.sh mongodb/mongodb-atlas-local:8.0.15
55+
- name: Install mongosh
56+
run: |
57+
wget -q https://downloads.mongodb.com/compass/mongosh-2.2.10-linux-x64.tgz
58+
tar -xzf mongosh-*-linux-x64.tgz
59+
sudo cp mongosh-*-linux-x64/bin/mongosh /usr/local/bin/
60+
mongosh --version
61+
- name: Install mongocryptd from Enterprise tarball
62+
run: |
63+
curl -sSL -o mongodb-enterprise.tgz "https://downloads.mongodb.com/linux/mongodb-linux-x86_64-enterprise-ubuntu2204-8.0.15.tgz"
64+
tar -xzf mongodb-enterprise.tgz
65+
sudo cp mongodb-linux-x86_64-enterprise-ubuntu2204-8.0.15/bin/mongocryptd /usr/local/bin/
66+
- name: Start mongocryptd
67+
run: |
68+
nohup mongocryptd --logpath=/tmp/mongocryptd.log &
69+
- name: Verify MongoDB installation
70+
run: |
71+
mongosh --eval 'db.runCommand({ connectionStatus: 1 })'
72+
- name: Verify mongocryptd is running
73+
run: |
74+
pgrep mongocryptd
5575
- name: Run tests
5676
run: python3 django_repo/tests/runtests_.py
5777
permissions:

docs/howto/queryable-encryption.rst

Lines changed: 144 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Encryption in your Django project.
1414
.. admonition:: MongoDB requirements
1515

1616
Queryable Encryption can be used with MongoDB replica sets or sharded
17-
clusters running version 7.0 or later. Standalone instances are not
17+
clusters running version 8.0 or later. Standalone instances are not
1818
supported. The following table summarizes which MongoDB server products
1919
support each Queryable Encryption mechanism.
2020

@@ -51,21 +51,36 @@ encryption keys.
5151
5252
import os
5353
54-
from django_mongodb_backend import parse_uri
5554
from pymongo.encryption_options import AutoEncryptionOpts
5655
5756
DATABASES = {
58-
# ...
59-
"encrypted": parse_uri(
60-
DATABASE_URL,
61-
options={
57+
"default": {
58+
"ENGINE": "django_mongodb_backend",
59+
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
60+
"NAME": "my_database",
61+
"USER": "my_user",
62+
"PASSWORD": "my_password",
63+
"PORT": 27017,
64+
"OPTIONS": {
65+
"retryWrites": "true",
66+
"w": "majority",
67+
"tls": "false",
68+
},
69+
},
70+
"encrypted": {
71+
"ENGINE": "django_mongodb_backend",
72+
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
73+
"NAME": "encrypted",
74+
"USER": "my_user",
75+
"PASSWORD": "my_password",
76+
"PORT": 27017,
77+
"OPTIONS": {
6278
"auto_encryption_opts": AutoEncryptionOpts(
63-
key_vault_namespace="keyvault.keyvault",
79+
key_vault_namespace="encrypted.keyvault",
6480
kms_providers={"local": {"key": os.urandom(96)}},
6581
)
6682
},
67-
db_name="encrypted",
68-
),
83+
},
6984
}
7085
7186
Configuring the ``DATABASE_ROUTERS`` setting
@@ -88,10 +103,15 @@ configure a custom router for Queryable Encryption:
88103
Encryption.
89104
"""
90105
106+
def db_for_read(self, model, **hints):
107+
if model._meta.app_label == "myapp":
108+
return "encrypted"
109+
return None
110+
111+
db_for_write = db_for_read
112+
91113
def allow_migrate(self, db, app_label, model_name=None, **hints):
92-
# The patientdata app's models are only created in the encrypted
93-
# database.
94-
if app_label == "patientdata":
114+
if app_label == "myapp":
95115
return db == "encrypted"
96116
# Don't create other app's models in the encrypted database.
97117
if db == "encrypted":
@@ -132,15 +152,19 @@ Example of KMS configuration with AWS KMS:
132152

133153
.. code-block:: python
134154
135-
from django_mongodb_backend import parse_uri
136155
from pymongo.encryption_options import AutoEncryptionOpts
137156
138157
DATABASES = {
139-
"encrypted": parse_uri(
140-
DATABASE_URL,
141-
options={
158+
"encrypted": {
159+
"ENGINE": "django_mongodb_backend",
160+
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
161+
"NAME": "encrypted",
162+
"USER": "my_user",
163+
"PASSWORD": "my_password",
164+
"PORT": 27017,
165+
"OPTIONS": {
142166
"auto_encryption_opts": AutoEncryptionOpts(
143-
key_vault_namespace="keyvault.keyvault",
167+
key_vault_namespace="encrypted.keyvault",
144168
kms_providers={
145169
"aws": {
146170
"accessKeyId": "your-access-key-id",
@@ -149,14 +173,12 @@ Example of KMS configuration with AWS KMS:
149173
},
150174
)
151175
},
152-
db_name="encrypted",
153-
),
154-
}
155-
156-
DATABASES["encrypted"]["KMS_CREDENTIALS"] = {
157-
"aws": {
158-
"key": os.getenv("AWS_KEY_ARN", ""),
159-
"region": os.getenv("AWS_KEY_REGION", ""),
176+
"KMS_CREDENTIALS": {
177+
"aws": {
178+
"key": os.getenv("AWS_KEY_ARN", ""),
179+
"region": os.getenv("AWS_KEY_REGION", ""),
180+
},
181+
},
160182
},
161183
}
162184
@@ -208,6 +230,57 @@ If you do not want to use the data keys created by Django MongoDB Backend (when
208230
In this scenario, Django MongoDB Backend will use the newly created data keys
209231
to create collections for models with encrypted fields.
210232

233+
Here is an example of how to configure the
234+
``encrypted_fields_map`` in your Django settings:
235+
236+
.. code-block:: python
237+
238+
from pymongo.encryption_options import AutoEncryptionOpts
239+
from bson import json_util
240+
241+
DATABASES = {
242+
"encrypted": {
243+
"ENGINE": "django_mongodb_backend",
244+
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
245+
"NAME": "encrypted",
246+
"USER": "my_user",
247+
"PASSWORD": "my_password",
248+
"PORT": 27017,
249+
"OPTIONS": {
250+
"auto_encryption_opts": AutoEncryptionOpts(
251+
key_vault_namespace="encrypted.keyvault",
252+
kms_providers={
253+
"aws": {
254+
"accessKeyId": "your-access-key-id",
255+
"secretAccessKey": "your-secret-access-key",
256+
}
257+
},
258+
encrypted_fields_map=json_util.loads(
259+
"""{
260+
"encrypt_patient": {
261+
"fields": [
262+
{
263+
"bsonType": "string",
264+
"path": "patient_record.ssn",
265+
"keyId": {
266+
"$binary": {
267+
"base64": "2MA29LaARIOqymYHGmi2mQ==",
268+
"subType": "04"
269+
}
270+
},
271+
"queries": {
272+
"queryType": "equality"
273+
}
274+
},
275+
]
276+
}
277+
}"""
278+
),
279+
)
280+
},
281+
},
282+
}
283+
211284
Configuring the Automatic Encryption Shared Library
212285
===================================================
213286

@@ -222,25 +295,62 @@ recommended for use with Queryable Encryption.
222295
You can :ref:`download the shared library
223296
<manual:qe-csfle-shared-library-download>` from the
224297
:ref:`manual:enterprise-official-packages` and configure it in your Django
225-
settings as follows:
298+
settings using the ``crypt_shared_lib_path`` option in
299+
:class:`pymongo.encryption_options.AutoEncryptionOpts`. The following example
300+
shows how to configure the shared library in your Django settings:
226301

227302
.. code-block:: python
228303
229-
from django_mongodb_backend import parse_uri
230304
from pymongo.encryption_options import AutoEncryptionOpts
231305
232306
DATABASES = {
233-
"encrypted": parse_uri(
234-
DATABASE_URL,
235-
options={
307+
"encrypted": {
308+
"ENGINE": "django_mongodb_backend",
309+
"HOST": "mongodb+srv://cluster0.example.mongodb.net",
310+
"NAME": "encrypted",
311+
"USER": "my_user",
312+
"PASSWORD": "my_password",
313+
"PORT": 27017,
314+
"OPTIONS": {
236315
"auto_encryption_opts": AutoEncryptionOpts(
237-
key_vault_namespace="keyvault.keyvault",
238-
kms_providers={"local": {"key": os.urandom(96)}},
316+
key_vault_namespace="encrypted.keyvault",
317+
kms_providers={
318+
"aws": {
319+
"accessKeyId": "your-access-key-id",
320+
"secretAccessKey": "your-secret-access-key",
321+
}
322+
},
323+
encrypted_fields_map=json_util.loads(
324+
"""{
325+
"encrypt_patient": {
326+
"fields": [
327+
{
328+
"bsonType": "string",
329+
"path": "patient_record.ssn",
330+
"keyId": {
331+
"$binary": {
332+
"base64": "2MA29LaARIOqymYHGmi2mQ==",
333+
"subType": "04"
334+
}
335+
},
336+
"queries": {
337+
"queryType": "equality"
338+
}
339+
},
340+
]
341+
}
342+
}"""
343+
),
239344
crypt_shared_lib_path="/path/to/mongo_crypt_shared_v1.dylib",
240345
)
241346
},
242-
db_name="encrypted",
243-
),
347+
"KMS_CREDENTIALS": {
348+
"aws": {
349+
"key": os.getenv("AWS_KEY_ARN", ""),
350+
"region": os.getenv("AWS_KEY_REGION", ""),
351+
},
352+
},
353+
},
244354
}
245355
246356
You are now ready to :doc:`start developing applications

docs/ref/django-admin.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Available commands
1717
``showencryptedfieldsmap``
1818
--------------------------
1919

20-
.. versionadded:: 5.2.2
20+
.. versionadded:: 5.2.3
2121

2222
.. django-admin:: showencryptedfieldsmap
2323

docs/ref/models/encrypted-fields.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Django MongoDB Backend supports :doc:`manual:core/queryable-encryption`.
99
See :doc:`/howto/queryable-encryption` for more information on how to use
1010
Queryable Encryption with Django MongoDB Backend.
1111

12-
See the :doc:`Queryable Encryption topic </topics/queryable-encryption>` for
12+
See the :doc:`/topics/queryable-encryption` topic guide for
1313
more information on developing applications with Queryable Encryption.
1414

1515
The following fields are supported by Django MongoDB Backend for use with

docs/topics/queryable-encryption.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ For example, to find a patient by their SSN, you can do the following::
106106
'Bob'
107107

108108

109-
QuerySet Limitations
109+
QuerySet limitations
110110
~~~~~~~~~~~~~~~~~~~~
111111

112112
When using Django QuerySets with MongoDB Queryable Encryption, it’s important to
@@ -128,8 +128,6 @@ be done client-side after decryption. Key limitations include:
128128
- **No joins on encrypted fields** – Filtering across relationships using
129129
encrypted foreign keys is unsupported because matching must happen
130130
client-side.
131-
- **Admin/debug limitations** – You’ll need to integrate client-side decryption
132-
for Django admin or tools, otherwise you’ll see ciphertext.
133131

134132
In short, when working with Queryable Encryption, design your queries to use
135133
exact matches only on encrypted fields, and plan to handle any sorting or

tests/backend_/test_features.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,24 @@ def non_enterprise_response(command):
6969
raise Exception("Unexpected command")
7070

7171
def test_supported_on_atlas(self):
72-
"""Supported on MongoDB 7.0+ Atlas replica set or sharded cluster."""
72+
"""Supported on MongoDB 8.0+ Atlas replica set or sharded cluster."""
7373
with (
7474
patch(
7575
"pymongo.synchronous.database.Database.command", wraps=self.non_enterprise_response
7676
),
7777
patch("django.db.connection.features.supports_atlas_search", True),
7878
patch("django.db.connection.features._supports_transactions", True),
79-
patch("django.db.connection.features.is_mongodb_7_0", True),
79+
patch("django.db.connection.features.is_mongodb_8_0", True),
8080
):
8181
self.assertIs(connection.features.supports_queryable_encryption, True)
8282

8383
def test_supported_on_enterprise(self):
84-
"""Supported on MongoDB 7.0+ Enterprise replica set or sharded cluster."""
84+
"""Supported on MongoDB 8.0+ Enterprise replica set or sharded cluster."""
8585
with (
8686
patch("pymongo.synchronous.database.Database.command", wraps=self.enterprise_response),
8787
patch("django.db.connection.features.supports_atlas_search", False),
8888
patch("django.db.connection.features._supports_transactions", True),
89-
patch("django.db.connection.features.is_mongodb_7_0", True),
89+
patch("django.db.connection.features.is_mongodb_8_0", True),
9090
):
9191
self.assertIs(connection.features.supports_queryable_encryption, True)
9292

@@ -98,7 +98,7 @@ def test_atlas_or_enterprise_required(self):
9898
),
9999
patch("django.db.connection.features.supports_atlas_search", False),
100100
patch("django.db.connection.features._supports_transactions", True),
101-
patch("django.db.connection.features.is_mongodb_7_0", True),
101+
patch("django.db.connection.features.is_mongodb_8_0", True),
102102
):
103103
self.assertIs(connection.features.supports_queryable_encryption, False)
104104

@@ -111,16 +111,16 @@ def test_transactions_required(self):
111111
patch("pymongo.synchronous.database.Database.command", wraps=self.enterprise_response),
112112
patch("django.db.connection.features.supports_atlas_search", False),
113113
patch("django.db.connection.features._supports_transactions", False),
114-
patch("django.db.connection.features.is_mongodb_7_0", True),
114+
patch("django.db.connection.features.is_mongodb_8_0", True),
115115
):
116116
self.assertIs(connection.features.supports_queryable_encryption, False)
117117

118-
def test_mongodb_7_0_required(self):
119-
"""Not supported on MongoDB < 7.0"""
118+
def test_mongodb_8_0_required(self):
119+
"""Not supported on MongoDB < 8.0"""
120120
with (
121121
patch("pymongo.synchronous.database.Database.command", wraps=self.enterprise_response),
122122
patch("django.db.connection.features.supports_atlas_search", False),
123123
patch("django.db.connection.features._supports_transactions", True),
124-
patch("django.db.connection.features.is_mongodb_7_0", False),
124+
patch("django.db.connection.features.is_mongodb_8_0", False),
125125
):
126126
self.assertIs(connection.features.supports_queryable_encryption, False)

0 commit comments

Comments
 (0)