142 lines
6.7 KiB
JavaScript
142 lines
6.7 KiB
JavaScript
/**
|
|
* This tests that user defined roles actually grant users the ability to perform the actions they
|
|
* should, and that changing the privileges assigned to roles changes the access granted to the user
|
|
*/
|
|
|
|
function runTest(conn) {
|
|
var authzErrorCode = 13;
|
|
var hasAuthzError = function(result) {
|
|
assert(result.hasWriteError());
|
|
assert.eq(authzErrorCode, result.getWriteError().code);
|
|
};
|
|
|
|
conn.getDB('admin').createUser({user: 'admin', pwd: 'pwd', roles: ['root']});
|
|
conn.getDB('admin').auth('admin', 'pwd');
|
|
conn.getDB('admin').createUser({user: 'userAdmin',
|
|
pwd: 'pwd',
|
|
roles: ['userAdminAnyDatabase']});
|
|
conn.getDB('admin').logout();
|
|
|
|
var userAdminConn = new Mongo(conn.host);
|
|
var adminUserAdmin = userAdminConn.getDB('admin');
|
|
adminUserAdmin.auth('userAdmin', 'pwd');
|
|
adminUserAdmin.createRole({role: 'adminRole', privileges:[], roles:[]});
|
|
var testUserAdmin = userAdminConn.getDB('test');
|
|
testUserAdmin.createRole({role: 'testRole1', privileges:[], roles:[]});
|
|
testUserAdmin.createRole({role: 'testRole2', privileges:[], roles:['testRole1']});
|
|
testUserAdmin.createUser({user: 'testUser',
|
|
pwd: 'pwd',
|
|
roles: ['testRole2', {role: 'adminRole', db: 'admin'}]});
|
|
|
|
var testDB = conn.getDB('test');
|
|
assert(testDB.auth('testUser', 'pwd'));
|
|
|
|
// At this point there are 3 db handles in use. testUserAdmin and adminUserAdmin are handles to
|
|
// the "test" and "admin" dbs respectively. Both testUserAdmin and adminUserAdmin are on the
|
|
// same connection (userAdminConn) which has been auth'd as a user with the
|
|
// 'userAdminAnyDatabase' role. Those will be used for manipulating the user defined roles
|
|
// used in the test. "testDB" is a handle to the test database on a connection that has been
|
|
// auth'd as 'testUser@test' - this is the connection that will be used to test how privilege
|
|
// enforcement works.
|
|
|
|
|
|
// test CRUD
|
|
hasAuthzError(testDB.foo.insert({ a: 1 }));
|
|
assert.throws(function() { testDB.foo.findOne()});
|
|
|
|
testUserAdmin.grantPrivilegesToRole('testRole1', [{resource: {db: 'test', collection: ''},
|
|
actions:['find']}]);
|
|
|
|
hasAuthzError(testDB.foo.insert({ a: 1 }));
|
|
assert.doesNotThrow(function() { testDB.foo.findOne()});
|
|
assert.eq(0, testDB.foo.count());
|
|
assert.eq(0, testDB.foo.find().itcount());
|
|
|
|
testUserAdmin.grantPrivilegesToRole('testRole1', [{resource: {db: 'test', collection: 'foo'},
|
|
actions:['insert']}]);
|
|
|
|
assert.writeOK(testDB.foo.insert({ a: 1 }));
|
|
assert.eq(1, testDB.foo.findOne().a)
|
|
assert.eq(1, testDB.foo.count());
|
|
assert.eq(1, testDB.foo.find().itcount());
|
|
hasAuthzError(testDB.foo.update({ a: 1 }, { $inc: { a: 1 }}));
|
|
assert.eq(1, testDB.foo.findOne().a)
|
|
|
|
hasAuthzError(testDB.bar.insert({ a: 1 }));
|
|
assert.eq(0, testDB.bar.count());
|
|
|
|
adminUserAdmin.grantPrivilegesToRole('adminRole', [{resource: {db: '', collection: 'foo'},
|
|
actions:['update']}]);
|
|
assert.writeOK(testDB.foo.update({ a: 1 }, { $inc: { a: 1 }}));
|
|
assert.eq(2, testDB.foo.findOne().a)
|
|
assert.writeOK(testDB.foo.update({ b: 1 }, { $inc: { b: 1 }}, true)); // upsert
|
|
assert.eq(2, testDB.foo.count());
|
|
assert.eq(2, testDB.foo.findOne({b: {$exists: true}}).b);
|
|
hasAuthzError(testDB.foo.remove({ b: 2 }));
|
|
assert.eq(2, testDB.foo.count());
|
|
|
|
adminUserAdmin.grantPrivilegesToRole('adminRole', [{resource: {db: '', collection: ''},
|
|
actions:['remove']}]);
|
|
assert.writeOK(testDB.foo.remove({ b: 2 }));
|
|
assert.eq(1, testDB.foo.count());
|
|
|
|
|
|
// Test revoking privileges
|
|
testUserAdmin.revokePrivilegesFromRole('testRole1', [{resource: {db: 'test', collection: 'foo'},
|
|
actions:['insert']}]);
|
|
hasAuthzError(testDB.foo.insert({ a: 1 }));
|
|
assert.eq(1, testDB.foo.count());
|
|
assert.writeOK(testDB.foo.update({ a: 2 }, { $inc: { a: 1 }}));
|
|
assert.eq(3, testDB.foo.findOne({a: {$exists: true}}).a);
|
|
hasAuthzError(testDB.foo.update({ c: 1 }, { $inc: { c: 1 }}, true)); // upsert should fail
|
|
assert.eq(1, testDB.foo.count());
|
|
|
|
|
|
// Test changeOwnPassword/changeOwnCustomData
|
|
assert.throws(function() { testDB.changeUserPassword('testUser', 'password'); });
|
|
assert.throws(function() { testDB.updateUser('testUser', {customData: {zipCode: 10036}})});
|
|
assert.eq(null, testDB.getUser('testUser').customData);
|
|
testUserAdmin.grantPrivilegesToRole('testRole1', [{resource: {db: 'test', collection: ''},
|
|
actions:['changeOwnPassword',
|
|
'changeOwnCustomData']}]);
|
|
testDB.changeUserPassword('testUser', 'password');
|
|
assert(!testDB.auth('testUser', 'pwd'));
|
|
assert(testDB.auth('testUser', 'password'));
|
|
testDB.updateUser('testUser', {customData: {zipCode: 10036}});
|
|
assert.eq(10036, testDB.getUser('testUser').customData.zipCode);
|
|
|
|
testUserAdmin.revokeRolesFromRole('testRole2', ['testRole1']);
|
|
assert.throws(function() { testDB.changeUserPassword('testUser', 'pwd'); });
|
|
assert.throws(function() { testDB.foo.findOne()});
|
|
assert.throws(function() { testDB.updateUser('testUser', {customData: {zipCode: 10028}})});
|
|
assert.eq(10036, testDB.getUser('testUser').customData.zipCode);
|
|
|
|
// Test changeAnyPassword/changeAnyCustomData
|
|
testUserAdmin.grantPrivilegesToRole('testRole2', [{resource: {db: 'test', collection: ''},
|
|
actions: ['changePassword',
|
|
'changeCustomData']}]);
|
|
testDB.changeUserPassword('testUser', 'pwd');
|
|
assert(!testDB.auth('testUser', 'password'));
|
|
assert(testDB.auth('testUser', 'pwd'));
|
|
testDB.updateUser('testUser', {customData: {zipCode: 10028}});
|
|
assert.eq(10028, testDB.getUser('testUser').customData.zipCode);
|
|
|
|
|
|
// Test privileges on the cluster resource
|
|
assert.commandFailed(testDB.runCommand({serverStatus:1}));
|
|
adminUserAdmin.grantPrivilegesToRole('adminRole', [{resource: {cluster: true},
|
|
actions:['serverStatus']}]);
|
|
assert.commandWorked(testDB.serverStatus());
|
|
|
|
}
|
|
|
|
jsTest.log('Test standalone');
|
|
var conn = MongoRunner.runMongod({ auth: '' });
|
|
runTest(conn);
|
|
MongoRunner.stopMongod(conn.port);
|
|
|
|
jsTest.log('Test sharding');
|
|
var st = new ShardingTest({ shards: 2, config: 3, keyFile: 'jstests/libs/key1' });
|
|
runTest(st.s);
|
|
st.stop();
|