211 lines
8.3 KiB
JavaScript
211 lines
8.3 KiB
JavaScript
|
|
// Test that mongod will not allow creating a validator or view containing JSON Schema with
|
||
|
|
// encryption keywords when the feature compatibility version is older than 4.2.
|
||
|
|
(function() {
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
const testName = "json_schema_encrypt_fcv";
|
||
|
|
let dbpath = MongoRunner.dataPath + testName;
|
||
|
|
resetDbpath(dbpath);
|
||
|
|
|
||
|
|
let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest"});
|
||
|
|
assert.neq(null, conn, "mongod was unable to start up");
|
||
|
|
|
||
|
|
let testDB = conn.getDB(testName);
|
||
|
|
assert.commandWorked(testDB.dropDatabase());
|
||
|
|
|
||
|
|
let adminDB = conn.getDB("admin");
|
||
|
|
|
||
|
|
// Explicitly set feature compatibility version 4.2.
|
||
|
|
assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.2"}));
|
||
|
|
|
||
|
|
// Create a collection with a validator containing JSON Schema with 'encrypt'.
|
||
|
|
const jsonSchemaWithEncrypt = {
|
||
|
|
$jsonSchema: {
|
||
|
|
type: "object",
|
||
|
|
properties: {
|
||
|
|
foo: {
|
||
|
|
encrypt:
|
||
|
|
{algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random", keyId: [UUID()]}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
assert.commandWorked(testDB.createCollection("coll", {validator: jsonSchemaWithEncrypt}));
|
||
|
|
let coll = testDB.coll;
|
||
|
|
|
||
|
|
// Create a view with a pipeline which contains a JSON Schema with 'encrypt' in a match stage.
|
||
|
|
assert.commandWorked(testDB.runCommand(
|
||
|
|
{create: "collView", viewOn: "coll", pipeline: [{$match: jsonSchemaWithEncrypt}]}));
|
||
|
|
|
||
|
|
// The validator should cause this insert to fail.
|
||
|
|
assert.writeError(coll.insert({foo: "not encrypted"}), ErrorCodes.DocumentValidationFailure);
|
||
|
|
|
||
|
|
// Set a validator with 'encrypt' on an existing collection.
|
||
|
|
assert.commandWorked(testDB.runCommand({
|
||
|
|
collMod: "coll",
|
||
|
|
validator: {
|
||
|
|
$jsonSchema: {
|
||
|
|
type: "object",
|
||
|
|
properties: {
|
||
|
|
bar: {
|
||
|
|
encrypt: {
|
||
|
|
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
|
||
|
|
keyId: [UUID()]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
|
||
|
|
// Another failing insert.
|
||
|
|
assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure);
|
||
|
|
|
||
|
|
// Querying the view while in FCV 4.2 should work.
|
||
|
|
assert.eq([], testDB.collView.find().toArray());
|
||
|
|
|
||
|
|
// Set the feature compatibility version to 4.0.
|
||
|
|
assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.0"}));
|
||
|
|
|
||
|
|
// The validator is already in place, so it should still cause this insert to fail.
|
||
|
|
assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure);
|
||
|
|
|
||
|
|
// Trying to create a new collection with a validator that contains 'encrypt' should fail while
|
||
|
|
// feature compatibility version is 4.0.
|
||
|
|
assert.commandFailedWithCode(
|
||
|
|
testDB.createCollection("coll2", {validator: jsonSchemaWithEncrypt}),
|
||
|
|
ErrorCodes.QueryFeatureNotAllowed);
|
||
|
|
|
||
|
|
// Trying to collMod a collection with 'encrypt' in the validator should also fail.
|
||
|
|
assert.commandFailedWithCode(
|
||
|
|
testDB.runCommand({collMod: "coll", validator: jsonSchemaWithEncrypt}),
|
||
|
|
ErrorCodes.QueryFeatureNotAllowed);
|
||
|
|
|
||
|
|
// Querying the view while in FCV 4.0 should continue to work.
|
||
|
|
assert.eq([], testDB.collView.find().toArray());
|
||
|
|
|
||
|
|
// Attempting to create a new view containing JSON Schema with 'encrypt' should fail while in
|
||
|
|
// FCV 4.0.
|
||
|
|
assert.commandFailedWithCode(
|
||
|
|
testDB.runCommand(
|
||
|
|
{create: "collView2", viewOn: "coll", pipeline: [{$match: jsonSchemaWithEncrypt}]}),
|
||
|
|
ErrorCodes.QueryFeatureNotAllowed);
|
||
|
|
|
||
|
|
MongoRunner.stopMongod(conn);
|
||
|
|
|
||
|
|
// If we try to start up a 4.0 mongod, it will fail, because it will not be able to parse the
|
||
|
|
// $jsonSchema validator.
|
||
|
|
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "4.0", noCleanData: true});
|
||
|
|
assert.eq(null,
|
||
|
|
conn,
|
||
|
|
"mongod 4.0 started, even with a $jsonSchema validator with 'encrypt' in place.");
|
||
|
|
|
||
|
|
// Starting up a 4.2 mongod, however, should succeed, even though the feature compatibility
|
||
|
|
// version is still set to 4.0.
|
||
|
|
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
|
||
|
|
assert.neq(null, conn, "mongod was unable to start up");
|
||
|
|
|
||
|
|
adminDB = conn.getDB("admin");
|
||
|
|
testDB = conn.getDB(testName);
|
||
|
|
coll = testDB.coll;
|
||
|
|
|
||
|
|
// And the validator should still work.
|
||
|
|
assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure);
|
||
|
|
|
||
|
|
// Remove the validator.
|
||
|
|
assert.commandWorked(testDB.runCommand({collMod: "coll", validator: {}}));
|
||
|
|
|
||
|
|
// Querying on the view should also still work.
|
||
|
|
assert.eq([], testDB.collView.find().toArray());
|
||
|
|
|
||
|
|
MongoRunner.stopMongod(conn);
|
||
|
|
|
||
|
|
// Now, we should be able to start up a 4.0 mongod.
|
||
|
|
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "4.0", noCleanData: true});
|
||
|
|
assert.neq(
|
||
|
|
null, conn, "mongod 4.0 failed to start, even after we removed the $jsonSchema validator");
|
||
|
|
|
||
|
|
testDB = conn.getDB(testName);
|
||
|
|
|
||
|
|
// The view containing the JSON Schema 'encrypt' keyword should still exist.
|
||
|
|
assert.eq(
|
||
|
|
"collView",
|
||
|
|
testDB.runCommand({listCollections: 1, filter: {type: "view"}}).cursor.firstBatch[0].name);
|
||
|
|
|
||
|
|
// However, querying on the view with the invalid view pipeline should fail on binary version
|
||
|
|
// 4.0.
|
||
|
|
assert.commandFailedWithCode(testDB.runCommand({find: "collView", filter: {}}),
|
||
|
|
ErrorCodes.FailedToParse);
|
||
|
|
|
||
|
|
// Dropping the invalid view should be allowed.
|
||
|
|
assert.commandWorked(testDB.runCommand({drop: "collView"}));
|
||
|
|
|
||
|
|
MongoRunner.stopMongod(conn);
|
||
|
|
|
||
|
|
// The rest of the test uses mongod 4.2.
|
||
|
|
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true});
|
||
|
|
assert.neq(null, conn, "mongod was unable to start up");
|
||
|
|
|
||
|
|
adminDB = conn.getDB("admin");
|
||
|
|
testDB = conn.getDB(testName);
|
||
|
|
coll = testDB.coll;
|
||
|
|
|
||
|
|
// Set the feature compatibility version back to 4.2.
|
||
|
|
assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.2"}));
|
||
|
|
|
||
|
|
// Now we should be able to create a collection with a validator containing 'encrypt' again.
|
||
|
|
assert.commandWorked(testDB.createCollection("coll2", {validator: jsonSchemaWithEncrypt}));
|
||
|
|
|
||
|
|
// And we should be able to modify a collection to have a validator containing 'encrypt'.
|
||
|
|
assert.commandWorked(testDB.runCommand({collMod: "coll", validator: jsonSchemaWithEncrypt}));
|
||
|
|
|
||
|
|
// And we should be able to create a view with a pipeline containing 'encrypt'.
|
||
|
|
assert.commandWorked(testDB.runCommand(
|
||
|
|
{create: "collView2", viewOn: "coll", pipeline: [{$match: jsonSchemaWithEncrypt}]}));
|
||
|
|
|
||
|
|
// Set the feature compatibility version to 4.0 and then restart with
|
||
|
|
// internalValidateFeaturesAsMaster=false.
|
||
|
|
assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "4.0"}));
|
||
|
|
MongoRunner.stopMongod(conn);
|
||
|
|
conn = MongoRunner.runMongod({
|
||
|
|
dbpath: dbpath,
|
||
|
|
binVersion: "latest",
|
||
|
|
noCleanData: true,
|
||
|
|
setParameter: "internalValidateFeaturesAsMaster=false"
|
||
|
|
});
|
||
|
|
assert.neq(null, conn, "mongod was unable to start up");
|
||
|
|
|
||
|
|
testDB = conn.getDB(testName);
|
||
|
|
|
||
|
|
// Even though the feature compatibility version is 4.0, we should still be able to add a
|
||
|
|
// JSON Schema validator containing 'encrypt', because internalValidateFeaturesAsMaster is
|
||
|
|
// false.
|
||
|
|
assert.commandWorked(testDB.createCollection("coll3", {validator: jsonSchemaWithEncrypt}));
|
||
|
|
|
||
|
|
// We should also be able to modify a collection to have a JSON Schema validator containing
|
||
|
|
// 'encrypt'.
|
||
|
|
assert.commandWorked(testDB.runCommand({
|
||
|
|
collMod: "coll3",
|
||
|
|
validator: {
|
||
|
|
$jsonSchema: {
|
||
|
|
type: "object",
|
||
|
|
properties: {
|
||
|
|
bar: {
|
||
|
|
encrypt: {
|
||
|
|
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
|
||
|
|
keyId: [UUID()]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
|
||
|
|
// We should also be able to create a view containing a JSON Schema with the 'encrypt' keyword.
|
||
|
|
assert.commandWorked(testDB.runCommand(
|
||
|
|
{create: "collView3", viewOn: "coll", pipeline: [{$match: jsonSchemaWithEncrypt}]}));
|
||
|
|
|
||
|
|
MongoRunner.stopMongod(conn);
|
||
|
|
}());
|