Skip to content

Commit 7672ade

Browse files
all changes
1 parent 42d9607 commit 7672ade

File tree

9 files changed

+876
-659
lines changed

9 files changed

+876
-659
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Encryption Tests
2+
3+
on:
4+
push:
5+
branches: ['master']
6+
pull_request:
7+
branches: [ 'master' ]
8+
workflow_dispatch: {}
9+
10+
permissions:
11+
contents: write
12+
pull-requests: write
13+
id-token: write
14+
15+
jobs:
16+
run-tests:
17+
permissions:
18+
# required for all workflows
19+
security-events: write
20+
id-token: write
21+
contents: write
22+
runs-on: ubuntu-latest
23+
name: Encryption tests
24+
env:
25+
FORCE_COLOR: true
26+
steps:
27+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
28+
- name: Setup node
29+
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
30+
with:
31+
node-version: latest
32+
- name: Install Dependencies
33+
run: npm install
34+
- name: Install mongodb-client-encryption
35+
run: npm install mongodb-client-encryption
36+
- name: Run Tests
37+
run: npm run test-encryption

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,6 @@ examples/ecommerce-netlify-functions/.netlify/state.json
6767

6868
notes.md
6969
list.out
70+
71+
data
72+
*.pid

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ If you have a question about Mongoose (not a bug report) please post it to eithe
4646
* execute `npm run test-tsd` to run the typescript tests
4747
* execute `npm run ts-benchmark` to run the typescript benchmark "performance test" for a single time.
4848
* execute `npm run ts-benchmark-watch` to run the typescript benchmark "performance test" while watching changes on types folder. Note: Make sure to commit all changes before executing this command.
49+
* in order to run tests that require an cluster with encryption locally, run `npm run test-encryption`. Alternatively, you can start an encrypted cluster using the `scripts/configure-cluster-with-encryption.sh` file.
4950

5051
## Documentation
5152

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.js",
103103
"test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit ./test/*.test.js",
104104
"test-tsd": "node ./test/types/check-types-filename && tsd",
105+
"test-encryption": "bash scripts/run-encryption-tests.sh",
105106
"tdd": "mocha ./test/*.test.js --inspect --watch --recursive --watch-files ./**/*.{js,ts}",
106107
"test-coverage": "nyc --reporter=html --reporter=text npm test",
107108
"ts-benchmark": "cd ./benchmarks/typescript/simple && npm install && npm run benchmark | node ../../../scripts/tsc-diagnostics-check"
@@ -142,4 +143,4 @@
142143
"target": "ES2017"
143144
}
144145
}
145-
}
146+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# note: in order to use FLE with mongodb, we must
2+
# have mongocryptd or the shared library downloaded
3+
# have an enterprise server >= 4.2
4+
5+
# this script downloads all tools required to use FLE with mongodb, then starts a cluster of the provided configuration (sharded on 8.0 server)
6+
7+
export CWD=$(pwd);
8+
mkdir data
9+
cd data
10+
11+
# note:
12+
# we're using drivers-evergreen-tools which is a repo used by MongoDB drivers to start clusters for testing.
13+
# if you'd like to make changes to the cluster settings, edit the exported variables below.
14+
# for configuration options for the exported variables, see here: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/run-orchestration.sh
15+
# after this script is run, the data/ folder will notably contain the following:
16+
# 'mo-expansion.yml' file which contains for your cluster URI and crypt shared library path
17+
# 'drivers-evergreen-tools/mongodb/bin' which contain executables for other mongodb libraries such as mongocryptd, mongosh, and mongod
18+
if [ ! -d "drivers-evergreen-tools/" ]; then
19+
git clone --depth=1 "https://github.com/mongodb-labs/drivers-evergreen-tools.git"
20+
fi
21+
22+
# configure cluster settings
23+
export DRIVERS_TOOLS=$CWD/data/drivers-evergreen-tools
24+
export MONGODB_VERSION=8.0
25+
export AUTH=true
26+
export MONGODB_BINARIES=$DRIVERS_TOOLS/mongodb/bin
27+
export MONGO_ORCHESTRATION_HOME=$DRIVERS_TOOLS/mo
28+
export PROJECT_ORCHESTRATION_HOME=$DRIVERS_TOOLS/.evergreen/orchestration
29+
export TOPOLOGY=sharded_cluster
30+
export SSL=nossl
31+
32+
cd $DRIVERS_TOOLS
33+
rm -rf mongosh mongodb mo
34+
mkdir mo
35+
cd -
36+
37+
rm expansions.sh 2> /dev/null
38+
39+
# start cluster
40+
bash $DRIVERS_TOOLS/.evergreen/run-orchestration.sh

scripts/run-encryption-tests.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
3+
# sets up mongodb cluster and encryption configuration, adds relevant variables to the environment, and runs encryption tests
4+
5+
export CWD=$(pwd);
6+
7+
# set up mongodb cluster and encryption configuration if the data/ folder does not exist
8+
# note: for tooling, cluster set-up and configuration look into the 'scripts/configure-cluster-with-encryption.sh' script
9+
10+
if [ -d "data" ]; then
11+
cd data
12+
else
13+
source $CWD/scripts/configure-cluster-with-encryption.sh
14+
fi
15+
16+
# extracts MONGOOSE_TEST_URI and CRYPT_SHARED_LIB_PATH from .yml file into environment variables for this test run
17+
read -r -d '' SOURCE_SCRIPT << EOM
18+
const fs = require('fs');
19+
const file = fs.readFileSync('mo-expansion.yml', { encoding: 'utf-8' })
20+
.trim().split('\\n');
21+
const regex = /^(?<key>.*): "(?<value>.*)"$/;
22+
const variables = file.map(
23+
(line) => regex.exec(line.trim()).groups
24+
).map(
25+
({key, value}) => \`export \${key}='\${value}'\`
26+
).join('\n');
27+
28+
process.stdout.write(variables);
29+
process.stdout.write('\n');
30+
EOM
31+
32+
node --eval "$SOURCE_SCRIPT" | tee expansions.sh
33+
source expansions.sh
34+
35+
export MONGOOSE_TEST_URI=$MONGODB_URI
36+
37+
# run encryption tests
38+
cd ..
39+
npx mocha --exit ./test/encryption/*.test.js

test/encryption/encryption.test.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const mdb = require('mongodb');
5+
const isBsonType = require('../../lib/helpers/isBsonType');
6+
7+
const LOCAL_KEY = Buffer.from('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'base64');
8+
9+
describe('ci', () => {
10+
describe('environmental variables', () => {
11+
it('MONGOOSE_TEST_URI is set', async function() {
12+
const uri = process.env.MONGOOSE_TEST_URI;
13+
assert.ok(uri);
14+
});
15+
16+
it('CRYPT_SHARED_LIB_PATH is set', async function() {
17+
const shared_library_path = process.env.CRYPT_SHARED_LIB_PATH;
18+
assert.ok(shared_library_path);
19+
});
20+
});
21+
22+
describe('basic integration', () => {
23+
let keyVaultClient;
24+
let dataKey;
25+
let encryptedClient;
26+
let unencryptedClient;
27+
28+
beforeEach(async function() {
29+
keyVaultClient = new mdb.MongoClient(process.env.MONGOOSE_TEST_URI);
30+
await keyVaultClient.connect();
31+
await keyVaultClient.db('keyvault').collection('datakeys');
32+
const clientEncryption = new mdb.ClientEncryption(keyVaultClient, {
33+
keyVaultNamespace: 'keyvault.datakeys',
34+
kmsProviders: { local: { key: LOCAL_KEY } }
35+
});
36+
dataKey = await clientEncryption.createDataKey('local');
37+
38+
encryptedClient = new mdb.MongoClient(
39+
process.env.MONGOOSE_TEST_URI,
40+
{
41+
autoEncryption: {
42+
keyVaultNamespace: 'keyvault.datakeys',
43+
kmsProviders: { local: { key: LOCAL_KEY } },
44+
schemaMap: {
45+
'db.coll': {
46+
bsonType: 'object',
47+
encryptMetadata: {
48+
keyId: [dataKey]
49+
},
50+
properties: {
51+
a: {
52+
encrypt: {
53+
bsonType: 'int',
54+
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Random',
55+
keyId: [dataKey]
56+
}
57+
}
58+
}
59+
}
60+
},
61+
extraOptions: {
62+
cryptdSharedLibRequired: true,
63+
cryptSharedLibPath: process.env.CRYPT_SHARED_LIB_PATH
64+
}
65+
}
66+
}
67+
);
68+
69+
unencryptedClient = new mdb.MongoClient(process.env.MONGOOSE_TEST_URI);
70+
});
71+
72+
afterEach(async function() {
73+
await keyVaultClient.close();
74+
await encryptedClient.close();
75+
await unencryptedClient.close();
76+
});
77+
78+
it('ci set-up should support basic mongodb auto-encryption integration', async() => {
79+
await encryptedClient.connect();
80+
const { insertedId } = await encryptedClient.db('db').collection('coll').insertOne({ a: 1 });
81+
82+
// client not configured with autoEncryption, returns a encrypted binary type, meaning that encryption succeeded
83+
const encryptedResult = await unencryptedClient.db('db').collection('coll').findOne({ _id: insertedId });
84+
85+
assert.ok(encryptedResult);
86+
assert.ok(encryptedResult.a);
87+
assert.ok(isBsonType(encryptedResult.a, 'Binary'));
88+
assert.ok(encryptedResult.a.sub_type === 6);
89+
90+
// when the encryptedClient runs a find, the original unencrypted value is returned
91+
const unencryptedResult = await encryptedClient.db('db').collection('coll').findOne({ _id: insertedId });
92+
assert.ok(unencryptedResult);
93+
assert.ok(unencryptedResult.a === 1);
94+
});
95+
});
96+
});

0 commit comments

Comments
 (0)