Files
mongo/jstests/auth/commands_builtin_roles.js
2015-07-22 14:17:20 -04:00

173 lines
5.5 KiB
JavaScript

/*
Exhaustive test for authorization of commands with builtin roles.
The test logic implemented here operates on the test cases defined
in jstests/auth/commands.js.
*/
load("jstests/auth/lib/commands_lib.js");
var roles = [
{key: "read", role: "read", dbname: firstDbName},
{key: "readAnyDatabase", role: "readAnyDatabase", dbname: adminDbName},
{key: "readWrite", role: "readWrite", dbname: firstDbName},
{key: "readWriteAnyDatabase", role: "readWriteAnyDatabase", dbname: adminDbName},
{key: "userAdmin", role: "userAdmin", dbname: firstDbName},
{key: "userAdminAnyDatabase", role: "userAdminAnyDatabase", dbname: adminDbName},
{key: "dbAdmin", role: "dbAdmin", dbname: firstDbName},
{key: "dbAdminAnyDatabase", role: "dbAdminAnyDatabase", dbname: adminDbName},
{key: "clusterAdmin", role: "clusterAdmin", dbname: adminDbName},
{key: "dbOwner", role: "dbOwner", dbname: firstDbName},
{key: "clusterMonitor", role: "clusterMonitor", dbname: adminDbName},
{key: "hostManager", role: "hostManager", dbname: adminDbName},
{key: "clusterManager", role: "clusterManager", dbname: adminDbName},
{key: "backup", role: "backup", dbname: adminDbName},
{key: "restore", role: "restore", dbname: adminDbName},
{key: "root", role: "root", dbname: adminDbName},
{key: "__system", role: "__system", dbname: adminDbName}
];
/**
* Parameters:
* conn -- connection, either to standalone mongod,
* or to mongos in sharded cluster
* t -- a test object from the tests array in jstests/auth/commands.js
* testcase -- the particular testcase from t to test
* r -- a role object from the "roles" array above
*
* Returns:
* An empty string on success, or an error string
* on test failure.
*/
function testProperAuthorization(conn, t, testcase, r) {
var out = "";
var runOnDb = conn.getDB(testcase.runOnDb);
authCommandsLib.setup(conn, t, runOnDb);
assert(r.db.auth("user|" + r.role, "password"));
var res = runOnDb.runCommand(t.command);
if (testcase.roles[r.role]) {
if (res.ok == 0 && res.code == authErrCode) {
out = "expected authorization success" +
" but received " + tojson(res) +
" on db " + testcase.runOnDb +
" with role " + r.key;
}
else if (res.ok == 0 && !testcase.expectFail && res.code != commandNotSupportedCode) {
// don't error if the test failed with code commandNotSupported since
// some storage engines (e.g wiredTiger) don't support some commands (e.g. touch)
out = "command failed with " + tojson(res) +
" on db " + testcase.runOnDb +
" with role " + r.key;
}
// test can provide a function that will run if
// the command completed successfully
else if (testcase.onSuccess) {
testcase.onSuccess(res);
}
}
else {
if (res.ok == 1 || (res.ok == 0 && res.code != authErrCode)) {
out = "expected authorization failure" +
" but received result " + tojson(res) +
" on db " + testcase.runOnDb +
" with role " + r.key;
}
}
r.db.logout();
authCommandsLib.teardown(conn, t, runOnDb);
return out;
}
function runOneTest(conn, t) {
var failures = [];
for (var i = 0; i < t.testcases.length; i++) {
var testcase = t.testcases[i];
if (!("roles" in testcase)) {
continue;
}
for (var j = 0; j < roles.length; j++) {
var msg = testProperAuthorization(conn, t, testcase, roles[j]);
if (msg) {
failures.push(t.testname + ": " + msg);
}
}
}
return failures;
}
function createUsers(conn) {
var adminDb = conn.getDB(adminDbName);
adminDb.createUser({
user: "admin",
pwd: "password",
roles: ["__system"]
});
assert(adminDb.auth("admin", "password"));
for (var i = 0; i < roles.length; i++) {
r = roles[i];
r.db = conn.getDB(r.dbname);
r.db.createUser({user: "user|" + r.role, pwd: "password", roles: [r.role]});
}
adminDb.logout();
}
/*
* Makes sure that none of the test cases reference roles
* that aren't part of the global "roles" array.
*/
function checkForNonExistentRoles() {
var tests = authCommandsLib.tests;
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
for (var j = 0; j < test.testcases.length; j++) {
var testcase = test.testcases[j];
for (role in testcase.roles) {
var roleExists = false;
for (var k = 0; k < roles.length; k++) {
if (roles[k].role === role) {
roleExists = true;
break;
}
}
assert(roleExists, "Role " + role + " found in test: " + test.testname +
", but doesn't exist in roles array");
}
}
}
}
var opts = {
auth:"",
enableExperimentalStorageDetailsCmd: ""
}
var impls = {
createUsers: createUsers,
runOneTest: runOneTest
}
checkForNonExistentRoles();
// run all tests standalone
var conn = MongoRunner.runMongod(opts);
authCommandsLib.runTests(conn, impls);
MongoRunner.stopMongod(conn);
// run all tests sharded
conn = new ShardingTest({
shards: 2,
mongos: 1,
keyFile: "jstests/libs/key1",
other: { shardOptions: opts }
});
authCommandsLib.runTests(conn, impls);
conn.stop();