mongo/jstests/auth/role_management_commands_ed...

380 lines
13 KiB
JavaScript

/**
* This tests that all the different commands for role manipulation all properly handle invalid
* and atypical inputs.
* @tags: [requires_sharding]
*/
import {ShardingTest} from "jstests/libs/shardingtest.js";
function runTest(conn) {
let db = conn.getDB("test");
let admin = conn.getDB("admin");
admin.createUser({user: "userAdmin", pwd: "pwd", roles: ["userAdminAnyDatabase"]});
admin.auth("userAdmin", "pwd");
(function testCreateRole() {
jsTestLog("Testing createRole");
// Role with no privs
db.createRole({role: "role1", roles: [], privileges: []});
// Role with duplicate other roles
db.createRole({role: "role2", roles: ["read", "read", "role1", "role1"], privileges: []});
assert.eq(2, db.getRole("role2").roles.length);
// Role with duplicate privileges
db.createRole({
role: "role3",
roles: ["role2"],
privileges: [
{resource: {db: "test", collection: ""}, actions: ["find"]},
{resource: {db: "test", collection: ""}, actions: ["find"]},
],
});
assert.eq(1, db.getRole("role3", {showPrivileges: true}).privileges.length);
// Try to create role that already exists.
assert.throws(function () {
db.createRole({role: "role2", roles: [], privileges: []});
});
// Try to create role with no name
assert.throws(function () {
db.createRole({role: "", roles: [], privileges: []});
});
// Try to create a role the wrong types for the arguments
assert.throws(function () {
db.createRole({role: 1, roles: [], privileges: []});
});
assert.throws(function () {
db.createRole({role: ["role4", "role5"], roles: [], privileges: []});
});
assert.throws(function () {
db.createRole({role: "role6", roles: 1, privileges: []});
});
assert.throws(function () {
db.createRole({role: "role7", roles: [], privileges: 1});
});
// Try to create a role with an invalid privilege
assert.throws(function () {
db.createRole({role: "role8", roles: [], privileges: [{resource: {}, actions: ["find"]}]});
});
assert.throws(function () {
db.createRole({
role: "role9",
roles: [],
privileges: [{resource: {db: "test", collection: "foo"}, actions: []}],
});
});
assert.throws(function () {
db.createRole({
role: "role10",
roles: [],
privileges: [{resource: {db: "test"}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role11",
roles: [],
privileges: [{resource: {collection: "foo"}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role12",
roles: [],
privileges: [{resource: {anyResource: false}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role13",
roles: [],
privileges: [{resource: {db: "test", collection: "foo", cluster: true}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role14",
roles: [],
privileges: [{resource: {cluster: false}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role15",
roles: [],
privileges: [{resource: {db: "test", collection: "$cmd"}, actions: ["find"]}],
});
});
assert.throws(function () {
db.createRole({
role: "role16",
roles: [],
privileges: [{resource: {db: "test", collection: "foo"}, actions: ["fakeAction"]}],
});
});
// Try to create role containing itself in its roles array
assert.throws(function () {
db.createRole({role: "role17", roles: ["role17"], privileges: []});
});
assert.eq(3, db.getRoles().length);
})();
(function testUpdateRole() {
jsTestLog("Testing updateRole");
// Try to update role that doesn't exist
assert.throws(function () {
db.updateRole("fakeRole", {roles: []});
});
// Try to update role to have a role that doesn't exist
assert.throws(function () {
db.updateRole("role1", {roles: ["fakeRole"]});
});
// Try to update a built-in role
assert.throws(function () {
db.updateRole("read", {roles: ["readWrite"]});
});
// Try to create a cycle in the role graph
assert.throws(function () {
db.updateRole("role1", {roles: ["role1"]});
});
assert.eq(0, db.getRole("role1").roles.length);
assert.throws(function () {
db.updateRole("role1", {roles: ["role2"]});
});
assert.eq(0, db.getRole("role1").roles.length);
assert.throws(function () {
db.updateRole("role1", {roles: ["role3"]});
});
assert.eq(0, db.getRole("role1").roles.length);
})();
(function testGrantRolesToRole() {
jsTestLog("Testing grantRolesToRole");
// Grant role1 to role2 even though role2 already has role1
db.grantRolesToRole("role2", ["role1"]);
assert.eq(2, db.getRole("role2").roles.length);
// Try to grant a role that doesn't exist
assert.throws(function () {
db.grantRolesToRole("role1", ["fakeRole"]);
});
// Try to grant *to* a role that doesn't exist
assert.throws(function () {
db.grantRolesToRole("fakeRole", ["role1"]);
});
// Must specify at least 1 role
assert.throws(function () {
db.grantRolesToRole("role1", []);
});
// Try to grant to a built-in role
assert.throws(function () {
db.grantRolesToRole("read", ["role1"]);
});
// Try to create a cycle in the role graph
assert.throws(function () {
db.grantRolesToRole("role1", ["role1"]);
});
assert.eq(0, db.getRole("role1").roles.length);
assert.throws(function () {
db.grantRolesToRole("role1", ["role2"]);
});
assert.eq(0, db.getRole("role1").roles.length);
assert.throws(function () {
db.grantRolesToRole("role1", ["role3"]);
});
assert.eq(0, db.getRole("role1").roles.length);
})();
(function testRevokeRolesFromRole() {
jsTestLog("Testing revokeRolesFromRole");
// Try to revoke a role that doesn't exist
// Should not error but should do nothing.
assert.doesNotThrow(function () {
db.revokeRolesFromRole("role2", ["fakeRole"]);
});
// Try to revoke role3 from role2 even though role2 does not contain role3.
// Should not error but should do nothing.
assert.doesNotThrow(function () {
db.revokeRolesFromRole("role2", ["role3"]);
});
assert.eq(2, db.getRole("role2").roles.length);
// Must revoke something
assert.throws(function () {
db.revokeRolesFromRole("role2", []);
});
// Try to remove from built-in role
assert.throws(function () {
db.revokeRolesFromRole("readWrite", ["read"]);
});
})();
(function testGrantPrivilegesToRole() {
jsTestLog("Testing grantPrivilegesToRole");
// Must grant something
assert.throws(function () {
db.grantPrivilegesToRole("role1", []);
});
let basicPriv = {resource: {db: "test", collection: ""}, actions: ["find"]};
// Invalid first argument
assert.throws(function () {
db.grantPrivilegesToRole(["role1", "role2"], [basicPriv]);
});
// Try to grant to role that doesn't exist
assert.throws(function () {
db.grantPrivilegesToRole("fakeRole", [basicPriv]);
});
// Test with invalid privileges
let badPrivs = [];
badPrivs.push("find");
badPrivs.push({resource: {db: "test", collection: ""}, actions: ["fakeAction"]});
badPrivs.push({resource: {db: ["test"], collection: ""}, actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: ""}});
badPrivs.push({actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: ""}, actions: []});
badPrivs.push({resource: {db: "test"}, actions: ["find"]});
badPrivs.push({resource: {collection: "test"}, actions: ["find"]});
badPrivs.push({resource: {}, actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: "", cluster: true}, actions: ["find"]});
for (var i = 0; i < badPrivs.length; i++) {
assert.throws(function () {
db.grantPrivilegesToRole("role1", [badPrivs[i]]);
});
}
assert.eq(0, db.getRole("role1", {showPrivileges: true}).privileges.length);
})();
(function testRevokePrivilegesFromRole() {
jsTestLog("Testing revokePrivilegesFromRole");
// Try to revoke a privilege the role doesn't have
// Should not error but should do nothing.
assert.doesNotThrow(function () {
db.revokePrivilegesFromRole("role3", [{resource: {db: "test", collection: "foobar"}, actions: ["insert"]}]);
});
assert.eq(0, db.getRole("role2", {showPrivileges: true}).privileges.length);
// Must revoke something
assert.throws(function () {
db.revokePrivilegesFromRole("role3", []);
});
// Try to remove from built-in role
assert.throws(function () {
db.revokePrivilegesFromRole("readWrite", [{resource: {db: "test", collection: ""}, actions: ["find"]}]);
});
let basicPriv = {resource: {db: "test", collection: ""}, actions: ["find"]};
// Invalid first argument
assert.throws(function () {
db.revokePrivilegesFromRole(["role3", "role2"], [basicPriv]);
});
// Try to revoke from role that doesn't exist
assert.throws(function () {
db.revokePrivilegesToRole("fakeRole", [basicPriv]);
});
// Test with invalid privileges
let badPrivs = [];
badPrivs.push("find");
badPrivs.push({resource: {db: "test", collection: ""}, actions: ["fakeAction"]});
badPrivs.push({resource: {db: ["test"], collection: ""}, actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: ""}});
badPrivs.push({actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: ""}, actions: []});
badPrivs.push({resource: {db: "test"}, actions: ["find"]});
badPrivs.push({resource: {collection: "test"}, actions: ["find"]});
badPrivs.push({resource: {}, actions: ["find"]});
badPrivs.push({resource: {db: "test", collection: "", cluster: true}, actions: ["find"]});
for (var i = 0; i < badPrivs.length; i++) {
assert.throws(function () {
db.revokePrivilegesFromRole("role3", [badPrivs[i]]);
});
}
assert.eq(1, db.getRole("role3", {showPrivileges: true}).privileges.length);
})();
(function testRolesInfo() {
jsTestLog("Testing rolesInfo");
// Try to get role that does not exist
assert.eq(null, db.getRole("fakeRole"));
// Pass wrong type for role name
assert.throws(function () {
db.getRole(5);
});
assert.throws(function () {
db.getRole([]);
});
assert.throws(function () {
db.getRole(["role1", "role2"]);
});
})();
(function testDropRole() {
jsTestLog("Testing dropRole");
// Try to drop a role that doesn't exist
// Should not error but should do nothing
assert.doesNotThrow(function () {
db.dropRole("fakeRole");
});
// Try to drop a built-in role
assert.throws(function () {
db.dropRole("read");
});
assert.eq(3, db.getRoles().length);
})();
// dropAllRolesFromDatabase ignores its arguments, so there's nothing to test for it.
}
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();