@@ -87,6 +87,76 @@ public ClientEncryptionProseTests(ITestOutputHelper testOutputHelper)
87
87
// public methods
88
88
[ Theory ]
89
89
[ 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]
90
160
public void BsonSizeLimitAndBatchSizeSplittingTest(
91
161
[ Values ( false , true ) ] bool async )
92
162
{
@@ -1123,6 +1193,7 @@ void RunTestCase(IMongoCollection<BsonDocument> decryptionEventsCollection, int
1123
1193
reply [ "cursor" ] [ "firstBatch" ] . AsBsonArray . Single ( ) [ "encrypted" ] . AsBsonBinaryData . SubType . Should ( ) . Be ( BsonBinarySubType . Encrypted ) ;
1124
1194
}
1125
1195
break ;
1196
+ default : throw new Exception ( $ "Unexpected test case { testCase } .") ;
1126
1197
}
1127
1198
}
1128
1199
@@ -1875,6 +1946,8 @@ HttpClientWrapperWithModifiedRequest CreateHttpClientWrapperWithModifiedRequest(
1875
1946
}
1876
1947
}
1877
1948
1949
+ [ SkippableTheory ]
1950
+ [ ParameterAttributeData ]
1878
1951
public void RewrapTest (
1879
1952
[ Values ( "local" , "aws" , "azure" , "gcp" , "kmip" ) ] string srcProvider ,
1880
1953
[ Values ( "local" , "aws" , "azure" , "gcp" , "kmip" ) ] string dstProvider ,
@@ -1929,7 +2002,7 @@ public void ViewAreProhibitedTest([Values(false, true)] bool async)
1929
2002
using ( var client = ConfigureClient ( false ) )
1930
2003
using ( var clientEncrypted = ConfigureClientEncrypted ( kmsProviderFilter : "local" ) )
1931
2004
{
1932
- DropView ( viewName ) ;
2005
+ DropCollection ( viewName ) ;
1933
2006
client
1934
2007
. GetDatabase ( viewName . DatabaseNamespace . DatabaseName )
1935
2008
. CreateView (
@@ -2257,6 +2330,28 @@ private void CreateCollection(IMongoClient client, CollectionNamespace collectio
2257
2330
} ) ;
2258
2331
}
2259
2332
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
+
2260
2355
private Guid CreateDataKey (
2261
2356
ClientEncryption clientEncryption ,
2262
2357
string kmsProvider ,
@@ -2407,9 +2502,9 @@ private MongoClientSettings CreateMongoClientSettings(
2407
2502
return mongoClientSettings ;
2408
2503
}
2409
2504
2410
- private void DropView ( CollectionNamespace viewNamespace )
2505
+ private void DropCollection ( CollectionNamespace collectionNamespace , BsonDocument encryptedFields = null )
2411
2506
{
2412
- var operation = new DropCollectionOperation ( viewNamespace , CoreTestConfiguration . MessageEncoderSettings ) ;
2507
+ var operation = DropCollectionOperation . CreateEncryptedDropCollectionOperationIfConfigured ( collectionNamespace , encryptedFields , CoreTestConfiguration . MessageEncoderSettings , configureDropCollectionConfigurator : null ) ;
2413
2508
using ( var session = CoreTestConfiguration . StartSession ( _cluster ) )
2414
2509
using ( var binding = new WritableServerBinding ( _cluster , session . Fork ( ) ) )
2415
2510
using ( var bindingHandle = new ReadWriteBindingHandle ( binding ) )
0 commit comments