Skip to content

Commit 5fbacbb

Browse files
CSHARP-4164: Provide FLE 2.0 API example for docs team. (#813)
1 parent f640ca5 commit 5fbacbb

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Threading;
19+
using FluentAssertions;
20+
using MongoDB.Bson;
21+
using MongoDB.Driver.Core.Clusters;
22+
using MongoDB.Driver.Core.Misc;
23+
using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
24+
using MongoDB.Driver.Encryption;
25+
using MongoDB.Driver.Tests;
26+
using Xunit;
27+
28+
namespace MongoDB.Driver.Examples
29+
{
30+
public class ClientSideEncryption2Examples
31+
{
32+
private const string LocalMasterKey = "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk";
33+
private readonly static CollectionNamespace CollectionNamespace = CollectionNamespace.FromFullName("docsExamples.encrypted");
34+
private readonly static CollectionNamespace KeyVaultNamespace = CollectionNamespace.FromFullName("keyvault.datakeys");
35+
36+
[SkippableFact]
37+
public void FLE2AutomaticEncryption()
38+
{
39+
RequireServer.Check().Supports(Feature.Csfle2).ClusterTypes(ClusterType.ReplicaSet, ClusterType.Sharded, ClusterType.LoadBalanced);
40+
41+
var unencryptedClient = DriverTestConfiguration.Client;
42+
43+
DropCollections(unencryptedClient);
44+
45+
var localMasterKey = Convert.FromBase64String(LocalMasterKey);
46+
47+
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
48+
var localKey = new Dictionary<string, object>
49+
{
50+
{ "key", localMasterKey }
51+
};
52+
kmsProviders.Add("local", localKey);
53+
54+
var keyVaultClient = new MongoClient();
55+
56+
// Create two data keys.
57+
var clientEncryptionOptions = new ClientEncryptionOptions(keyVaultClient, KeyVaultNamespace, kmsProviders);
58+
using var clientEncryption = new ClientEncryption(clientEncryptionOptions);
59+
var dataKeyOptions = new DataKeyOptions();
60+
var dataKey1 = clientEncryption.CreateDataKey("local", dataKeyOptions, CancellationToken.None);
61+
var dataKey2 = clientEncryption.CreateDataKey("local", dataKeyOptions, CancellationToken.None);
62+
63+
// Create an encryptedFieldsMap with an indexed and unindexed field.
64+
var encryptedFieldsMap = new Dictionary<string, BsonDocument>()
65+
{
66+
{
67+
CollectionNamespace.ToString(),
68+
new BsonDocument
69+
{
70+
{
71+
"fields",
72+
new BsonArray
73+
{
74+
new BsonDocument
75+
{
76+
{ "path", "encryptedIndexed" },
77+
{ "bsonType", "string" },
78+
{ "keyId", new BsonBinaryData(dataKey1, GuidRepresentation.Standard) },
79+
{ "queries", new BsonDocument("queryType", "equality") }
80+
},
81+
new BsonDocument
82+
{
83+
{ "path", "encryptedUnindexed" },
84+
{ "bsonType", "string" },
85+
{ "keyId", new BsonBinaryData(dataKey2, GuidRepresentation.Standard) }
86+
}
87+
}
88+
}
89+
}
90+
}
91+
};
92+
var autoEncryptionOptions = new AutoEncryptionOptions(KeyVaultNamespace, kmsProviders, encryptedFieldsMap: encryptedFieldsMap);
93+
var encryptedClient = new MongoClient(new MongoClientSettings { AutoEncryptionOptions = autoEncryptionOptions });
94+
95+
// Create an FLE 2 collection.
96+
var database = encryptedClient.GetDatabase(CollectionNamespace.DatabaseNamespace.DatabaseName);
97+
database.CreateCollection(CollectionNamespace.CollectionName);
98+
var encryptedCollection = database.GetCollection<BsonDocument>(CollectionNamespace.CollectionName);
99+
100+
// Auto encrypt an insert and find with "Indexed" and "Unindexed" encrypted fields.
101+
string indexedValue = "indexedValue";
102+
string unindexedValue = "unindexedValue";
103+
encryptedCollection.InsertOne(new BsonDocument { { "_id", 1 }, { "encryptedIndexed", indexedValue }, { "encryptedUnindexed", unindexedValue } });
104+
105+
var findResult = encryptedCollection.Find(new BsonDocument("encryptedIndexed", "indexedValue")).Single().AsBsonDocument;
106+
107+
findResult["encryptedIndexed"].Should().Be(new BsonString(indexedValue));
108+
findResult["encryptedUnindexed"].Should().Be(new BsonString(unindexedValue));
109+
110+
// Find documents without decryption.
111+
var unencryptedDatabase = unencryptedClient.GetDatabase(CollectionNamespace.DatabaseNamespace.DatabaseName);
112+
var unencryptedCollection = unencryptedDatabase.GetCollection<BsonDocument>(CollectionNamespace.CollectionName);
113+
findResult = unencryptedCollection.Find(new BsonDocument("_id", 1)).Single().AsBsonDocument;
114+
findResult["encryptedIndexed"].Should().BeOfType<BsonBinaryData>();
115+
findResult["encryptedUnindexed"].Should().BeOfType<BsonBinaryData>();
116+
}
117+
118+
private void DropCollections(IMongoClient client)
119+
{
120+
var database = client.GetDatabase(CollectionNamespace.DatabaseNamespace.DatabaseName);
121+
database.DropCollection(
122+
CollectionNamespace.CollectionName,
123+
new DropCollectionOptions
124+
{
125+
EncryptedFields = new BsonDocument
126+
{
127+
{ "escCollection", $"enxcol_.{CollectionNamespace.CollectionName}.esc" },
128+
{ "eccCollection", $"enxcol_.{CollectionNamespace.CollectionName}.ecc" },
129+
{ "ecocCollection", $"enxcol_.{CollectionNamespace.CollectionName}.ecoc" },
130+
}
131+
});
132+
133+
database = client.GetDatabase(KeyVaultNamespace.DatabaseNamespace.DatabaseName);
134+
database.DropCollection(KeyVaultNamespace.CollectionName);
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)