Skip to content

Commit b1fc872

Browse files
authored
test(NODE-5015): clientEncryption createEncryptedCollection helper (#3555)
1 parent ddfc2b9 commit b1fc872

File tree

5 files changed

+166
-6
lines changed

5 files changed

+166
-6
lines changed

.evergreen/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,7 @@ tasks:
22042204
- func: bootstrap kms servers
22052205
- func: run custom csfle tests
22062206
vars:
2207-
CSFLE_GIT_REF: 67bec571c0c21f4db8a96b6bd61cb24dfc87a223
2207+
CSFLE_GIT_REF: 77b51c00ab4ff58916dd39f55657e1ecc0af281c
22082208
- name: run-custom-csfle-tests-5.0-master
22092209
tags:
22102210
- run-custom-dependency-tests
@@ -2234,7 +2234,7 @@ tasks:
22342234
- func: bootstrap kms servers
22352235
- func: run custom csfle tests
22362236
vars:
2237-
CSFLE_GIT_REF: 67bec571c0c21f4db8a96b6bd61cb24dfc87a223
2237+
CSFLE_GIT_REF: 77b51c00ab4ff58916dd39f55657e1ecc0af281c
22382238
- name: run-custom-csfle-tests-rapid-master
22392239
tags:
22402240
- run-custom-dependency-tests
@@ -2264,7 +2264,7 @@ tasks:
22642264
- func: bootstrap kms servers
22652265
- func: run custom csfle tests
22662266
vars:
2267-
CSFLE_GIT_REF: 67bec571c0c21f4db8a96b6bd61cb24dfc87a223
2267+
CSFLE_GIT_REF: 77b51c00ab4ff58916dd39f55657e1ecc0af281c
22682268
- name: run-custom-csfle-tests-latest-master
22692269
tags:
22702270
- run-custom-dependency-tests

.evergreen/generate_evergreen_tasks.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,10 @@ const oneOffFuncAsTasks = oneOffFuncs.map(oneOffFunc => ({
622622
]
623623
}));
624624

625+
const FLE_PINNED_COMMIT = '77b51c00ab4ff58916dd39f55657e1ecc0af281c'
626+
625627
for (const version of ['5.0', 'rapid', 'latest']) {
626-
for (const ref of ['67bec571c0c21f4db8a96b6bd61cb24dfc87a223', 'master']) {
628+
for (const ref of [FLE_PINNED_COMMIT, 'master']) {
627629
oneOffFuncAsTasks.push({
628630
name: `run-custom-csfle-tests-${version}-${ref === 'master' ? ref : 'pinned-commit'}`,
629631
tags: ['run-custom-dependency-tests'],

.evergreen/run-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ else
5252
source "$DRIVERS_TOOLS"/.evergreen/csfle/set-temp-creds.sh
5353
fi
5454

55-
npm install mongodb-client-encryption@"2.4.0"
55+
npm install mongodb-client-encryption@"2.5.0"
5656
npm install @mongodb-js/zstd
5757
npm install snappy
5858

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { expect } from 'chai';
2+
3+
import { BSON, Collection, Db, MongoServerError } from '../../../src';
4+
import { installNodeDNSWorkaroundHooks } from '../../tools/runner/hooks/configuration';
5+
6+
const metadata = {
7+
requires: {
8+
clientSideEncryption: true,
9+
mongodb: '>=6.0.0',
10+
topology: '!single'
11+
}
12+
} as const;
13+
14+
const documentValidationFailureCode = 121;
15+
const typeMismatchCode = 14;
16+
17+
describe('21. Automatic Data Encryption Keys', () => {
18+
installNodeDNSWorkaroundHooks();
19+
20+
let db: Db;
21+
let clientEncryption;
22+
let client;
23+
let MongoCryptCreateEncryptedCollectionError;
24+
25+
const runProseTestsFor = provider => {
26+
const masterKey = {
27+
aws: {
28+
region: 'us-east-1',
29+
key: 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0'
30+
},
31+
local: null
32+
}[provider];
33+
beforeEach(async function () {
34+
client = this.configuration.newClient();
35+
const {
36+
ClientEncryption,
37+
MongoCryptCreateEncryptedCollectionError: MongoCryptCreateEncryptedCollectionErrorCtor
38+
} = this.configuration.mongodbClientEncryption;
39+
MongoCryptCreateEncryptedCollectionError = MongoCryptCreateEncryptedCollectionErrorCtor;
40+
41+
if (typeof process.env.CSFLE_KMS_PROVIDERS !== 'string') {
42+
if (this.currentTest) {
43+
this.currentTest.skipReason = 'This test requires env CSFLE_KMS_PROVIDERS to be set';
44+
}
45+
return this.currentTest?.skip();
46+
}
47+
48+
const { aws, local } = BSON.EJSON.parse(process.env.CSFLE_KMS_PROVIDERS);
49+
50+
clientEncryption = new ClientEncryption(client, {
51+
keyVaultClient: client,
52+
keyVaultNamespace: 'keyvault.datakeys',
53+
kmsProviders: { aws, local }
54+
});
55+
56+
db = client.db('automatic_data_encryption_keys');
57+
await db.dropDatabase().catch(() => null);
58+
});
59+
60+
afterEach(async function () {
61+
await db?.dropDatabase().catch(() => null);
62+
await client?.close();
63+
});
64+
65+
it('Case 1: Simple Creation and Validation', metadata, async () => {
66+
const createCollectionOptions = {
67+
encryptedFields: { fields: [{ path: 'ssn', bsonType: 'string', keyId: null }] }
68+
};
69+
70+
const { collection } = await clientEncryption.createEncryptedCollection(db, 'testing1', {
71+
provider,
72+
createCollectionOptions,
73+
masterKey
74+
});
75+
76+
expect(collection).to.be.instanceOf(Collection);
77+
expect(collection.namespace).to.equal('automatic_data_encryption_keys.testing1');
78+
79+
const result = await collection.insertOne({ ssn: '123-45-6789' }).catch(error => error);
80+
expect(result).to.be.instanceOf(MongoServerError);
81+
expect(result).to.have.property('code', documentValidationFailureCode);
82+
});
83+
84+
it('Case 2: Missing encryptedFields', metadata, async () => {
85+
const createCollectionOptions = {};
86+
87+
const result = await clientEncryption
88+
.createEncryptedCollection(db, 'testing1', {
89+
provider,
90+
createCollectionOptions,
91+
masterKey
92+
})
93+
.catch(error => error);
94+
95+
expect(result).to.be.instanceOf(TypeError);
96+
});
97+
98+
it('Case 3: Invalid keyId', metadata, async () => {
99+
const createCollectionOptions = {
100+
encryptedFields: { fields: [{ path: 'ssn', bsonType: 'string', keyId: false }] }
101+
};
102+
103+
const result = await clientEncryption
104+
.createEncryptedCollection(db, 'testing1', {
105+
provider,
106+
createCollectionOptions,
107+
masterKey
108+
})
109+
.catch(error => error);
110+
111+
expect(result).to.be.instanceOf(MongoCryptCreateEncryptedCollectionError);
112+
expect(result).nested.property('cause.code', typeMismatchCode);
113+
// BSON field 'create.encryptedFields.fields.keyId' is the wrong type 'bool', expected type 'binData'
114+
expect(result.cause.message)
115+
.to.match(/bool/i)
116+
.and.match(/binData/i)
117+
.and.match(/keyId/i);
118+
});
119+
120+
it('Case 4: Insert encrypted value', metadata, async () => {
121+
const createCollectionOptions = {
122+
encryptedFields: { fields: [{ path: 'ssn', bsonType: 'string', keyId: null }] }
123+
};
124+
125+
const { collection, encryptedFields } = await clientEncryption.createEncryptedCollection(
126+
db,
127+
'testing1',
128+
{
129+
provider,
130+
createCollectionOptions,
131+
masterKey
132+
}
133+
);
134+
135+
expect(collection).to.be.instanceOf(Collection);
136+
expect(collection.namespace).to.equal('automatic_data_encryption_keys.testing1');
137+
138+
const ssn = clientEncryption.encrypt('123-45-6789', {
139+
algorithm: 'Unindexed',
140+
keyId: encryptedFields.fields[0].keyId
141+
});
142+
143+
const result = await collection.insertOne({ ssn }).catch(error => error);
144+
expect(result).to.be.instanceOf(MongoServerError);
145+
expect(result).to.have.property('code', documentValidationFailureCode);
146+
expect(result).to.have.nested.property(
147+
'errInfo.details.schemaRulesNotSatisfied[0].propertiesNotSatisfied[0].propertyName',
148+
'ssn'
149+
);
150+
});
151+
};
152+
153+
for (const provider of ['local', 'aws']) {
154+
context(`${provider}`, () => {
155+
runProseTestsFor(provider);
156+
});
157+
}
158+
});

test/integration/client-side-encryption/client_side_encryption.prose.22.range_explicit_encryption.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const metaData: MongoDBMetadataUI = {
2727
};
2828

2929
/**
30-
* a comparitor function to sort two documents by their _id
30+
* a comparator function to sort two documents by their _id
3131
*/
3232
function byId(a, b) {
3333
if (a._id > b._id) return 1;

0 commit comments

Comments
 (0)