mirror of https://github.com/mongodb/mongo
227 lines
8.2 KiB
JavaScript
227 lines
8.2 KiB
JavaScript
// Ensure that created/updated users have the correct credentials.
|
|
// @tags: [requires_persistence]
|
|
|
|
let mongod = MongoRunner.runMongod({
|
|
auth: "",
|
|
setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN",
|
|
});
|
|
const admin = mongod.getDB("admin");
|
|
const test = mongod.getDB("test");
|
|
|
|
function checkUser(userid, passwd, haveSCRAMSHA1, haveSCRAMSHA256) {
|
|
function checkCredentialRecord(creds, hashLen, saltLen, itCount) {
|
|
assert.eq(creds.iterationCount, itCount);
|
|
assert.eq(creds.salt.length, saltLen);
|
|
assert.eq(creds.storedKey.length, hashLen);
|
|
assert.eq(creds.serverKey.length, hashLen);
|
|
}
|
|
function checkLogin(mech, digestOK, nodigestOK) {
|
|
assert(test.auth({user: userid, pwd: passwd, mechanism: mech}));
|
|
test.logout();
|
|
assert.eq(digestOK, test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: true}));
|
|
if (digestOK) {
|
|
test.logout();
|
|
}
|
|
assert.eq(nodigestOK, test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: false}));
|
|
if (nodigestOK) {
|
|
test.logout();
|
|
}
|
|
}
|
|
|
|
assert(admin.auth("admin", "pass"));
|
|
const user = admin.system.users.findOne({_id: "test." + userid});
|
|
assert.eq(user.credentials.hasOwnProperty("SCRAM-SHA-1"), haveSCRAMSHA1);
|
|
assert.eq(user.credentials.hasOwnProperty("SCRAM-SHA-256"), haveSCRAMSHA256);
|
|
|
|
// usersInfo contains correct mechanisms for the user
|
|
const userInfo = assert.commandWorked(test.runCommand({usersInfo: userid}));
|
|
assert(Array.isArray(userInfo.users[0].mechanisms));
|
|
assert.eq(userInfo.users[0].mechanisms.includes("SCRAM-SHA-1"), haveSCRAMSHA1);
|
|
assert.eq(userInfo.users[0].mechanisms.includes("SCRAM-SHA-256"), haveSCRAMSHA256);
|
|
|
|
// usersInfo with showCredentials shows correct mechanisms and credentials
|
|
const userInfoWithCredentials = assert.commandWorked(test.runCommand({usersInfo: userid, showCredentials: true}));
|
|
print(tojson(userInfoWithCredentials));
|
|
assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty("SCRAM-SHA-1"), haveSCRAMSHA1);
|
|
assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty("SCRAM-SHA-256"), haveSCRAMSHA256);
|
|
assert(Array.isArray(userInfoWithCredentials.users[0].mechanisms));
|
|
assert.eq(userInfoWithCredentials.users[0].mechanisms.includes("SCRAM-SHA-1"), haveSCRAMSHA1);
|
|
assert.eq(userInfoWithCredentials.users[0].mechanisms.includes("SCRAM-SHA-256"), haveSCRAMSHA256);
|
|
admin.logout();
|
|
|
|
if (haveSCRAMSHA1) {
|
|
checkCredentialRecord(user.credentials["SCRAM-SHA-1"], 28, 24, 10000);
|
|
checkLogin("SCRAM-SHA-1", true, false);
|
|
checkLogin("PLAIN", false, true);
|
|
}
|
|
if (haveSCRAMSHA256) {
|
|
checkCredentialRecord(user.credentials["SCRAM-SHA-256"], 44, 40, 15000);
|
|
checkLogin("SCRAM-SHA-256", false, true);
|
|
checkLogin("PLAIN", false, true);
|
|
}
|
|
}
|
|
|
|
admin.createUser({user: "admin", pwd: "pass", roles: jsTest.adminUserRoles});
|
|
assert(admin.auth("admin", "pass"));
|
|
|
|
function createUser(db, user) {
|
|
assert(admin.auth("admin", "pass"));
|
|
db.createUser(user);
|
|
admin.logout();
|
|
}
|
|
|
|
function createUserThrows(db, user) {
|
|
assert(admin.auth("admin", "pass"));
|
|
assert.throws(() => db.createUser(user));
|
|
admin.logout();
|
|
}
|
|
|
|
// Unknown mechanism.
|
|
createUserThrows(test, {
|
|
user: "shalala",
|
|
pwd: "pass",
|
|
roles: jsTest.basicUserRoles,
|
|
mechanisms: ["SCRAM-SHA-1", "SCRAM-SHA-LA-LA"],
|
|
});
|
|
|
|
// By default, users are created with both SCRAM variants.
|
|
createUser(test, {user: "user", pwd: "pass", roles: jsTest.basicUserRoles});
|
|
checkUser("user", "pass", true, true);
|
|
|
|
// Request SHA1 only.
|
|
createUser(test, {user: "sha1user", pwd: "pass", roles: jsTest.basicUserRoles, mechanisms: ["SCRAM-SHA-1"]});
|
|
checkUser("sha1user", "pass", true, false);
|
|
|
|
// Request SHA256 only.
|
|
createUser(test, {user: "sha256user", pwd: "pass", roles: jsTest.basicUserRoles, mechanisms: ["SCRAM-SHA-256"]});
|
|
checkUser("sha256user", "pass", false, true);
|
|
|
|
// Fail passing an empty mechanisms field.
|
|
createUserThrows(test, {user: "userNoMech", pwd: "pass", roles: jsTest.basicUserRoles, mechanisms: []});
|
|
|
|
// Repeat above, but request client-side digesting.
|
|
// Only the SCRAM-SHA-1 exclusive version should succeed.
|
|
|
|
createUserThrows(test, {user: "user2", pwd: "pass", roles: jsTest.basicUserRoles, passwordDisgestor: "client"});
|
|
|
|
createUser(test, {
|
|
user: "sha1user2",
|
|
pwd: "pass",
|
|
roles: jsTest.basicUserRoles,
|
|
mechanisms: ["SCRAM-SHA-1"],
|
|
passwordDigestor: "client",
|
|
});
|
|
checkUser("sha1user2", "pass", true, false);
|
|
|
|
createUserThrows(test, {
|
|
user: "sha256user2",
|
|
pwd: "pass",
|
|
roles: jsTest.basicUserRoles,
|
|
mechanisms: ["SCRAM-SHA-256"],
|
|
passwordDigestor: "client",
|
|
});
|
|
|
|
function updateUser(db, user, props) {
|
|
assert(admin.auth("admin", "pass"));
|
|
db.updateUser(user, props);
|
|
admin.logout();
|
|
}
|
|
|
|
function updateUserThrows(db, user, props) {
|
|
assert(admin.auth("admin", "pass"));
|
|
assert.throws(() => db.updateUser(user, props));
|
|
admin.logout();
|
|
}
|
|
|
|
// Update original 1/256 user to just sha-1.
|
|
updateUser(test, "user", {pwd: "pass1", mechanisms: ["SCRAM-SHA-1"]});
|
|
checkUser("user", "pass1", true, false);
|
|
|
|
// Then flip to 256-only
|
|
updateUser(test, "user", {pwd: "pass256", mechanisms: ["SCRAM-SHA-256"]});
|
|
checkUser("user", "pass256", false, true);
|
|
|
|
// And back to (default) all.
|
|
updateUser(test, "user", {pwd: "passAll"});
|
|
checkUser("user", "passAll", true, true);
|
|
|
|
// Trim out mechanisms without changing password.
|
|
updateUser(test, "user", {mechanisms: ["SCRAM-SHA-256"]});
|
|
checkUser("user", "passAll", false, true);
|
|
|
|
// Fail when mechanisms is not a subset of the current user.
|
|
updateUserThrows(test, "user", {mechanisms: ["SCRAM-SHA-1"]});
|
|
|
|
// Fail when passing an empty mechanisms field.
|
|
updateUserThrows(test, "user", {pwd: "passEmpty", mechanisms: []});
|
|
|
|
// Succeed if we're using SHA-1 only.
|
|
createUser(test, {user: "\u2168", pwd: "pass", roles: jsTest.basicUserRoles, mechanisms: ["SCRAM-SHA-1"]});
|
|
checkUser("\u2168", "pass", true, false);
|
|
|
|
assert(admin.auth("admin", "pass"));
|
|
|
|
// Demonstrate that usersInfo returns all users with mechanisms lists
|
|
const allUsersInfo = assert.commandWorked(test.runCommand({usersInfo: 1}));
|
|
allUsersInfo.users.forEach(function (userObj) {
|
|
assert(Array.isArray(userObj.mechanisms));
|
|
});
|
|
|
|
// Demonstrate that usersInfo can return all users with credentials
|
|
const allUsersInfoWithCredentials = assert.commandWorked(test.runCommand({usersInfo: 1, showCredentials: true}));
|
|
allUsersInfoWithCredentials.users.forEach(function (userObj) {
|
|
assert(userObj.credentials !== undefined);
|
|
assert(!Array.isArray(userObj.credentials));
|
|
assert(userObj.mechanisms !== undefined);
|
|
assert(Array.isArray(userObj.mechanisms));
|
|
});
|
|
|
|
// Demonstrate that usersInfo can find SCRAM-SHA-1 users
|
|
const allSCRAMSHA1UsersInfo = assert.commandWorked(
|
|
test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-1"}}),
|
|
);
|
|
let foundUsers = [];
|
|
allSCRAMSHA1UsersInfo.users.forEach(function (userObj) {
|
|
foundUsers.push(userObj.user);
|
|
});
|
|
assert.eq(["sha1user", "sha1user2", "\u2168"], foundUsers);
|
|
|
|
// Demonstrate that usersInfo can find SCRAM-SHA-256 users
|
|
const allSCRAMSHA256UsersInfo = assert.commandWorked(
|
|
test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-256"}}),
|
|
);
|
|
foundUsers = [];
|
|
allSCRAMSHA256UsersInfo.users.forEach(function (userObj) {
|
|
foundUsers.push(userObj.user);
|
|
});
|
|
assert.eq(["sha256user", "user"], foundUsers);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
|
|
// Ensure mechanisms can be enabled and disabled.
|
|
function restartWithOneMech(mech) {
|
|
const sha1ok = mech === "SCRAM-SHA-1";
|
|
const sha256ok = mech === "SCRAM-SHA-256";
|
|
mongod = MongoRunner.runMongod({
|
|
auth: "",
|
|
setParameter: "authenticationMechanisms=" + mech,
|
|
restart: mongod,
|
|
noCleanData: true,
|
|
});
|
|
|
|
const test = mongod.getDB("test");
|
|
assert.eq(test.auth("sha1user", "pass"), sha1ok);
|
|
if (sha1ok) {
|
|
test.logout();
|
|
}
|
|
assert.eq(test.auth("sha256user", "pass"), sha256ok);
|
|
if (sha256ok) {
|
|
test.logout();
|
|
}
|
|
assert(mongod.getDB("admin").auth("admin", "pass"));
|
|
MongoRunner.stopMongod(mongod);
|
|
}
|
|
|
|
restartWithOneMech("SCRAM-SHA-1");
|
|
restartWithOneMech("SCRAM-SHA-256");
|