@@ -4561,6 +4561,195 @@ test_decryption_events_decrypt_success (void *unused)
4561
4561
decryption_events_fixture_destroy (def );
4562
4562
}
4563
4563
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
+ }
4564
4753
4565
4754
void
4566
4755
test_client_side_encryption_install (TestSuite * suite )
@@ -4802,4 +4991,13 @@ test_client_side_encryption_install (TestSuite *suite)
4802
4991
NULL /* ctx */ ,
4803
4992
test_framework_skip_if_no_client_side_encryption ,
4804
4993
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 );
4805
5003
}
0 commit comments