summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/aggregation/sources/out/bypass_doc_validation.js64
-rw-r--r--jstests/auth/commands_builtin_roles.js2
-rw-r--r--jstests/auth/commands_user_defined_roles.js4
-rw-r--r--jstests/auth/lib/commands_lib.js195
4 files changed, 182 insertions, 83 deletions
diff --git a/jstests/aggregation/sources/out/bypass_doc_validation.js b/jstests/aggregation/sources/out/bypass_doc_validation.js
index 3b67647ef14..41d5ac4d41d 100644
--- a/jstests/aggregation/sources/out/bypass_doc_validation.js
+++ b/jstests/aggregation/sources/out/bypass_doc_validation.js
@@ -55,7 +55,7 @@
}());
function assertDocValidationFailure(cmdOptions) {
- targetColl.remove({});
+ assert.commandWorked(targetColl.remove({}));
assertErrorCode(sourceColl,
[{$out: targetColl.getName()}],
ErrorCodes.DocumentValidationFailure,
@@ -119,7 +119,7 @@
// Test that the bypassDocumentValidation is casted to true if the value is non-boolean.
(function testNonBooleanBypassDocValidationFlag() {
- targetColl.remove({});
+ assert.commandWorked(targetColl.remove({}));
assert.commandWorked(testDB.runCommand({collMod: targetColl.getName(), validator: {a: 1}}));
sourceColl.drop();
assert.commandWorked(sourceColl.insert({_id: 0, a: 1}));
@@ -132,4 +132,64 @@
{bypassDocumentValidation: "false"});
assert.eq([{_id: 0, a: 3}], targetColl.find().toArray());
}());
+
+ // Test bypassDocumentValidation with $out to a collection in a foreign database.
+ (function testForeignDb() {
+ const foreignDB = db.getSiblingDB("foreign_db");
+ const foreignColl = foreignDB.foreign_coll;
+ foreignColl.drop();
+ assert.commandWorked(
+ foreignDB.createCollection(foreignColl.getName(), {validator: {a: 2}}));
+
+ sourceColl.aggregate(
+ [
+ {$addFields: {a: 3}},
+ {
+ $out: {
+ db: foreignDB.getName(),
+ to: foreignColl.getName(),
+ mode: "replaceDocuments"
+ }
+ }
+ ],
+ {bypassDocumentValidation: true});
+ assert.eq([{_id: 0, a: 3}], foreignColl.find().toArray());
+
+ sourceColl.aggregate(
+ [
+ {$replaceRoot: {newRoot: {_id: 1, a: 4}}},
+ {
+ $out:
+ {db: foreignDB.getName(), to: foreignColl.getName(), mode: "insertDocuments"}
+ }
+ ],
+ {bypassDocumentValidation: true});
+ assert.eq([{_id: 0, a: 3}, {_id: 1, a: 4}], foreignColl.find().sort({_id: 1}).toArray());
+
+ assert.commandWorked(foreignColl.remove({}));
+ assertErrorCode(sourceColl,
+ [
+ {$addFields: {a: 3}},
+ {
+ $out: {
+ db: foreignDB.getName(),
+ to: foreignColl.getName(),
+ mode: "replaceDocuments"
+ }
+ }
+ ],
+ ErrorCodes.DocumentValidationFailure);
+
+ assertErrorCode(
+ sourceColl,
+ [
+ {$replaceRoot: {newRoot: {_id: 1, a: 4}}},
+ {
+ $out:
+ {db: foreignDB.getName(), to: foreignColl.getName(), mode: "insertDocuments"}
+ }
+ ],
+ ErrorCodes.DocumentValidationFailure);
+ assert.eq(0, foreignColl.find().itcount());
+ }());
}());
diff --git a/jstests/auth/commands_builtin_roles.js b/jstests/auth/commands_builtin_roles.js
index 92a21ec4096..f309435d6d6 100644
--- a/jstests/auth/commands_builtin_roles.js
+++ b/jstests/auth/commands_builtin_roles.js
@@ -59,7 +59,7 @@ function testProperAuthorization(conn, t, testcase, r) {
authCommandsLib.authenticatedSetup(t, runOnDb);
var command = t.command;
if (typeof(command) === "function") {
- command = t.command(state);
+ command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
diff --git a/jstests/auth/commands_user_defined_roles.js b/jstests/auth/commands_user_defined_roles.js
index 686d4d381e3..049034f4c86 100644
--- a/jstests/auth/commands_user_defined_roles.js
+++ b/jstests/auth/commands_user_defined_roles.js
@@ -41,7 +41,7 @@ function testProperAuthorization(conn, t, testcase, privileges) {
var command = t.command;
if (typeof(command) === "function") {
- command = t.command(state);
+ command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
@@ -79,7 +79,7 @@ function testInsufficientPrivileges(conn, t, testcase, privileges) {
var command = t.command;
if (typeof(command) === "function") {
- command = t.command(state);
+ command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index b61ab47137a..0a485990027 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -79,6 +79,11 @@ privileges causes an authorization failure. If an individual privilege specifies
"removeWhenTestingAuthzFailure: false", then that privilege will not be removed when testing for
authorization failure.
+9) commandArgs
+
+Set of options to be passed to your 'command' function. Can be used to send different versions of
+the command depending on the testcase being run.
+
*/
// constants
@@ -1052,10 +1057,18 @@ var authCommandsLib = {
},
{
testname: "aggregate_out_legacy",
- command: {aggregate: "foo", pipeline: [{$out: "foo_out"}], cursor: {}},
+ command: function(state, args) {
+ return {
+ aggregate: "foo",
+ pipeline: [{$out: "foo_out"}],
+ cursor: {},
+ bypassDocumentValidation: args.bypassDocumentValidation,
+ };
+ },
testcases: [
{
runOnDb: firstDbName,
+ commandArgs: {bypassDocumentValidation: false},
roles: {readWrite: 1, readWriteAnyDatabase: 1, dbOwner: 1, root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
@@ -1065,6 +1078,7 @@ var authCommandsLib = {
},
{
runOnDb: secondDbName,
+ commandArgs: {bypassDocumentValidation: false},
roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
privileges: [
{resource: {db: secondDbName, collection: "foo"}, actions: ["find"]},
@@ -1072,18 +1086,35 @@ var authCommandsLib = {
{resource: {db: secondDbName, collection: "foo_out"}, actions: ["remove"]}
]
},
+ {
+ runOnDb: firstDbName,
+ commandArgs: {bypassDocumentValidation: true},
+ // Note that the built-in role must have 'bypassDocumentValidation' for this test.
+ roles: {dbOwner: 1, root: 1, __system: 1},
+ privileges: [
+ {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
+ {
+ resource: {db: firstDbName, collection: "foo_out"},
+ actions: ["insert", "remove", "bypassDocumentValidation"]
+ },
+ ]
+ },
]
},
{
testname: "aggregate_out_replace_collection",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "replaceCollection"}}],
- cursor: {}
+ command: function(state, args) {
+ return {
+ aggregate: "foo",
+ pipeline: [{$out: {db: args.targetDB, to: "foo_out", mode: "replaceCollection"}}],
+ cursor: {},
+ bypassDocumentValidation: args.bypassDocumentValidation,
+ };
},
testcases: [
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: false},
roles: {readWrite: 1, readWriteAnyDatabase: 1, dbOwner: 1, root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
@@ -1093,6 +1124,7 @@ var authCommandsLib = {
},
{
runOnDb: secondDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: false},
roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
privileges: [
{resource: {db: secondDbName, collection: "foo"}, actions: ["find"]},
@@ -1100,18 +1132,36 @@ var authCommandsLib = {
{resource: {db: secondDbName, collection: "foo_out"}, actions: ["remove"]}
]
},
+ {
+ runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: true},
+ // Note that the built-in role must have 'bypassDocumentValidation' for this test.
+ roles: {dbOwner: 1, root: 1, __system: 1},
+ privileges: [
+ {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
+ {
+ resource: {db: firstDbName, collection: "foo_out"},
+ actions: ["insert", "remove", "bypassDocumentValidation"]
+ },
+ ]
+ },
+ // TODO SERVER-36832: Test with mode "replaceCollection" to a foreign database.
]
},
{
testname: "aggregate_out_insert_documents",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "insertDocuments"}}],
- cursor: {}
+ command: function(state, args) {
+ return {
+ aggregate: "foo",
+ pipeline: [{$out: {db: args.targetDB, to: "foo_out", mode: "insertDocuments"}}],
+ cursor: {},
+ bypassDocumentValidation: args.bypassDocumentValidation,
+ };
},
testcases: [
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: false},
roles: {readWrite: 1, readWriteAnyDatabase: 1, dbOwner: 1, root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
@@ -1120,99 +1170,97 @@ var authCommandsLib = {
},
{
runOnDb: secondDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: false},
roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
privileges: [
{resource: {db: secondDbName, collection: "foo"}, actions: ["find"]},
{resource: {db: secondDbName, collection: "foo_out"}, actions: ["insert"]},
]
},
- ]
- },
- {
- testname: "aggregate_out_replace_documents",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "replaceDocuments"}}],
- cursor: {}
- },
- testcases: [
{
runOnDb: firstDbName,
- roles: {readWrite: 1, readWriteAnyDatabase: 1, dbOwner: 1, root: 1, __system: 1},
- privileges: [
- {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
- {resource: {db: firstDbName, collection: "foo_out"}, actions: ["insert"]},
- {resource: {db: firstDbName, collection: "foo_out"}, actions: ["update"]},
- ]
- },
- {
- runOnDb: secondDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: false},
roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
privileges: [
- {resource: {db: secondDbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
{resource: {db: secondDbName, collection: "foo_out"}, actions: ["insert"]},
- {resource: {db: secondDbName, collection: "foo_out"}, actions: ["update"]},
]
},
- ]
- },
- {
- testname: "aggregate_out_legacy_bypass_doc_validation",
- command: {
- aggregate: "foo",
- pipeline: [{$out: "foo_out"}],
- cursor: {},
- bypassDocumentValidation: true,
- },
- testcases: [
+ // Test for bypassDocumentValidation.
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: true},
// Note that the built-in role must have 'bypassDocumentValidation' for this test.
roles: {dbOwner: 1, root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
{
resource: {db: firstDbName, collection: "foo_out"},
- actions: ["insert", "remove", "bypassDocumentValidation"]
+ actions: ["insert", "bypassDocumentValidation"]
},
]
},
- ]
- },
- {
- testname: "aggregate_out_replace_collection_bypass_doc_validation",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "replaceCollection"}}],
- cursor: {},
- bypassDocumentValidation: true,
- },
- testcases: [
+ // Test for bypassDocumentValidation to a foreign database.
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: true},
// Note that the built-in role must have 'bypassDocumentValidation' for this test.
- roles: {dbOwner: 1, root: 1, __system: 1},
+ roles: {root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
{
- resource: {db: firstDbName, collection: "foo_out"},
- actions: ["insert", "remove", "bypassDocumentValidation"]
+ resource: {db: secondDbName, collection: "foo_out"},
+ actions: ["insert", "bypassDocumentValidation"]
},
]
},
]
},
{
- testname: "aggregate_out_replace_documents_bypass_doc_validation",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "replaceDocuments"}}],
- cursor: {},
- bypassDocumentValidation: true,
+ testname: "aggregate_out_replace_documents",
+ command: function(state, args) {
+ return {
+ aggregate: "foo",
+ pipeline: [{$out: {db: args.targetDB, to: "foo_out", mode: "replaceDocuments"}}],
+ cursor: {},
+ bypassDocumentValidation: args.bypassDocumentValidation,
+ };
},
testcases: [
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: false},
+ roles: {readWrite: 1, readWriteAnyDatabase: 1, dbOwner: 1, root: 1, __system: 1},
+ privileges: [
+ {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: firstDbName, collection: "foo_out"}, actions: ["insert"]},
+ {resource: {db: firstDbName, collection: "foo_out"}, actions: ["update"]},
+ ]
+ },
+ {
+ runOnDb: secondDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: false},
+ roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
+ privileges: [
+ {resource: {db: secondDbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: secondDbName, collection: "foo_out"}, actions: ["insert"]},
+ {resource: {db: secondDbName, collection: "foo_out"}, actions: ["update"]},
+ ]
+ },
+ {
+ runOnDb: firstDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: false},
+ roles: {readWriteAnyDatabase: 1, root: 1, __system: 1},
+ privileges: [
+ {resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: secondDbName, collection: "foo_out"}, actions: ["insert"]},
+ {resource: {db: secondDbName, collection: "foo_out"}, actions: ["update"]},
+ ]
+ },
+ // Test for bypassDocumentValidation.
+ {
+ runOnDb: firstDbName,
+ commandArgs: {targetDB: firstDbName, bypassDocumentValidation: true},
// Note that the built-in role must have 'bypassDocumentValidation' for this test.
roles: {dbOwner: 1, root: 1, __system: 1},
privileges: [
@@ -1223,26 +1271,17 @@ var authCommandsLib = {
},
]
},
- ]
- },
- {
- testname: "aggregate_out_insert_documents_bypass_doc_validation",
- command: {
- aggregate: "foo",
- pipeline: [{$out: {to: "foo_out", mode: "insertDocuments"}}],
- cursor: {},
- bypassDocumentValidation: true,
- },
- testcases: [
+ // Test for bypassDocumentValidation to a foreign database.
{
runOnDb: firstDbName,
+ commandArgs: {targetDB: secondDbName, bypassDocumentValidation: true},
// Note that the built-in role must have 'bypassDocumentValidation' for this test.
- roles: {dbOwner: 1, root: 1, __system: 1},
+ roles: {root: 1, __system: 1},
privileges: [
{resource: {db: firstDbName, collection: "foo"}, actions: ["find"]},
{
- resource: {db: firstDbName, collection: "foo_out"},
- actions: ["insert", "bypassDocumentValidation"]
+ resource: {db: secondDbName, collection: "foo_out"},
+ actions: ["insert", "update", "bypassDocumentValidation"]
},
]
},
@@ -5965,11 +6004,11 @@ var authCommandsLib = {
return impls.runOneTest(conn, t);
},
- setup: function(conn, t, runOnDb) {
+ setup: function(conn, t, runOnDb, testcase) {
var adminDb = conn.getDB(adminDbName);
if (t.setup) {
adminDb.auth("admin", "password");
- var state = t.setup(runOnDb);
+ var state = t.setup(runOnDb, testcase);
runOnDb.getLastError();
adminDb.logout();
return state;