138 lines
4.6 KiB
JavaScript
138 lines
4.6 KiB
JavaScript
/**
|
|
* Test that the client cannot gossip clusterTime from one replica set to another if it doesn't
|
|
* have the advanceClusterTime privilege.
|
|
*
|
|
* @tags: [
|
|
* ]
|
|
*/
|
|
|
|
(function() {
|
|
"use strict";
|
|
|
|
// Multiple users cannot be authenticated on one connection within a session.
|
|
TestData.disableImplicitSessions = true;
|
|
|
|
const kDbName = "testDb";
|
|
const kCollName = "testColl";
|
|
|
|
const kAdminUser = {
|
|
name: "admin",
|
|
pwd: "admin",
|
|
};
|
|
|
|
const kUserWithoutAdvanceClusterTimePrivilege = {
|
|
name: "cannotAdvanceClusterTime",
|
|
pwd: "pwd"
|
|
};
|
|
const kUserWithAdvanceClusterTimePrivilege = {
|
|
name: "canAdvanceClusterTime",
|
|
pwd: "pwd"
|
|
};
|
|
|
|
function createUsers(primary) {
|
|
// Create the admin user and advanceClusterTimeRole.
|
|
const adminDB = primary.getDB("admin");
|
|
assert.commandWorked(
|
|
adminDB.runCommand({createUser: kAdminUser.name, pwd: kAdminUser.pwd, roles: ["root"]}));
|
|
assert.eq(1, adminDB.auth(kAdminUser.name, kAdminUser.pwd));
|
|
assert.commandWorked(adminDB.runCommand({
|
|
createRole: "advanceClusterTimeRole",
|
|
privileges: [{resource: {cluster: true}, actions: ["advanceClusterTime"]}],
|
|
roles: []
|
|
}));
|
|
|
|
// Create one user without advanceClusterTime privilege, and one with advanceClusterTime
|
|
// privilege.
|
|
const testDB = primary.getDB(kDbName);
|
|
assert.commandWorked(testDB.runCommand({
|
|
createUser: kUserWithoutAdvanceClusterTimePrivilege.name,
|
|
pwd: kUserWithoutAdvanceClusterTimePrivilege.pwd,
|
|
roles: ["readWrite"]
|
|
}));
|
|
assert.commandWorked(testDB.runCommand({
|
|
createUser: kUserWithAdvanceClusterTimePrivilege.name,
|
|
pwd: kUserWithAdvanceClusterTimePrivilege.pwd,
|
|
roles: [{role: "advanceClusterTimeRole", db: "admin"}, "readWrite"]
|
|
}));
|
|
adminDB.logout();
|
|
}
|
|
|
|
const rst1 = new ReplSetTest({
|
|
nodes: [
|
|
{setParameter: {"failpoint.alwaysValidateClientsClusterTime": tojson({mode: "alwaysOn"})}}
|
|
],
|
|
name: "rst1",
|
|
keyFile: "jstests/libs/key1"
|
|
});
|
|
const rst2 = new ReplSetTest({nodes: 1, name: "rst2", keyFile: "jstests/libs/key2"});
|
|
|
|
rst1.startSet();
|
|
rst1.initiate();
|
|
|
|
rst2.startSet();
|
|
rst2.initiate();
|
|
|
|
const rst1Primary = rst1.getPrimary();
|
|
const rst2Primary = rst2.getPrimary();
|
|
|
|
createUsers(rst1Primary);
|
|
createUsers(rst2Primary);
|
|
|
|
const rst1TestDB = rst1Primary.getDB(kDbName);
|
|
const rst2TestDB = rst2Primary.getDB(kDbName);
|
|
|
|
// Test clusterTime gossip when the client does not have advanceClusterTime privilege.
|
|
(() => {
|
|
assert.eq(1,
|
|
rst1TestDB.auth(kUserWithoutAdvanceClusterTimePrivilege.name,
|
|
kUserWithoutAdvanceClusterTimePrivilege.pwd));
|
|
assert.eq(1,
|
|
rst2TestDB.auth(kUserWithoutAdvanceClusterTimePrivilege.name,
|
|
kUserWithoutAdvanceClusterTimePrivilege.pwd));
|
|
|
|
const rst1ClusterTime =
|
|
assert.commandWorked(rst1TestDB.runCommand({find: kCollName})).$clusterTime;
|
|
const rst2ClusterTime =
|
|
assert.commandWorked(rst2TestDB.runCommand({insert: kCollName, documents: [{_id: 0}]}))
|
|
.$clusterTime;
|
|
jsTest.log("rst1's clusterTime " + tojson(rst1ClusterTime));
|
|
jsTest.log("rst2's clusterTime " + tojson(rst2ClusterTime));
|
|
|
|
// A key's keyId is generated as the node's current clusterTime's Timestamp so it is possible
|
|
// for the keyId for rst2ClusterTime to match the key on rst1, and in that case the command
|
|
// would fail with TimeProofMismatch instead of KeyNotFound.
|
|
assert.commandFailedWithCode(
|
|
rst1TestDB.runCommand({find: kCollName, $clusterTime: rst2ClusterTime}),
|
|
[ErrorCodes.TimeProofMismatch, ErrorCodes.KeyNotFound]);
|
|
|
|
rst1TestDB.logout();
|
|
rst2TestDB.logout();
|
|
})();
|
|
|
|
// Test clusterTime gossip when the client does have advanceClusterTime privilege.
|
|
(() => {
|
|
assert.eq(1,
|
|
rst1TestDB.auth(kUserWithAdvanceClusterTimePrivilege.name,
|
|
kUserWithAdvanceClusterTimePrivilege.pwd));
|
|
assert.eq(1,
|
|
rst2TestDB.auth(kUserWithoutAdvanceClusterTimePrivilege.name,
|
|
kUserWithoutAdvanceClusterTimePrivilege.pwd));
|
|
|
|
const rst1ClusterTime =
|
|
assert.commandWorked(rst1TestDB.runCommand({find: kCollName})).$clusterTime;
|
|
const rst2ClusterTime =
|
|
assert.commandWorked(rst2TestDB.runCommand({insert: kCollName, documents: [{_id: 1}]}))
|
|
.$clusterTime;
|
|
jsTest.log("rst1's clusterTime " + tojson(rst1ClusterTime));
|
|
jsTest.log("rst2's clusterTime " + tojson(rst2ClusterTime));
|
|
|
|
assert.commandWorked(rst1TestDB.runCommand({find: kCollName, $clusterTime: rst2ClusterTime}));
|
|
|
|
rst1TestDB.logout();
|
|
rst2TestDB.logout();
|
|
})();
|
|
|
|
rst1.stopSet();
|
|
rst2.stopSet();
|
|
})();
|