@@ -2818,3 +2818,120 @@ async fn bind(addr: &str) -> Result<TcpListener> {
2818
2818
Ok ( TcpListener :: bind ( addr) . await ?)
2819
2819
}
2820
2820
}
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