mongo/jstests/auth/authz_modifications_access_...

313 lines
12 KiB
JavaScript

/**
* This tests that the proper access control is enforced around modifications to user and role data.
* @tags: [requires_sharding]
*/
import {ShardingTest} from "jstests/libs/shardingtest.js";
function runTest(conn) {
let authzErrorCode = 13;
conn.getDB("admin").createUser({user: "userAdmin", pwd: "pwd", roles: ["userAdminAnyDatabase"]});
let userAdminConn = new Mongo(conn.host);
userAdminConn.getDB("admin").auth("userAdmin", "pwd");
let testUserAdmin = userAdminConn.getDB("test");
let adminUserAdmin = userAdminConn.getDB("admin");
testUserAdmin.createRole({role: "testRole", roles: [], privileges: []});
adminUserAdmin.createRole({role: "adminRole", roles: [], privileges: []});
testUserAdmin.createUser({user: "spencer", pwd: "pwd", roles: ["testRole", {role: "adminRole", db: "admin"}]});
adminUserAdmin.createUser({user: "otherUser", pwd: "pwd", roles: []});
var db = conn.getDB("test");
db.auth("spencer", "pwd");
let admindb = conn.getDB("admin");
// "adminUserAdmin" and "testUserAdmin" are handles to the "admin" and "test" dbs, respectively.
// Both are on the same connection, which has been auth'd as a user with 'userAdminAnyDatabase'.
// "db" and "admindb" are also handles to the "test" and "admin" dbs, but on a connection that
// has been auth'd as the user spencer@test. "testUserAdmin" and "adminUserAdmin" will be used
// to control what privileges spencer@test has (and thus are usable by "db" and "admindb"),
// while "db" and "admindb" will be used for the actual permission checks that are being tested.
(function testCreateUser() {
jsTestLog("Testing user creation");
let res = db.runCommand({createUser: "andy", pwd: "pwd", roles: []});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["createUser"]},
]);
assert.commandWorked(db.runCommand({createUser: "andy", pwd: "pwd", roles: []}));
res = admindb.runCommand({createUser: "andy", pwd: "pwd", roles: []});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function testCreateRole() {
jsTestLog("Testing role creation");
let res = db.runCommand({createRole: "testRole2", roles: [], privileges: []});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["createRole"]},
]);
assert.commandWorked(db.runCommand({createRole: "testRole2", roles: [], privileges: []}));
res = admindb.runCommand({createRole: "testRole2", roles: [], privileges: []});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function () {
jsTestLog("Testing role creation, of user-defined roles with same name as built-in roles");
let cmdObj = {createRole: "readWrite", roles: [], privileges: []};
let res = adminUserAdmin.runCommand(cmdObj);
assert.commandFailed(res, tojson(cmdObj));
let roleObj = adminUserAdmin.system.roles.findOne({role: "readWrite", db: "admin"});
// double check that no role object named "readWrite" has been created
assert(!roleObj, 'user-defined "readWrite" role was created: ' + tojson(roleObj));
})();
(function testViewUser() {
jsTestLog("Testing viewing user information");
let res = db.runCommand({usersInfo: "andy"});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["viewUser"]},
]);
assert.commandWorked(db.runCommand({usersInfo: "andy"}));
res = admindb.runCommand({usersInfo: "andy"});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function testViewRole() {
jsTestLog("Testing viewing role information");
let res = db.runCommand({rolesInfo: "testRole2"});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["viewRole"]},
]);
assert.commandWorked(db.runCommand({rolesInfo: "testRole2"}));
res = admindb.runCommand({rolesInfo: "testRole2"});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function testDropUser() {
jsTestLog("Testing dropping user");
let res = db.runCommand({dropUser: "andy"});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["dropUser"]},
]);
assert.commandWorked(db.runCommand({dropUser: "andy"}));
res = admindb.runCommand({dropUser: "andy"});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function testDropRole() {
jsTestLog("Testing dropping role");
let res = db.runCommand({dropRole: "testRole2"});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["dropRole"]},
]);
assert.commandWorked(db.runCommand({dropRole: "testRole2"}));
res = admindb.runCommand({dropRole: "testRole2"});
assert.commandFailedWithCode(res, authzErrorCode);
})();
(function testGrantRole() {
jsTestLog("Testing granting roles");
let res = db.runCommand({createUser: "andy", pwd: "pwd", roles: ["read"]});
assert.commandFailedWithCode(res, authzErrorCode);
res = db.runCommand({grantRolesToUser: "spencer", roles: ["read"]});
assert.commandFailedWithCode(res, authzErrorCode);
res = db.runCommand({grantRolesToRole: "testRole", roles: ["read"]});
assert.commandFailedWithCode(res, authzErrorCode);
res = admindb.runCommand({grantRolesToUser: "otherUser", roles: [{role: "read", db: "test"}]});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["grantRole"]},
]);
assert.commandWorked(db.runCommand({createUser: "andy", pwd: "pwd", roles: ["read"]}));
assert.commandWorked(db.runCommand({grantRolesToUser: "spencer", roles: ["read"]}));
assert.commandWorked(db.runCommand({grantRolesToRole: "testRole", roles: ["read"]}));
// Granting roles from other dbs should fail
res = db.runCommand({grantRolesToUser: "spencer", roles: [{role: "read", db: "other"}]});
assert.commandFailedWithCode(res, authzErrorCode);
// Granting roles from this db to users in another db, however, should work
res = admindb.runCommand({grantRolesToUser: "otherUser", roles: [{role: "read", db: "test"}]});
assert.commandWorked(res);
})();
(function testRevokeRole() {
jsTestLog("Testing revoking roles");
let res = db.runCommand({revokeRolesFromUser: "spencer", roles: ["read"]});
assert.commandFailedWithCode(res, authzErrorCode);
res = db.runCommand({revokeRolesFromRole: "testRole", roles: ["read"]});
assert.commandFailedWithCode(res, authzErrorCode);
res = admindb.runCommand({revokeRolesFromUser: "otherUser", roles: [{role: "read", db: "test"}]});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["revokeRole"]},
]);
assert.commandWorked(db.runCommand({revokeRolesFromUser: "spencer", roles: ["read"]}));
assert.commandWorked(db.runCommand({revokeRolesFromRole: "testRole", roles: ["read"]}));
// Revoking roles from other dbs should fail
res = db.runCommand({revokeRolesFromUser: "spencer", roles: [{role: "read", db: "other"}]});
assert.commandFailedWithCode(res, authzErrorCode);
// Revoking roles from this db from users in another db, however, should work
res = admindb.runCommand({revokeRolesFromUser: "otherUser", roles: [{role: "read", db: "test"}]});
assert.commandWorked(res);
})();
(function testGrantPrivileges() {
jsTestLog("Testing granting privileges");
testUserAdmin.revokePrivilegesFromRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["grantRole"]},
]);
let res = db.runCommand({
createRole: "testRole2",
roles: [],
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
res = db.runCommand({
grantPrivilegesToRole: "testRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
res = admindb.runCommand({
grantPrivilegesToRole: "adminRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["grantRole"]},
]);
res = db.runCommand({
createRole: "testRole2",
roles: [],
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandWorked(res);
res = db.runCommand({
grantPrivilegesToRole: "testRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandWorked(res);
// Granting privileges from other dbs should fail
res = db.runCommand({
grantPrivilegesToRole: "testRole",
privileges: [{resource: {db: "other", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
// Granting privileges from this db to users in another db, however, should work
res = admindb.runCommand({
grantPrivilegesToRole: "adminRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandWorked(res);
})();
(function testRevokePrivileges() {
jsTestLog("Testing revoking privileges");
testUserAdmin.revokePrivilegesFromRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["revokeRole"]},
]);
let res = db.runCommand({
revokePrivilegesFromRole: "testRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
res = admindb.runCommand({
revokePrivilegesFromRole: "adminRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
testUserAdmin.grantPrivilegesToRole("testRole", [
{resource: {db: "test", collection: ""}, actions: ["revokeRole"]},
]);
res = db.runCommand({
revokePrivilegesFromRole: "testRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandWorked(res);
// Revoking privileges from other dbs should fail
res = db.runCommand({
revokePrivilegesFromRole: "testRole",
privileges: [{resource: {db: "other", collection: ""}, actions: ["find"]}],
});
assert.commandFailedWithCode(res, authzErrorCode);
// Granting privileges from this db to users in another db, however, should work
res = admindb.runCommand({
revokePrivilegesFromRole: "adminRole",
privileges: [{resource: {db: "test", collection: ""}, actions: ["find"]}],
});
assert.commandWorked(res);
})();
}
jsTest.log("Test standalone");
let conn = MongoRunner.runMongod({auth: ""});
runTest(conn);
MongoRunner.stopMongod(conn);
jsTest.log("Test sharding");
let st = new ShardingTest({shards: 2, config: 3, keyFile: "jstests/libs/key1"});
runTest(st.s);
st.stop();