mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-25 09:19:32 +01:00
241 lines
8.3 KiB
JavaScript
241 lines
8.3 KiB
JavaScript
// Ensure that created/updated users have the correct credentials.
|
|
// @tags: [requires_persistence]
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
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');
|
|
})();
|