mirror of https://github.com/mongodb/mongo
462 lines
18 KiB
JavaScript
462 lines
18 KiB
JavaScript
/**
|
|
* This tests that all the different commands for user manipulation all work properly for all valid
|
|
* forms of input.
|
|
*/
|
|
export function runAllUserManagementCommandsTests(conn, writeConcern) {
|
|
function hasAuthzError(result) {
|
|
assert(result instanceof WriteCommandError);
|
|
assert.eq(ErrorCodes.Unauthorized, result.code);
|
|
}
|
|
|
|
const admin = conn.getDB("admin");
|
|
|
|
admin.createUser({user: "admin", pwd: "pwd", roles: ["root"]}, writeConcern);
|
|
assert(admin.auth("admin", "pwd"));
|
|
admin.createUser(
|
|
{
|
|
user: "userAdmin",
|
|
pwd: "pwd",
|
|
roles: ["userAdminAnyDatabase"],
|
|
customData: {userAdmin: true},
|
|
},
|
|
writeConcern,
|
|
);
|
|
admin.logout();
|
|
|
|
const userAdminConn = new Mongo(conn.host);
|
|
const userAdmin = userAdminConn.getDB("admin");
|
|
assert(userAdmin.auth("userAdmin", "pwd"));
|
|
const testUserAdmin = userAdminConn.getDB("test");
|
|
testUserAdmin.createRole(
|
|
{
|
|
role: "testRole",
|
|
roles: [],
|
|
privileges: [{resource: {db: "test", collection: ""}, actions: ["viewRole"]}],
|
|
},
|
|
writeConcern,
|
|
);
|
|
userAdmin.createRole(
|
|
{
|
|
role: "adminRole",
|
|
roles: [],
|
|
privileges: [{resource: {cluster: true}, actions: ["connPoolSync"]}],
|
|
},
|
|
writeConcern,
|
|
);
|
|
|
|
const db = conn.getDB("test");
|
|
|
|
// At this point there are 2 handles to the "test" database in use - "testUserAdmin" and "db".
|
|
// "testUserAdmin" is on a connection which has been auth'd as a user with the
|
|
// 'userAdminAnyDatabase' role. This will be used for manipulating the user defined roles
|
|
// used in the test. "db" is a handle to the test database on a connection that has not
|
|
// yet been authenticated as anyone. This is the connection that will be used to log in as
|
|
// various users and test that their access control is correct.
|
|
|
|
(function testCreateUser() {
|
|
jsTestLog("Testing createUser");
|
|
|
|
testUserAdmin.createUser(
|
|
{
|
|
user: "spencer",
|
|
pwd: "pwd",
|
|
customData: {zipCode: 10028},
|
|
roles: ["readWrite", "testRole", {role: "adminRole", db: "admin"}],
|
|
},
|
|
writeConcern,
|
|
);
|
|
testUserAdmin.createUser({user: "andy", pwd: "pwd", roles: []}, writeConcern);
|
|
|
|
const user = testUserAdmin.getUser("spencer");
|
|
assert.eq(10028, user.customData.zipCode);
|
|
assert(db.auth("spencer", "pwd"));
|
|
assert.commandWorked(db.foo.insert({a: 1}));
|
|
assert.eq(1, db.foo.findOne().a);
|
|
assert.doesNotThrow(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandWorked(db.adminCommand("connPoolSync"));
|
|
|
|
db.logout();
|
|
|
|
assert(db.auth("andy", "pwd"));
|
|
hasAuthzError(db.foo.insert({a: 1}));
|
|
assert.throws(function () {
|
|
db.foo.findOne();
|
|
});
|
|
assert.throws(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
db.logout();
|
|
})();
|
|
|
|
(function testUpdateUser() {
|
|
jsTestLog("Testing updateUser");
|
|
|
|
testUserAdmin.updateUser("spencer", {pwd: "password", customData: {}}, writeConcern);
|
|
const user1 = testUserAdmin.getUser("spencer");
|
|
assert.eq(null, user1.customData.zipCode);
|
|
assert(!db.auth("spencer", "pwd"));
|
|
assert(db.auth("spencer", "password"));
|
|
|
|
testUserAdmin.updateUser("spencer", {customData: {zipCode: 10036}, roles: ["read", "testRole"]}, writeConcern);
|
|
const user = testUserAdmin.getUser("spencer");
|
|
assert.eq(10036, user.customData.zipCode);
|
|
hasAuthzError(db.foo.insert({a: 1}));
|
|
assert.eq(1, db.foo.findOne().a);
|
|
assert.eq(1, db.foo.count());
|
|
assert.doesNotThrow(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandFailedWithCode(db.adminCommand("connPoolSync"), ErrorCodes.Unauthorized);
|
|
|
|
testUserAdmin.updateUser("spencer", {roles: ["readWrite", {role: "adminRole", db: "admin"}]}, writeConcern);
|
|
assert.commandWorked(db.foo.update({}, {$inc: {a: 1}}));
|
|
assert.eq(2, db.foo.findOne().a);
|
|
assert.eq(1, db.foo.count());
|
|
assert.throws(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandWorked(db.adminCommand("connPoolSync"));
|
|
})();
|
|
|
|
(function testGrantRolesToUser() {
|
|
jsTestLog("Testing grantRolesToUser");
|
|
|
|
assert.commandFailedWithCode(db.runCommand({collMod: "foo"}), ErrorCodes.Unauthorized);
|
|
|
|
testUserAdmin.grantRolesToUser(
|
|
"spencer",
|
|
["readWrite", "dbAdmin", {role: "readWrite", db: "test"}, {role: "testRole", db: "test"}, "readWrite"],
|
|
writeConcern,
|
|
);
|
|
|
|
assert.commandWorked(db.runCommand({collMod: "foo"}));
|
|
assert.commandWorked(db.foo.update({}, {$inc: {a: 1}}));
|
|
assert.eq(3, db.foo.findOne().a);
|
|
assert.eq(1, db.foo.count());
|
|
assert.doesNotThrow(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandWorked(db.adminCommand("connPoolSync"));
|
|
})();
|
|
|
|
(function testRevokeRolesFromUser() {
|
|
jsTestLog("Testing revokeRolesFromUser");
|
|
|
|
testUserAdmin.revokeRolesFromUser(
|
|
"spencer",
|
|
[
|
|
"readWrite",
|
|
{role: "dbAdmin", db: "test2"}, // role user doesnt have
|
|
"testRole",
|
|
],
|
|
writeConcern,
|
|
);
|
|
|
|
assert.commandWorked(db.runCommand({collMod: "foo"}));
|
|
hasAuthzError(db.foo.update({}, {$inc: {a: 1}}));
|
|
assert.throws(function () {
|
|
db.foo.findOne();
|
|
});
|
|
assert.throws(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandWorked(db.adminCommand("connPoolSync"));
|
|
|
|
testUserAdmin.revokeRolesFromUser("spencer", [{role: "adminRole", db: "admin"}], writeConcern);
|
|
|
|
hasAuthzError(db.foo.update({}, {$inc: {a: 1}}));
|
|
assert.throws(function () {
|
|
db.foo.findOne();
|
|
});
|
|
assert.throws(function () {
|
|
db.getRole("testRole");
|
|
});
|
|
assert.commandFailedWithCode(db.adminCommand("connPoolSync"), ErrorCodes.Unauthorized);
|
|
})();
|
|
|
|
(function testUsersInfo() {
|
|
// Helper functions for the expected output of usersInfo, depending on the variant used.
|
|
function assertNoExtraInfo(user) {
|
|
assert(!user.credentials);
|
|
assertNoPrivilegesOrAuthRestrictions(user);
|
|
}
|
|
|
|
function assertNoPrivilegesOrAuthRestrictions(user) {
|
|
assert(!user.inheritedRoles);
|
|
assert(!user.inheritedPrivileges);
|
|
assert(!user.inheritedAuthenticationRestrictions);
|
|
assert(!user.authenticationRestrictions);
|
|
}
|
|
|
|
function assertShowCredentials(user) {
|
|
assert(user.credentials["SCRAM-SHA-1"]);
|
|
assert(user.credentials["SCRAM-SHA-256"]);
|
|
}
|
|
|
|
function assertShowPrivileges(
|
|
user,
|
|
expectedInheritedRolesLength,
|
|
expectedInheritedPrivilegesLength,
|
|
expectedInheritedAuthenticationRestrictionsLength,
|
|
) {
|
|
assert.eq(expectedInheritedRolesLength, user.inheritedRoles.length);
|
|
assert.eq(expectedInheritedPrivilegesLength, user.inheritedPrivileges.length);
|
|
assert.eq(
|
|
expectedInheritedAuthenticationRestrictionsLength,
|
|
user.inheritedAuthenticationRestrictions.length,
|
|
);
|
|
}
|
|
|
|
function assertShowAuthenticationRestrictions(
|
|
user,
|
|
expectedInheritedRolesLength,
|
|
expectedInheritedPrivilegesLength,
|
|
expectedInheritedAuthenticationRestrictionsLength,
|
|
expectedAuthenticationRestrictionsLength,
|
|
) {
|
|
assertShowPrivileges(
|
|
user,
|
|
expectedInheritedRolesLength,
|
|
expectedInheritedPrivilegesLength,
|
|
expectedInheritedAuthenticationRestrictionsLength,
|
|
);
|
|
assert.eq(expectedAuthenticationRestrictionsLength, user.authenticationRestrictions.length);
|
|
}
|
|
|
|
jsTestLog("Testing usersInfo");
|
|
|
|
jsTestLog("Running exact usersInfo with default options on username only");
|
|
let res = testUserAdmin.runCommand({usersInfo: "spencer"});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assertNoExtraInfo(res.users[0]);
|
|
|
|
jsTestLog("Running exact usersInfo with default options on username and db");
|
|
res = testUserAdmin.runCommand({usersInfo: {user: "spencer", db: "test"}});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assertNoExtraInfo(res.users[0]);
|
|
|
|
jsTestLog("Running exact usersInfo on single user with showCredentials set to true");
|
|
res = testUserAdmin.runCommand({usersInfo: {user: "spencer", db: "test"}, showCredentials: true});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assertShowCredentials(res.users[0]);
|
|
assertNoPrivilegesOrAuthRestrictions(res.users[0]);
|
|
|
|
jsTestLog("Running exact usersInfo on single user with showPrivileges set to true");
|
|
res = testUserAdmin.runCommand({usersInfo: {user: "spencer", db: "test"}, showPrivileges: true});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert(!res.users[0].credentials);
|
|
assertShowPrivileges(res.users[0], 1, 2, 0);
|
|
assert(!res.users[0].authenticationRestrictions);
|
|
|
|
jsTestLog("Running exact usersInfo on single user with showAuthenticationRestrictions set to true");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: {user: "spencer", db: "test"},
|
|
showAuthenticationRestrictions: true,
|
|
});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert(!res.users[0].credentials);
|
|
assertShowAuthenticationRestrictions(res.users[0], 1, 2, 0, 0);
|
|
|
|
jsTestLog("Running exact usersInfo on single user with showCustomData set to false");
|
|
res = testUserAdmin.runCommand({usersInfo: {user: "spencer", db: "test"}, showCustomData: false});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert(!res.users[0].customData);
|
|
assertNoExtraInfo(res.users[0]);
|
|
|
|
// This should trigger the authorization user cache.
|
|
jsTestLog("Running exact usersInfo on single user with all non-default options set");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: {user: "spencer", db: "test"},
|
|
showCredentials: true,
|
|
showPrivileges: true,
|
|
showAuthenticationRestrictions: true,
|
|
showCustomData: false,
|
|
});
|
|
printjson(res);
|
|
assert.eq(1, res.users.length);
|
|
assert(!res.users[0].customData);
|
|
assertShowCredentials(res.users[0]);
|
|
assertShowAuthenticationRestrictions(res.users[0], 1, 2, 0, 0);
|
|
|
|
// UsersInfo results are ordered alphabetically by user field then db field,
|
|
// not by user insertion order
|
|
jsTestLog("Running exact usersInfo on multiple users with default options");
|
|
res = testUserAdmin.runCommand({usersInfo: ["spencer", {user: "userAdmin", db: "admin"}]});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("spencer", res.users[0].user);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert.eq("userAdmin", res.users[1].user);
|
|
assert(res.users[1].customData.userAdmin);
|
|
res.users.forEach((user) => {
|
|
assertNoExtraInfo(user);
|
|
});
|
|
|
|
jsTestLog("Running exact usersInfo on multiple users with showCredentials set to true");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: ["spencer", {user: "userAdmin", db: "admin"}],
|
|
showCredentials: true,
|
|
});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("spencer", res.users[0].user);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert.eq("userAdmin", res.users[1].user);
|
|
assert(res.users[1].customData.userAdmin);
|
|
res.users.forEach((user) => {
|
|
assertShowCredentials(user);
|
|
assertNoPrivilegesOrAuthRestrictions(user);
|
|
});
|
|
|
|
jsTestLog("Running exact usersInfo on multiple users with showPrivileges set to true");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: ["spencer", {user: "userAdmin", db: "admin"}],
|
|
showPrivileges: true,
|
|
});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("spencer", res.users[0].user);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert(!res.users[0].credentials);
|
|
assertShowPrivileges(res.users[0], 1, 2, 0);
|
|
assert(!res.users[0].authenticationRestrictions);
|
|
assert.eq("userAdmin", res.users[1].user);
|
|
assert(res.users[1].customData.userAdmin);
|
|
assert(!res.users[1].credentials);
|
|
assertShowPrivileges(res.users[1], 1, 9, 0);
|
|
assert(!res.users[1].authenticationRestrictions);
|
|
|
|
jsTestLog("Running exact usersInfo on multiple users with showAuthenticationRestrictions set to true");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: ["spencer", {user: "userAdmin", db: "admin"}],
|
|
showAuthenticationRestrictions: true,
|
|
});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("spencer", res.users[0].user);
|
|
assert.eq(10036, res.users[0].customData.zipCode);
|
|
assert(!res.users[0].credentials);
|
|
assertShowAuthenticationRestrictions(res.users[0], 1, 2, 0, 0);
|
|
assert.eq("userAdmin", res.users[1].user);
|
|
assert(res.users[1].customData.userAdmin);
|
|
assert(!res.users[1].credentials);
|
|
assertShowAuthenticationRestrictions(res.users[1], 1, 9, 0, 0);
|
|
|
|
// This should also trigger the authorization user cache.
|
|
jsTestLog("Running exact usersInfo on multiple users with all non-default options set");
|
|
res = testUserAdmin.runCommand({
|
|
usersInfo: ["spencer", {user: "userAdmin", db: "admin"}],
|
|
showCredentials: true,
|
|
showPrivileges: true,
|
|
showAuthenticationRestrictions: true,
|
|
showCustomData: false,
|
|
});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("spencer", res.users[0].user);
|
|
assert(!res.users[0].customData);
|
|
assertShowAuthenticationRestrictions(res.users[0], 1, 2, 0, 0);
|
|
assert.eq("userAdmin", res.users[1].user);
|
|
assert(!res.users[1].customData);
|
|
assertShowAuthenticationRestrictions(res.users[1], 1, 9, 0, 0);
|
|
res.users.forEach((user) => {
|
|
assertShowCredentials(user);
|
|
});
|
|
|
|
jsTestLog("Running non-exact usersInfo on current db with all default options set");
|
|
res = testUserAdmin.runCommand({usersInfo: 1});
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("andy", res.users[0].user);
|
|
assert.eq("spencer", res.users[1].user);
|
|
assert(!res.users[0].customData);
|
|
assert.eq(10036, res.users[1].customData.zipCode);
|
|
// showPrivileges and showAuthenticationRestrictions should not be allowed on non-exact
|
|
// usersInfo queries.
|
|
assert.commandFailed(testUserAdmin.runCommand({usersInfo: 1, showPrivileges: true}));
|
|
assert.commandFailed(testUserAdmin.runCommand({usersInfo: 1, showAuthenticationRestrictions: true}));
|
|
|
|
// showCredentials and showCustomData should be allowed on non-exact usersInfo queries.
|
|
jsTestLog(
|
|
"Running non-exact usersInfo on current db with showCredentials and showCustomData set to non-defaults",
|
|
);
|
|
res = testUserAdmin.runCommand({usersInfo: 1, showCredentials: true, showCustomData: false});
|
|
printjson(res);
|
|
assert.eq(2, res.users.length);
|
|
assert.eq("andy", res.users[0].user);
|
|
assert.eq("spencer", res.users[1].user);
|
|
res.users.forEach((user) => {
|
|
assertShowCredentials(user);
|
|
assert(!user.customData);
|
|
});
|
|
|
|
res = testUserAdmin.runCommand({usersInfo: {forAllDBs: true}});
|
|
printjson(res);
|
|
assert.eq(4, res.users.length);
|
|
assert.eq("admin", res.users[0].user);
|
|
assert.eq("andy", res.users[1].user);
|
|
assert.eq("spencer", res.users[2].user);
|
|
assert.eq("userAdmin", res.users[3].user);
|
|
// showPrivileges and showAuthenticationRestrictions should not be allowed on non-exact
|
|
// usersInfo queries.
|
|
assert.commandFailed(testUserAdmin.runCommand({usersInfo: {forAllDBs: true}, showPrivileges: true}));
|
|
assert.commandFailed(
|
|
testUserAdmin.runCommand({usersInfo: {forAllDBs: true}, showAuthenticationRestrictions: true}),
|
|
);
|
|
|
|
// showCredentials and showCustomData should be allowed on non-exact usersInfo queries.
|
|
res = testUserAdmin.runCommand({usersInfo: {forAllDBs: true}, showCredentials: true, showCustomData: false});
|
|
printjson(res);
|
|
assert.eq(4, res.users.length);
|
|
assert.eq("admin", res.users[0].user);
|
|
assert.eq("andy", res.users[1].user);
|
|
assert.eq("spencer", res.users[2].user);
|
|
assert.eq("userAdmin", res.users[3].user);
|
|
res.users.forEach((user) => {
|
|
assertShowCredentials(user);
|
|
assert(!user.customData);
|
|
});
|
|
})();
|
|
|
|
(function testDropUser() {
|
|
jsTestLog("Testing dropUser");
|
|
|
|
assert(db.auth("spencer", "password"));
|
|
db.logout();
|
|
assert(db.auth("andy", "pwd"));
|
|
|
|
testUserAdmin.dropUser("spencer", writeConcern);
|
|
|
|
assert(!db.auth("spencer", "password"));
|
|
assert(db.auth("andy", "pwd"));
|
|
db.logout();
|
|
|
|
assert.eq(1, testUserAdmin.getUsers().length);
|
|
})();
|
|
|
|
(function testDropAllUsersFromDatabase() {
|
|
jsTestLog("Testing dropAllUsersFromDatabase");
|
|
|
|
assert.eq(1, testUserAdmin.getUsers().length);
|
|
assert(db.auth("andy", "pwd"));
|
|
db.logout();
|
|
|
|
testUserAdmin.dropAllUsers(writeConcern);
|
|
|
|
assert(!db.auth("andy", "pwd"));
|
|
assert.eq(0, testUserAdmin.getUsers().length);
|
|
})();
|
|
}
|