0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-24 16:46:00 +01:00
mongodb/jstests/auth/user_defined_roles.js
Matt Broadstone 771dabd098 SERVER-81339 Convert ReplSetTest and ShardingTest to modules (#26332)
GitOrigin-RevId: 744aa110a53786b23c62ff53f87a1418b5991e8d
2024-08-20 22:00:49 +00:00

153 lines
6.4 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
* @tags: [requires_sharding]
*/
import {ShardingTest} from "jstests/libs/shardingtest.js";
function runTest(conn) {
var authzErrorCode = 13;
var hasAuthzError = function(result) {
assert(result instanceof WriteCommandError);
assert.eq(authzErrorCode, result.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.commandWorked(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.commandWorked(testDB.foo.update({a: 1}, {$inc: {a: 1}}));
assert.eq(2, testDB.foo.findOne().a);
assert.commandWorked(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.commandWorked(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.commandWorked(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);
jsTest.log('Test sharding');
var st = new ShardingTest({shards: 2, config: 3, keyFile: 'jstests/libs/key1'});
runTest(st.s);
st.stop();