Skip to content

Commit e08284b

Browse files
authored
PYTHON-5456 Support text indexes with auto encryption (#2500)
1 parent 5e96353 commit e08284b

File tree

7 files changed

+1727
-4
lines changed

7 files changed

+1727
-4
lines changed

test/asynchronous/unified_format.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ async def is_run_on_requirement_satisfied(requirement):
159159
if req_csfle is True:
160160
min_version_satisfied = Version.from_string("4.2") <= server_version
161161
csfle_satisfied = _HAVE_PYMONGOCRYPT and min_version_satisfied
162+
elif isinstance(req_csfle, dict) and "minLibmongocryptVersion" in req_csfle:
163+
csfle_satisfied = False
164+
req_version = req_csfle["minLibmongocryptVersion"]
165+
if _HAVE_PYMONGOCRYPT:
166+
from pymongocrypt import libmongocrypt_version
167+
168+
if Version.from_string(libmongocrypt_version()) >= Version.from_string(req_version):
169+
csfle_satisfied = True
162170

163171
return (
164172
topology_satisfied
@@ -450,7 +458,7 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
450458
a class attribute ``TEST_SPEC``.
451459
"""
452460

453-
SCHEMA_VERSION = Version.from_string("1.23")
461+
SCHEMA_VERSION = Version.from_string("1.25")
454462
RUN_ON_LOAD_BALANCER = True
455463
TEST_SPEC: Any
456464
TEST_PATH = "" # This gets filled in by generate_test_classes
@@ -1545,7 +1553,7 @@ class SpecTestBase(with_metaclass(UnifiedSpecTestMeta)): # type: ignore
15451553

15461554
# Add "encryption" marker if the "csfle" runOnRequirement is set.
15471555
for req in test_spec.get("runOnRequirements", []):
1548-
if req.get("csfle", False):
1556+
if "csfle" in req:
15491557
base = pytest.mark.encryption(base)
15501558

15511559
return base
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
{
2+
"description": "QE-Text-cleanupStructuredEncryptionData",
3+
"schemaVersion": "1.25",
4+
"runOnRequirements": [
5+
{
6+
"minServerVersion": "8.2.0",
7+
"topologies": [
8+
"replicaset",
9+
"sharded",
10+
"load-balanced"
11+
],
12+
"csfle": {
13+
"minLibmongocryptVersion": "1.15.0"
14+
}
15+
}
16+
],
17+
"createEntities": [
18+
{
19+
"client": {
20+
"id": "client",
21+
"autoEncryptOpts": {
22+
"keyVaultNamespace": "keyvault.datakeys",
23+
"kmsProviders": {
24+
"local": {
25+
"key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk"
26+
}
27+
}
28+
},
29+
"observeEvents": [
30+
"commandStartedEvent"
31+
]
32+
}
33+
},
34+
{
35+
"database": {
36+
"id": "db",
37+
"client": "client",
38+
"databaseName": "db"
39+
}
40+
},
41+
{
42+
"collection": {
43+
"id": "coll",
44+
"database": "db",
45+
"collectionName": "coll"
46+
}
47+
}
48+
],
49+
"initialData": [
50+
{
51+
"databaseName": "keyvault",
52+
"collectionName": "datakeys",
53+
"documents": [
54+
{
55+
"_id": {
56+
"$binary": {
57+
"base64": "q83vqxI0mHYSNBI0VniQEg==",
58+
"subType": "04"
59+
}
60+
},
61+
"keyMaterial": {
62+
"$binary": {
63+
"base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==",
64+
"subType": "00"
65+
}
66+
},
67+
"creationDate": {
68+
"$date": {
69+
"$numberLong": "1648914851981"
70+
}
71+
},
72+
"updateDate": {
73+
"$date": {
74+
"$numberLong": "1648914851981"
75+
}
76+
},
77+
"status": {
78+
"$numberInt": "0"
79+
},
80+
"masterKey": {
81+
"provider": "local"
82+
}
83+
}
84+
]
85+
},
86+
{
87+
"databaseName": "db",
88+
"collectionName": "coll",
89+
"documents": [],
90+
"createOptions": {
91+
"encryptedFields": {
92+
"fields": [
93+
{
94+
"keyId": {
95+
"$binary": {
96+
"base64": "q83vqxI0mHYSNBI0VniQEg==",
97+
"subType": "04"
98+
}
99+
},
100+
"path": "encryptedText",
101+
"bsonType": "string",
102+
"queries": [
103+
{
104+
"queryType": "suffixPreview",
105+
"contention": {
106+
"$numberLong": "0"
107+
},
108+
"strMinQueryLength": {
109+
"$numberLong": "3"
110+
},
111+
"strMaxQueryLength": {
112+
"$numberLong": "30"
113+
},
114+
"caseSensitive": true,
115+
"diacriticSensitive": true
116+
}
117+
]
118+
}
119+
]
120+
}
121+
}
122+
}
123+
],
124+
"tests": [
125+
{
126+
"description": "QE Text cleanupStructuredEncryptionData works",
127+
"operations": [
128+
{
129+
"name": "runCommand",
130+
"object": "db",
131+
"arguments": {
132+
"command": {
133+
"cleanupStructuredEncryptionData": "coll"
134+
},
135+
"commandName": "cleanupStructuredEncryptionData"
136+
},
137+
"expectResult": {
138+
"ok": 1
139+
}
140+
}
141+
],
142+
"expectEvents": [
143+
{
144+
"client": "client",
145+
"events": [
146+
{
147+
"commandStartedEvent": {
148+
"command": {
149+
"listCollections": 1,
150+
"filter": {
151+
"name": "coll"
152+
}
153+
},
154+
"commandName": "listCollections"
155+
}
156+
},
157+
{
158+
"commandStartedEvent": {
159+
"command": {
160+
"find": "datakeys",
161+
"filter": {
162+
"$or": [
163+
{
164+
"_id": {
165+
"$in": [
166+
{
167+
"$binary": {
168+
"base64": "q83vqxI0mHYSNBI0VniQEg==",
169+
"subType": "04"
170+
}
171+
}
172+
]
173+
}
174+
},
175+
{
176+
"keyAltNames": {
177+
"$in": []
178+
}
179+
}
180+
]
181+
},
182+
"$db": "keyvault",
183+
"readConcern": {
184+
"level": "majority"
185+
}
186+
},
187+
"commandName": "find"
188+
}
189+
},
190+
{
191+
"commandStartedEvent": {
192+
"command": {
193+
"cleanupStructuredEncryptionData": "coll",
194+
"cleanupTokens": {
195+
"encryptedText": {
196+
"ecoc": {
197+
"$binary": {
198+
"base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=",
199+
"subType": "00"
200+
}
201+
},
202+
"anchorPaddingToken": {
203+
"$binary": {
204+
"base64": "YAiF7Iwhqq1UyfxPvm70xfQJtrIRPrjfD2yRLG1+saQ=",
205+
"subType": "00"
206+
}
207+
}
208+
}
209+
}
210+
},
211+
"commandName": "cleanupStructuredEncryptionData"
212+
}
213+
}
214+
]
215+
}
216+
]
217+
}
218+
]
219+
}

0 commit comments

Comments
 (0)