Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add back install dir
  • Loading branch information
baileympearson committed Aug 5, 2024
commit b9d141e73fc63117bee47a037ebd1c77207fb373
7 changes: 3 additions & 4 deletions .evergreen/install-mongodb-client-encryption.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#! /usr/bin/env bash
set +o xtrace # Do not write AWS credentials to stderr
set +o xtrace

# Initial checks for running these tests
if [ -z ${PROJECT_DIRECTORY+omitted} ]; then echo "PROJECT_DIRECTORY is unset" && exit 1; fi
Expand All @@ -9,20 +9,19 @@ source "${PROJECT_DIRECTORY}/.evergreen/init-node-and-npm-env.sh"
set -o xtrace # Write all commands first to stderr
set -o errexit # Exit the script with error if any of the commands fail

rm -rf $INSTALL_DIR
rm -rf mongodb-client-encryption
git clone https://github.com/mongodb-js/mongodb-client-encryption.git
pushd mongodb-client-encryption

if [ -n "${LIBMONGOCRYPT_VERSION}" ]; then
# nightly tests test with `latest` to test against the laster FLE build.
npm run install:libmongocrypt -- --libVersion $LIBMONGOCRYPT_VERSION
npm run install:libmongocrypt -- --build --libVersion $LIBMONGOCRYPT_VERSION
else
# otherwise use whatever is specified in the package.json.
npm run install:libmongocrypt
fi

echo "finished installing libmongocrypt"
BINDINGS_DIR=$(pwd)

popd

Expand Down
15 changes: 12 additions & 3 deletions src/client-side-encryption/client_encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ import type {
MongoCryptOptions
} from 'mongodb-client-encryption';

import { type Binary, deserialize, type Document, type Long, serialize, type UUID } from '../bson';
import {
type Binary,
deserialize,
type Document,
type Int32,
type Long,
serialize,
type UUID
} from '../bson';
import { type AnyBulkWriteOperation, type BulkWriteResult } from '../bulk/common';
import { type ProxyOptions } from '../cmap/connection';
import { type Collection } from '../collection';
Expand Down Expand Up @@ -948,12 +956,13 @@ export interface ClientEncryptionRewrapManyDataKeyResult {
/**
* @public
* RangeOptions specifies index options for a Queryable Encryption field supporting "rangePreview" queries.
* min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
* min, max, sparsity, trimFactor and range must match the values set in the encryptedFields of the destination collection.
* For double and decimal128, min/max/precision must all be set, or all be unset.
*/
export interface RangeOptions {
min?: any;
max?: any;
sparsity: Long;
sparsity?: Long;
trimFactor?: Int32;
precision?: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { type Binary, EJSON, Int32, Long } from 'bson';
import { expect } from 'chai';

/* eslint-disable @typescript-eslint/no-restricted-imports */
import { ClientEncryption } from '../../../src/client-side-encryption/client_encryption';
import { installNodeDNSWorkaroundHooks } from '../../tools/runner/hooks/configuration';

const metaData: MongoDBMetadataUI = {
requires: {
clientSideEncryption: '>=6.1.0',

// The Range Explicit Encryption tests require MongoDB server 7.0+ for QE v2.
// The tests must not run against a standalone.
//
// `range` is not supported on 8.0+ servers.
mongodb: '>=8.0.0',
topology: '!single'
}
};

const getKmsProviders = (): { local: { key: string } } => {
const result = EJSON.parse(process.env.CSFLE_KMS_PROVIDERS || '{}') as unknown as {
local: { key: string };
};

return { local: result.local };
};

describe('Range Explicit Encryption Defaults', function () {
installNodeDNSWorkaroundHooks();

let clientEncryption: ClientEncryption;
let keyId;
let keyVaultClient;
let payload_defaults: Binary;

beforeEach(async function () {
// Create a MongoClient named `keyVaultClient`.
keyVaultClient = this.configuration.newClient();

// Create a ClientEncryption object named `clientEncryption` with these options:
// ```typescript
// class ClientEncryptionOpts {
// keyVaultClient: keyVaultClient,
// keyVaultNamespace: "keyvault.datakeys",
// kmsProviders: { "local": { "key": "<base64 decoding of LOCAL_MASTERKEY>" } },
// }
// ```
clientEncryption = new ClientEncryption(keyVaultClient, {
keyVaultNamespace: 'keyvault.datakeys',
kmsProviders: getKmsProviders()
});

// Create a key with `clientEncryption.createDataKey`. Store the returned key ID in a variable named `keyId`.
keyId = await clientEncryption.createDataKey('local');

// Call `clientEncryption.encrypt` to encrypt the int32 value `123` with these options:
// ```typescript
// class EncryptOpts {
// keyId : keyId,
// algorithm: "Range",
// contentionFactor: 0,
// rangeOpts: RangeOpts {
// min: 0,
// max: 1000
// }
// }
// ```
// Store the result in a variable named `payload_defaults`.
payload_defaults = await clientEncryption.encrypt(new Int32(123), {
keyId,
algorithm: 'Range',
contentionFactor: 0,
rangeOptions: {
min: 0,
max: 1000
}
});
});

afterEach(async function () {
await keyVaultClient.close();
});

it('Case 1: Uses libmongocrypt defaults', metaData, async function () {
// Call `clientEncryption.encrypt` to encrypt the int32 value `123` with these options:
// ```typescript
// class EncryptOpts {
// keyId : keyId,
// algorithm: "Range",
// contentionFactor: 0,
// rangeOpts: RangeOpts {
// min: 0,
// max: 1000,
// sparsity: 2,
// trimFactor: 6
// }
// }
// ```
const encrypted = await clientEncryption.encrypt(new Int32(123), {
keyId: keyId,
algorithm: 'Range',
contentionFactor: 0,
rangeOptions: {
min: 0,
max: 1000,
sparsity: new Long(2),
trimFactor: new Int32(6)
}
});

// Assert the returned payload size equals the size of `payload_defaults`.
expect(encrypted.length()).to.equal(payload_defaults.length());
});

it('Case 2: can find encrypted range and return the maximum', metaData, async function () {
// Call `clientEncryption.encrypt` to encrypt the int32 value `123` with these options:
// ```typescript
// class EncryptOpts {
// keyId : keyId,
// algorithm: "Range",
// contentionFactor: 0,
// rangeOpts: RangeOpts {
// min: 0,
// max: 1000,
// trimFactor: 0
// }
// }
// ```
const encrypted = await clientEncryption.encrypt(new Int32(123), {
keyId: keyId,
algorithm: 'Range',
contentionFactor: 0,
rangeOptions: {
min: 0,
max: 1000,
trimFactor: new Int32(0)
}
});

// Assert the returned payload size is greater than the size of `payload_defaults`.
expect(encrypted.length()).to.be.greaterThan(payload_defaults.length());
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"runOn": [
{
"minServerVersion": "8.0.0",
"minServerVersion": "7.0.0",
"topology": [
"replicaset",
"sharded",
Expand Down Expand Up @@ -130,6 +130,9 @@
"command": {
"compactStructuredEncryptionData": "default"
}
},
"result": {
"ok": 1
}
}
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Requires libmongocrypt 1.8.0.
# Requires libmongocrypt 1.8.0. libmongocrypt 1.10.0 has a bug (MONGOCRYPT-699) that may cause this test to fail on server version 7.
runOn:
# TODO(NODE-6128): lower server version to 7.0.0
- minServerVersion: "8.0.0"
- minServerVersion: "7.0.0"
# Skip QEv2 (also referred to as FLE2v2) tests on Serverless. Unskip once Serverless enables the QEv2 protocol.
# FLE 2 Encrypted collections are not supported on standalone.
topology: [ "replicaset", "sharded", "load-balanced" ]
Expand All @@ -23,6 +22,8 @@ tests:
arguments:
command:
compactStructuredEncryptionData: *collection_name
result:
ok: 1
expectations:
- command_started_event:
command:
Expand Down Expand Up @@ -80,4 +81,4 @@ tests:
command:
compactStructuredEncryptionData: *collection_name
result:
errorContains: "'compactStructuredEncryptionData.compactionTokens' is missing"
errorContains: "'compactStructuredEncryptionData.compactionTokens' is missing"
Loading