Skip to content

Commit 52cd426

Browse files
committed
CDRIVER-4379 add example use of Queryable Encryption (#1038)
1 parent b11dbcb commit 52cd426

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

src/libmongoc/tests/test-mongoc-client-side-encryption.c

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4561,6 +4561,195 @@ test_decryption_events_decrypt_success (void *unused)
45614561
decryption_events_fixture_destroy (def);
45624562
}
45634563

4564+
/* test_qe_docs_example tests the documentation example requested in
4565+
* CDRIVER-4379. */
4566+
static void
4567+
test_qe_docs_example (void *unused)
4568+
{
4569+
bson_error_t error;
4570+
mongoc_client_t *const client = test_framework_new_default_client ();
4571+
bson_t *const kmsProviders =
4572+
_make_kms_providers (false /* with aws */, true /* with local */);
4573+
bson_value_t key1ID;
4574+
bson_value_t key2ID;
4575+
bson_t *encryptedFieldsMap;
4576+
mongoc_client_t *encryptedClient;
4577+
mongoc_collection_t *encryptedColl;
4578+
4579+
/* Drop data from prior test runs. */
4580+
{
4581+
mongoc_database_t *db;
4582+
mongoc_collection_t *coll;
4583+
4584+
coll = mongoc_client_get_collection (client, "keyvault", "datakeys");
4585+
if (!mongoc_collection_drop (coll, &error)) {
4586+
bool ignored_error = NULL != strstr (error.message, "ns not found");
4587+
ASSERT_OR_PRINT (ignored_error, error);
4588+
}
4589+
mongoc_collection_destroy (coll);
4590+
4591+
db = mongoc_client_get_database (client, "docsExamples");
4592+
ASSERT_OR_PRINT (mongoc_database_drop (db, &error), error);
4593+
mongoc_database_destroy (db);
4594+
}
4595+
4596+
/* Create two data keys. */
4597+
{
4598+
mongoc_client_encryption_opts_t *ceOpts;
4599+
mongoc_client_encryption_t *ce;
4600+
mongoc_client_encryption_datakey_opts_t *dkOpts;
4601+
4602+
ceOpts = mongoc_client_encryption_opts_new ();
4603+
mongoc_client_encryption_opts_set_kms_providers (ceOpts, kmsProviders);
4604+
mongoc_client_encryption_opts_set_keyvault_namespace (
4605+
ceOpts, "keyvault", "datakeys");
4606+
mongoc_client_encryption_opts_set_keyvault_client (ceOpts, client);
4607+
ce = mongoc_client_encryption_new (ceOpts, &error);
4608+
ASSERT_OR_PRINT (ce, error);
4609+
4610+
dkOpts = mongoc_client_encryption_datakey_opts_new ();
4611+
ASSERT_OR_PRINT (mongoc_client_encryption_create_key (
4612+
ce, "local", dkOpts, &key1ID, &error),
4613+
error);
4614+
ASSERT_OR_PRINT (mongoc_client_encryption_create_key (
4615+
ce, "local", dkOpts, &key2ID, &error),
4616+
error);
4617+
4618+
mongoc_client_encryption_datakey_opts_destroy (dkOpts);
4619+
mongoc_client_encryption_destroy (ce);
4620+
mongoc_client_encryption_opts_destroy (ceOpts);
4621+
}
4622+
4623+
/* Create an encryptedFieldsMap. */
4624+
/* clang-format off */
4625+
encryptedFieldsMap = BCON_NEW (
4626+
"docsExamples.encrypted", "{",
4627+
"fields", "[",
4628+
"{",
4629+
"path", "encryptedIndexed",
4630+
"bsonType", "string",
4631+
"keyId", BCON_BIN (key1ID.value.v_binary.subtype,
4632+
key1ID.value.v_binary.data,
4633+
key1ID.value.v_binary.data_len),
4634+
"queries", "[", "{", "queryType", "equality", "}", "]",
4635+
"}",
4636+
"{",
4637+
"path", "encryptedUnindexed",
4638+
"bsonType", "string",
4639+
"keyId", BCON_BIN (key2ID.value.v_binary.subtype,
4640+
key2ID.value.v_binary.data,
4641+
key2ID.value.v_binary.data_len),
4642+
"}",
4643+
"]",
4644+
"}"
4645+
);
4646+
/* clang-format on */
4647+
4648+
/* Create an Queryable Encryption collection. */
4649+
{
4650+
mongoc_auto_encryption_opts_t *aeOpts;
4651+
mongoc_database_t *db;
4652+
4653+
encryptedClient = test_framework_new_default_client ();
4654+
aeOpts = mongoc_auto_encryption_opts_new ();
4655+
mongoc_auto_encryption_opts_set_kms_providers (aeOpts, kmsProviders);
4656+
mongoc_auto_encryption_opts_set_keyvault_namespace (
4657+
aeOpts, "keyvault", "datakeys");
4658+
mongoc_auto_encryption_opts_set_encrypted_fields_map (aeOpts,
4659+
encryptedFieldsMap);
4660+
ASSERT_OR_PRINT (
4661+
mongoc_client_enable_auto_encryption (encryptedClient, aeOpts, &error),
4662+
error);
4663+
/* Create the Queryable Encryption collection docsExample.encrypted. */
4664+
db = mongoc_client_get_database (encryptedClient, "docsExamples");
4665+
/* Because docsExample.encrypted is in encryptedFieldsMap, it is created
4666+
* with Queryable Encryption support. */
4667+
encryptedColl = mongoc_database_create_collection (
4668+
db, "encrypted", NULL /* opts */, &error);
4669+
ASSERT_OR_PRINT (encryptedColl, error);
4670+
4671+
mongoc_database_destroy (db);
4672+
mongoc_auto_encryption_opts_destroy (aeOpts);
4673+
}
4674+
4675+
/* Auto encrypt an insert and find. */
4676+
{
4677+
/* Encrypt an insert. */
4678+
bson_t *to_insert;
4679+
bson_t *filter;
4680+
const bson_t *got;
4681+
mongoc_cursor_t *cursor;
4682+
bool found;
4683+
bson_iter_t iter;
4684+
4685+
to_insert = BCON_NEW ("_id",
4686+
BCON_INT32 (1),
4687+
"encryptedIndexed",
4688+
"indexedValue",
4689+
"encryptedUnindexed",
4690+
"unindexedValue");
4691+
4692+
ASSERT_OR_PRINT (mongoc_collection_insert_one (encryptedColl,
4693+
to_insert,
4694+
NULL /* opts */,
4695+
NULL /* reply */,
4696+
&error),
4697+
error);
4698+
4699+
filter = BCON_NEW ("encryptedIndexed", "indexedValue");
4700+
cursor = mongoc_collection_find_with_opts (
4701+
encryptedColl, filter, NULL /* opts */, NULL /* read prefs */);
4702+
found = mongoc_cursor_next (cursor, &got);
4703+
ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error);
4704+
ASSERT (found);
4705+
ASSERT (bson_iter_init_find (&iter, got, "encryptedIndexed"));
4706+
ASSERT (BSON_ITER_HOLDS_UTF8 (&iter));
4707+
ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL /* length */), "indexedValue");
4708+
ASSERT (bson_iter_init_find (&iter, got, "encryptedUnindexed"));
4709+
ASSERT (BSON_ITER_HOLDS_UTF8 (&iter));
4710+
ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL /* length */),
4711+
"unindexedValue");
4712+
4713+
mongoc_cursor_destroy (cursor);
4714+
bson_destroy (filter);
4715+
bson_destroy (to_insert);
4716+
}
4717+
4718+
/* Find documents without decryption. */
4719+
{
4720+
mongoc_collection_t *unencryptedColl;
4721+
bson_t *filter;
4722+
const bson_t *got;
4723+
mongoc_cursor_t *cursor;
4724+
bool found;
4725+
bson_iter_t iter;
4726+
4727+
unencryptedColl =
4728+
mongoc_client_get_collection (client, "docsExamples", "encrypted");
4729+
filter = BCON_NEW ("_id", BCON_INT32 (1));
4730+
cursor = mongoc_collection_find_with_opts (
4731+
unencryptedColl, filter, NULL /* opts */, NULL /* read prefs */);
4732+
found = mongoc_cursor_next (cursor, &got);
4733+
ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error);
4734+
ASSERT (found);
4735+
ASSERT (bson_iter_init_find (&iter, got, "encryptedIndexed"));
4736+
ASSERT (BSON_ITER_HOLDS_BINARY (&iter));
4737+
ASSERT (bson_iter_init_find (&iter, got, "encryptedUnindexed"));
4738+
ASSERT (BSON_ITER_HOLDS_BINARY (&iter));
4739+
4740+
mongoc_cursor_destroy (cursor);
4741+
bson_destroy (filter);
4742+
mongoc_collection_destroy (unencryptedColl);
4743+
}
4744+
4745+
mongoc_collection_destroy (encryptedColl);
4746+
mongoc_client_destroy (encryptedClient);
4747+
bson_destroy (encryptedFieldsMap);
4748+
bson_value_destroy (&key2ID);
4749+
bson_value_destroy (&key1ID);
4750+
bson_destroy (kmsProviders);
4751+
mongoc_client_destroy (client);
4752+
}
45644753

45654754
void
45664755
test_client_side_encryption_install (TestSuite *suite)
@@ -4802,4 +4991,13 @@ test_client_side_encryption_install (TestSuite *suite)
48024991
NULL /* ctx */,
48034992
test_framework_skip_if_no_client_side_encryption,
48044993
test_framework_skip_if_max_wire_version_less_than_8);
4994+
4995+
TestSuite_AddFull (suite,
4996+
"/client_side_encryption/qe_docs_example",
4997+
test_qe_docs_example,
4998+
NULL /* dtor */,
4999+
NULL /* ctx */,
5000+
test_framework_skip_if_no_client_side_encryption,
5001+
test_framework_skip_if_max_wire_version_less_than_17,
5002+
test_framework_skip_if_single);
48055003
}

0 commit comments

Comments
 (0)