@@ -460,3 +460,128 @@ func TestFLE2CreateCollection(t *testing.T) {
460
460
}
461
461
})
462
462
}
463
+
464
+ func TestFLE2DocsExample (t * testing.T ) {
465
+ // FLE 2 is not supported on Standalone topology.
466
+ mtOpts := mtest .NewOptions ().
467
+ MinServerVersion ("6.0" ).
468
+ Enterprise (true ).
469
+ CreateClient (false ).
470
+ Topologies (mtest .ReplicaSet ,
471
+ mtest .Sharded ,
472
+ mtest .LoadBalanced ,
473
+ mtest .ShardedReplicaSet )
474
+ mt := mtest .New (t , mtOpts )
475
+ defer mt .Close ()
476
+
477
+ mt .Run ("Auto Encryption" , func (mt * mtest.T ) {
478
+ // Drop data from prior test runs.
479
+ {
480
+ err := mt .Client .Database ("keyvault" ).Collection ("datakeys" ).Drop (context .Background ())
481
+ assert .Nil (mt , err , "error in Drop: %v" , err )
482
+ err = mt .Client .Database ("docsExamples" ).Drop (context .Background ())
483
+ assert .Nil (mt , err , "error in Drop: %v" , err )
484
+ }
485
+
486
+ kmsProvidersMap := map [string ]map [string ]interface {}{
487
+ "local" : {"key" : localMasterKey },
488
+ }
489
+
490
+ var key1ID primitive.Binary
491
+ var key2ID primitive.Binary
492
+
493
+ // Create two data keys.
494
+ {
495
+ cOpts := options .Client ().ApplyURI (mtest .ClusterURI ())
496
+ testutil .AddTestServerAPIVersion (cOpts )
497
+ keyVaultClient , err := mongo .Connect (context .Background (), cOpts )
498
+ assert .Nil (mt , err , "error in Connect: %v" , err )
499
+ defer keyVaultClient .Disconnect (context .Background ())
500
+ ceOpts := options .ClientEncryption ().SetKmsProviders (kmsProvidersMap ).SetKeyVaultNamespace ("keyvault.datakeys" )
501
+ ce , err := mongo .NewClientEncryption (keyVaultClient , ceOpts )
502
+ assert .Nil (mt , err , "error in NewClientEncryption: %v" , err )
503
+ defer ce .Close (context .Background ())
504
+ key1ID , err = ce .CreateDataKey (context .Background (), "local" )
505
+ assert .Nil (mt , err , "error in CreateDataKey: %v" , err )
506
+ key2ID , err = ce .CreateDataKey (context .Background (), "local" )
507
+ assert .Nil (mt , err , "error in CreateDataKey: %v" , err )
508
+ }
509
+
510
+ // Create an encryptedFieldsMap.
511
+ encryptedFieldsMap := bson.M {
512
+ "docsExamples.encrypted" : bson.M {
513
+ "fields" : []bson.M {
514
+ {
515
+ "path" : "encryptedIndexed" ,
516
+ "bsonType" : "string" ,
517
+ "keyId" : key1ID ,
518
+ "queries" : []bson.M {
519
+ {
520
+ "queryType" : "equality" ,
521
+ },
522
+ },
523
+ },
524
+ {
525
+ "path" : "encryptedUnindexed" ,
526
+ "bsonType" : "string" ,
527
+ "keyId" : key2ID ,
528
+ },
529
+ },
530
+ },
531
+ }
532
+
533
+ // Create an FLE 2 collection.
534
+ var encryptedColl * mongo.Collection
535
+ {
536
+ cOpts := options .Client ().ApplyURI (mtest .ClusterURI ())
537
+ testutil .AddTestServerAPIVersion (cOpts )
538
+ aeOpts := options .AutoEncryption ().SetKmsProviders (kmsProvidersMap ).SetKeyVaultNamespace ("keyvault.datakeys" ).SetEncryptedFieldsMap (encryptedFieldsMap )
539
+ cOpts .SetAutoEncryptionOptions (aeOpts )
540
+ encryptedClient , err := mongo .Connect (context .Background (), cOpts )
541
+ defer encryptedClient .Disconnect (context .Background ())
542
+ assert .Nil (mt , err , "error in Connect: %v" , err )
543
+ // Create the FLE 2 collection docsExample.encrypted.
544
+ db := encryptedClient .Database ("docsExamples" )
545
+ // Because docsExample.encrypted is in encryptedFieldsMap, it is created with FLE 2 support.
546
+ err = db .CreateCollection (context .Background (), "encrypted" )
547
+ assert .Nil (mt , err , "error in CreateCollection" )
548
+ encryptedColl = db .Collection ("encrypted" )
549
+ }
550
+
551
+ // Auto encrypt an insert and find.
552
+ {
553
+ // Encrypt an insert.
554
+ _ , err := encryptedColl .InsertOne (context .Background (), bson.M {
555
+ "_id" : 1 ,
556
+ "encryptedIndexed" : "indexedValue" ,
557
+ "encryptedUnindexed" : "unindexedValue" ,
558
+ })
559
+ assert .Nil (mt , err , "error in InsertOne" )
560
+
561
+ // Encrypt a find.
562
+ res := encryptedColl .FindOne (context .Background (), bson.M {
563
+ "encryptedIndexed" : "indexedValue" ,
564
+ })
565
+ assert .Nil (mt , res .Err (), "error in FindOne: %v" , res .Err ())
566
+ var resBSON bson.M
567
+ err = res .Decode (& resBSON )
568
+ assert .Nil (mt , err , "error in Decode: %v" , err )
569
+ assert .Equal (mt , resBSON ["encryptedIndexed" ], "indexedValue" , "expected 'indexedValue', got %q" , resBSON ["encryptedIndexed" ])
570
+ assert .Equal (mt , resBSON ["encryptedUnindexed" ], "unindexedValue" , "expected 'unindexedValue', got %q" , resBSON ["encryptedUnindexed" ])
571
+ }
572
+
573
+ // Find documents without decryption.
574
+ {
575
+ unencryptedColl := mt .Client .Database ("docsExamples" ).Collection ("encrypted" )
576
+ res := unencryptedColl .FindOne (context .Background (), bson.M {"_id" : 1 })
577
+ assert .Nil (mt , res .Err (), "error in FindOne: %v" , res .Err ())
578
+ resBSON , err := res .DecodeBytes ()
579
+ assert .Nil (mt , err , "error in DecodeBytes: %v" , err )
580
+
581
+ val := resBSON .Lookup ("encryptedIndexed" )
582
+ assert .Equal (mt , val .Type , bsontype .Binary , "expected encryptedIndexed to be Binary, got %v" , val .Type )
583
+ val = resBSON .Lookup ("encryptedUnindexed" )
584
+ assert .Equal (mt , val .Type , bsontype .Binary , "expected encryptedUnindexed to be Binary, got %v" , val .Type )
585
+ }
586
+ })
587
+ }
0 commit comments