@@ -87,6 +87,76 @@ public ClientEncryptionProseTests(ITestOutputHelper testOutputHelper)
8787 // public methods
8888 [ Theory ]
8989 [ ParameterAttributeData ]
90+ public void AutomaticDataEncryptionKeysTest (
91+ [ Range ( 1 , 4 ) ] int testCase ,
92+ [ Values ( false , true ) ] bool async )
93+ {
94+ RequireServer . Check ( ) . Supports ( Feature . Csfle2 ) . ClusterTypes ( ClusterType . ReplicaSet , ClusterType . Sharded , ClusterType . LoadBalanced ) ;
95+
96+ var kmsProvider = "local" ;
97+ using ( var client = ConfigureClient ( ) )
98+ using ( var clientEncryption = ConfigureClientEncryption ( client , kmsProviderFilter : kmsProvider ) )
99+ {
100+ var encryptedFields = BsonDocument . Parse ( $@ "
101+ {{
102+ fields:
103+ [
104+ {{
105+ path: ""ssn"",
106+ bsonType: ""string"",
107+ keyId: null
108+ }}
109+ ]
110+ }}" ) ;
111+
112+ DropCollection ( __collCollectionNamespace , encryptedFields ) ;
113+
114+ RunTestCase ( testCase ) ;
115+
116+ void RunTestCase ( int testCase )
117+ {
118+ switch ( testCase )
119+ {
120+ case 1 : // Case 1: Simple Creation and Validation
121+ {
122+ var collection = CreateEncryptedCollection ( client , clientEncryption , __collCollectionNamespace , encryptedFields , kmsProvider , async ) ;
123+
124+ var exception = Record . Exception ( ( ) => Insert ( collection , async , new BsonDocument ( "ssn" , "123-45-6789" ) ) ) ;
125+ exception . Should ( ) . BeOfType < MongoBulkWriteException < BsonDocument > > ( ) . Which . Message . Should ( ) . Contain ( "Document failed validation" ) ;
126+ }
127+ break ;
128+ case 2 : // Case 2: Missing ``encryptedFields``
129+ {
130+ var exception = Record . Exception ( ( ) => CreateEncryptedCollection ( client , clientEncryption , __collCollectionNamespace , encryptedFields : null , kmsProvider , async) ) ;
131+
132+ exception . Should ( ) . BeOfType < InvalidOperationException > ( ) . Which . Message . Should ( ) . Contain ( "There are no encrypted fields defined for the collection." ) ;
133+ }
134+ break ;
135+ case 3 : // Case 3: Invalid ``keyId``
136+ {
137+ var effectiveEncryptedFields = encryptedFields . DeepClone ( ) ;
138+ effectiveEncryptedFields [ "fields" ] . AsBsonArray [ 0 ] . AsBsonDocument [ "keyId" ] = false ;
139+ var exception = Record . Exception ( ( ) => CreateEncryptedCollection ( client , clientEncryption , __collCollectionNamespace , effectiveEncryptedFields . AsBsonDocument , kmsProvider , async) ) ;
140+ exception . Should ( ) . BeOfType < MongoCommandException > ( ) . Which . Message . Should ( ) . Contain ( "BSON field 'create.encryptedFields.fields.keyId' is the wrong type 'bool', expected type 'binData'" ) ;
141+ }
142+ break ;
143+ case 4 : // Case 4: Insert encrypted value
144+ {
145+ var createCollectionOptions = new CreateCollectionOptions { EncryptedFields = encryptedFields } ;
146+ var collection = CreateEncryptedCollection ( client , clientEncryption , __collCollectionNamespace , createCollectionOptions , kmsProvider , async ) ;
147+ var dataKey = createCollectionOptions . EncryptedFields [ "fields" ] . AsBsonArray [ 0 ] . AsBsonDocument [ "keyId" ] . AsGuid ; // get generated datakey
148+ var encryptedValue = ExplicitEncrypt ( clientEncryption , new EncryptOptions ( algorithm : EncryptionAlgorithm . Unindexed , keyId : dataKey ) , "123-45-6789" , async ) ; // use explicit encryption to encrypt data before inserting
149+ Insert ( collection , async , new BsonDocument ( "ssn", encryptedValue) ) ;
150+ }
151+ break ;
152+ default : throw new Exception( $"Unexpected test case { testCase} . ") ;
153+ }
154+ }
155+ }
156+ }
157+
158+ [ SkippableTheory]
159+ [ ParameterAttributeData]
90160 public void BsonSizeLimitAndBatchSizeSplittingTest(
91161 [ Values ( false , true ) ] bool async )
92162 {
@@ -1123,6 +1193,7 @@ void RunTestCase(IMongoCollection<BsonDocument> decryptionEventsCollection, int
11231193 reply [ "cursor" ] [ "firstBatch" ] . AsBsonArray . Single ( ) [ "encrypted" ] . AsBsonBinaryData . SubType . Should ( ) . Be ( BsonBinarySubType . Encrypted ) ;
11241194 }
11251195 break ;
1196+ default : throw new Exception ( $ "Unexpected test case { testCase } .") ;
11261197 }
11271198 }
11281199
@@ -1875,6 +1946,8 @@ HttpClientWrapperWithModifiedRequest CreateHttpClientWrapperWithModifiedRequest(
18751946 }
18761947 }
18771948
1949+ [ SkippableTheory ]
1950+ [ ParameterAttributeData ]
18781951 public void RewrapTest (
18791952 [ Values ( "local" , "aws" , "azure" , "gcp" , "kmip" ) ] string srcProvider ,
18801953 [ Values ( "local" , "aws" , "azure" , "gcp" , "kmip" ) ] string dstProvider ,
@@ -1929,7 +2002,7 @@ public void ViewAreProhibitedTest([Values(false, true)] bool async)
19292002 using ( var client = ConfigureClient ( false ) )
19302003 using ( var clientEncrypted = ConfigureClientEncrypted ( kmsProviderFilter : "local" ) )
19312004 {
1932- DropView ( viewName ) ;
2005+ DropCollection ( viewName ) ;
19332006 client
19342007 . GetDatabase ( viewName . DatabaseNamespace . DatabaseName )
19352008 . CreateView (
@@ -2257,6 +2330,28 @@ private void CreateCollection(IMongoClient client, CollectionNamespace collectio
22572330 } ) ;
22582331 }
22592332
2333+ private IMongoCollection < BsonDocument > CreateEncryptedCollection ( IMongoClient client , ClientEncryption clientEncryption , CollectionNamespace collectionNamespace , BsonDocument encryptedFields , string kmsProvider , bool async )
2334+ {
2335+ var createCollectionOptions = new CreateCollectionOptions { EncryptedFields = encryptedFields } ;
2336+ return CreateEncryptedCollection ( client , clientEncryption , collectionNamespace , createCollectionOptions , kmsProvider , async ) ;
2337+ }
2338+
2339+ private IMongoCollection < BsonDocument > CreateEncryptedCollection ( IMongoClient client , ClientEncryption clientEncryption , CollectionNamespace collectionNamespace , CreateCollectionOptions createCollectionOptions , string kmsProvider , bool async )
2340+ {
2341+ var datakeyOptions = CreateDataKeyOptions ( kmsProvider ) ;
2342+
2343+ if ( async)
2344+ {
2345+ clientEncryption . CreateEncryptedCollectionAsync < BsonDocument > ( collectionNamespace , createCollectionOptions , kmsProvider , datakeyOptions , cancellationToken : default ) . GetAwaiter ( ) . GetResult ( ) ;
2346+ }
2347+ else
2348+ {
2349+ clientEncryption . CreateEncryptedCollection < BsonDocument > ( collectionNamespace , createCollectionOptions , kmsProvider , datakeyOptions , cancellationToken : default ) ;
2350+ }
2351+
2352+ return client . GetDatabase ( collectionNamespace . DatabaseNamespace . DatabaseName ) . GetCollection < BsonDocument > ( collectionNamespace . CollectionName ) ;
2353+ }
2354+
22602355 private Guid CreateDataKey (
22612356 ClientEncryption clientEncryption ,
22622357 string kmsProvider ,
@@ -2407,9 +2502,9 @@ private MongoClientSettings CreateMongoClientSettings(
24072502 return mongoClientSettings ;
24082503 }
24092504
2410- private void DropView ( CollectionNamespace viewNamespace )
2505+ private void DropCollection ( CollectionNamespace collectionNamespace , BsonDocument encryptedFields = null )
24112506 {
2412- var operation = new DropCollectionOperation ( viewNamespace , CoreTestConfiguration . MessageEncoderSettings ) ;
2507+ var operation = DropCollectionOperation . CreateEncryptedDropCollectionOperationIfConfigured ( collectionNamespace , encryptedFields , CoreTestConfiguration . MessageEncoderSettings , configureDropCollectionConfigurator : null ) ;
24132508 using ( var session = CoreTestConfiguration . StartSession ( _cluster ) )
24142509 using ( var binding = new WritableServerBinding ( _cluster , session . Fork ( ) ) )
24152510 using ( var bindingHandle = new ReadWriteBindingHandle ( binding ) )
0 commit comments