@@ -2818,3 +2818,120 @@ async fn bind(addr: &str) -> Result<TcpListener> {
28182818 Ok ( TcpListener :: bind ( addr) . await ?)
28192819 }
28202820}
2821+
2822+ // FLE 2.0 Documentation Example
2823+ #[ cfg_attr( feature = "tokio-runtime" , tokio:: test) ]
2824+ #[ cfg_attr( feature = "async-std-runtime" , async_std:: test) ]
2825+ async fn fle2_example ( ) -> Result < ( ) > {
2826+ if !check_env ( "fle2_example" , false ) {
2827+ return Ok ( ( ) ) ;
2828+ }
2829+ let _guard = LOCK . run_exclusively ( ) . await ;
2830+
2831+ // FLE 2 is not supported on Standalone topology.
2832+ let test_client = Client :: test_builder ( ) . build ( ) . await ;
2833+ if test_client. server_version_lt ( 6 , 0 ) {
2834+ log_uncaptured ( "skipping fle2 example: server below 6.0" ) ;
2835+ return Ok ( ( ) ) ;
2836+ }
2837+ if test_client. is_standalone ( ) {
2838+ log_uncaptured ( "skipping fle2 example: cannot run on standalone" ) ;
2839+ return Ok ( ( ) ) ;
2840+ }
2841+
2842+ // Drop data from prior test runs.
2843+ test_client
2844+ . database ( "keyvault" )
2845+ . collection :: < Document > ( "datakeys" )
2846+ . drop ( None )
2847+ . await ?;
2848+ test_client. database ( "docsExamples" ) . drop ( None ) . await ?;
2849+
2850+ // Create two data keys.
2851+ let ce = ClientEncryption :: new (
2852+ test_client. clone ( ) . into_client ( ) ,
2853+ KV_NAMESPACE . clone ( ) ,
2854+ LOCAL_KMS . clone ( ) ,
2855+ ) ?;
2856+ let key1_id = ce. create_data_key ( MasterKey :: Local ) . run ( ) . await ?;
2857+ let key2_id = ce. create_data_key ( MasterKey :: Local ) . run ( ) . await ?;
2858+
2859+ // Create an encryptedFieldsMap.
2860+ let encrypted_fields_map = [ (
2861+ "docsExamples.encrypted" ,
2862+ doc ! {
2863+ "fields" : [
2864+ {
2865+ "path" : "encryptedIndexed" ,
2866+ "bsonType" : "string" ,
2867+ "keyId" : key1_id,
2868+ "queries" : { "queryType" : "equality" } ,
2869+ } ,
2870+ {
2871+ "path" : "encryptedUnindexed" ,
2872+ "bsonType" : "string" ,
2873+ "keyId" : key2_id,
2874+ } ,
2875+ ]
2876+ } ,
2877+ ) ] ;
2878+
2879+ // Create an FLE 2 collection.
2880+ let encrypted_client = Client :: encrypted_builder (
2881+ CLIENT_OPTIONS . get ( ) . await . clone ( ) ,
2882+ KV_NAMESPACE . clone ( ) ,
2883+ LOCAL_KMS . clone ( ) ,
2884+ ) ?
2885+ . encrypted_fields_map ( encrypted_fields_map)
2886+ . build ( )
2887+ . await ?;
2888+ let db = encrypted_client. database ( "docsExamples" ) ;
2889+ db. create_collection ( "encrypted" , None ) . await ?;
2890+ let encrypted_coll = db. collection :: < Document > ( "encrypted" ) ;
2891+
2892+ // Auto encrypt an insert and find.
2893+
2894+ // Encrypt an insert.
2895+ encrypted_coll
2896+ . insert_one (
2897+ doc ! {
2898+ "_id" : 1 ,
2899+ "encryptedIndexed" : "indexedValue" ,
2900+ "encryptedUnindexed" : "unindexedValue" ,
2901+ } ,
2902+ None ,
2903+ )
2904+ . await ?;
2905+
2906+ // Encrypt a find.
2907+ let found = encrypted_coll
2908+ . find_one (
2909+ doc ! {
2910+ "encryptedIndexed" : "indexedValue" ,
2911+ } ,
2912+ None ,
2913+ )
2914+ . await ?
2915+ . unwrap ( ) ;
2916+ assert_eq ! ( "indexedValue" , found. get_str( "encryptedIndexed" ) ?) ;
2917+ assert_eq ! ( "unindexedValue" , found. get_str( "encryptedUnindexed" ) ?) ;
2918+
2919+ // Find documents without decryption.
2920+ let unencrypted_coll = test_client
2921+ . database ( "docsExamples" )
2922+ . collection :: < Document > ( "encrypted" ) ;
2923+ let found = unencrypted_coll
2924+ . find_one ( doc ! { "_id" : 1 } , None )
2925+ . await ?
2926+ . unwrap ( ) ;
2927+ assert_eq ! (
2928+ Some ( ElementType :: Binary ) ,
2929+ found. get( "encryptedIndexed" ) . map( Bson :: element_type)
2930+ ) ;
2931+ assert_eq ! (
2932+ Some ( ElementType :: Binary ) ,
2933+ found. get( "encryptedUnindexed" ) . map( Bson :: element_type)
2934+ ) ;
2935+
2936+ Ok ( ( ) )
2937+ }
0 commit comments