Files
mongo/jstests/core/shell/user_management_helpers.js
Enrico Golfieri b4768fe1f8 SERVER-114498 Extend the sharding_jscore_passthrough to deploy a fixture with multiple mongos (#45370)
GitOrigin-RevId: d29e8acda17aff7391bce94dba9f072de84b094d
2026-01-07 18:11:30 +00:00

153 lines
5.4 KiB
JavaScript

// This test is a basic sanity check of the shell helpers for manipulating user objects
// It is not a comprehensive test of the functionality of the user manipulation commands
//
// @tags: [
// # The test runs commands that are not allowed with security token: createUser, dropUser,
// # grantRolesToUser, logout, revokeRolesFromUser, updateUser.
// not_allowed_with_signed_security_token,
// assumes_superuser_permissions,
// assumes_write_concern_unchanged,
// creates_and_authenticates_user,
// requires_auth,
// requires_non_retryable_commands,
// ]
// Running this test against multiple mongoses has high chance of authentication failures.
// Every mongos proactively discovers new passwords for users by refreshing its cache via polling against the config servers.
// The authentication might happen too early, before the refresh occurs.
// pinToSingleMongos due to updateUser command.
TestData.pinToSingleMongos = true;
function assertHasRole(rolesArray, roleName, roleDB) {
for (let i in rolesArray) {
const curRole = rolesArray[i];
if (curRole.role == roleName && curRole.db == roleDB) {
return;
}
}
assert(false, "role " + roleName + "@" + roleDB + " not found in array: " + tojson(rolesArray));
}
function runTest(db) {
db.dropDatabase();
db.dropAllUsers();
db.createUser({user: "spencer", pwd: "password", roles: ["readWrite"]});
db.createUser({user: "andy", pwd: "password", roles: ["readWrite"]});
// Test getUser
let userObj = db.getUser("spencer");
assert.eq(1, userObj.roles.length);
assertHasRole(userObj.roles, "readWrite", db.getName());
// Test getUsers
let users = db.getUsers();
assert.eq(2, users.length);
assert(users[0].user == "spencer" || users[1].user == "spencer");
assert(users[0].user == "andy" || users[1].user == "andy");
assert.eq(1, users[0].roles.length);
assert.eq(1, users[1].roles.length);
assertHasRole(users[0].roles, "readWrite", db.getName());
assertHasRole(users[1].roles, "readWrite", db.getName());
// Granting roles to nonexistent user fails
assert.throws(function () {
db.grantRolesToUser("fakeUser", ["dbAdmin"]);
});
// Granting non-existant role fails
assert.throws(function () {
db.grantRolesToUser("spencer", ["dbAdmin", "fakeRole"]);
});
userObj = db.getUser("spencer");
assert.eq(1, userObj.roles.length);
assertHasRole(userObj.roles, "readWrite", db.getName());
// Granting a role you already have is no problem
db.grantRolesToUser("spencer", ["readWrite", "dbAdmin"]);
userObj = db.getUser("spencer");
assert.eq(2, userObj.roles.length);
assertHasRole(userObj.roles, "readWrite", db.getName());
assertHasRole(userObj.roles, "dbAdmin", db.getName());
// Revoking roles the user doesn't have is fine
db.revokeRolesFromUser("spencer", ["dbAdmin", "read"]);
userObj = db.getUser("spencer");
assert.eq(1, userObj.roles.length);
assertHasRole(userObj.roles, "readWrite", db.getName());
// Update user
db.updateUser("spencer", {customData: {hello: "world"}, roles: ["read"]});
userObj = db.getUser("spencer");
assert.eq("world", userObj.customData.hello);
assert.eq(1, userObj.roles.length);
assertHasRole(userObj.roles, "read", db.getName());
// Test dropUser
db.dropUser("andy");
assert.eq(null, db.getUser("andy"));
// Test dropAllUsers
db.dropAllUsers();
assert.eq(0, db.getUsers().length);
// Test password digestion
assert.throws(function () {
db.createUser({user: "user1", pwd: "x", roles: [], digestPassword: true});
});
assert.throws(function () {
db.createUser({user: "user1", pwd: "x", roles: [], digestPassword: false});
});
assert.throws(function () {
db.createUser({user: "user1", pwd: "x", roles: [], passwordDigestor: "foo"});
});
db.createUser({user: "user1", pwd: "x", roles: [], passwordDigestor: "server"});
assert(db.auth("user1", "x"));
assert.throws(function () {
db.updateUser("user1", {pwd: "y", digestPassword: true});
});
assert.throws(function () {
db.updateUser("user1", {pwd: "y", digestPassword: false});
});
assert.throws(function () {
db.updateUser("user1", {pwd: "y", passwordDigestor: "foo"});
});
// Change password and reauth using new credentials.
db.updateUser("user1", {pwd: "y", passwordDigestor: "server"});
assert(db.auth("user1", "y"));
db.logout();
// Note that as of SERVER-32974, client-side digestion is only permitted under the SCRAM-SHA-1
// mechanism.
db.createUser({
user: "user2",
pwd: "x",
roles: [],
mechanisms: ["SCRAM-SHA-1"],
passwordDigestor: "client",
});
assert(db.auth("user2", "x"));
db.updateUser("user2", {pwd: "y", mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"});
assert(db.auth("user2", "y"));
db.logout();
// Test createUser requires 'user' field
assert.throws(function () {
db.createUser({pwd: "x", roles: ["dbAdmin"]});
});
// Test createUser disallows 'createUser' field
assert.throws(function () {
db.createUser({createUser: "ben", pwd: "x", roles: ["dbAdmin"]});
});
}
try {
runTest(db.getSiblingDB("user_management_helpers"));
} catch (x) {
// BF-836 Print current users on failure to aid debugging
db.getSiblingDB("admin").system.users.find().forEach(printjson);
throw x;
}