diff options
Diffstat (limited to 'jstests/core/shell/user_management_helpers.js')
-rw-r--r-- | jstests/core/shell/user_management_helpers.js | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/jstests/core/shell/user_management_helpers.js b/jstests/core/shell/user_management_helpers.js new file mode 100644 index 00000000000..0e68c51d1f3 --- /dev/null +++ b/jstests/core/shell/user_management_helpers.js @@ -0,0 +1,152 @@ +// The test runs commands that are not allowed with security token: createUser, dropUser, +// grantRolesToUser, logout, revokeRolesFromUser, updateUser. +// @tags: [ +// not_allowed_with_security_token, +// assumes_superuser_permissions, +// assumes_write_concern_unchanged, +// creates_and_authenticates_user, +// requires_auth, +// requires_non_retryable_commands, +// # This test uses db._authOrThrow which does not use runCommand (required by the +// # inject_tenant_prefix.js override). +// tenant_migration_incompatible, +// ] + +(function() { +'use strict'; + +// This test is a basic sanity check of the shell helpers for manipulating user objects +// It is not a comprehensive test of the functionality of the user manipulation commands +function assertHasRole(rolesArray, roleName, roleDB) { + for (let i in rolesArray) { + const curRole = rolesArray[i]; + if (curRole.role == roleName && curRole.db == roleDB) { + return; + } + } + assert(false, "role " + roleName + "@" + roleDB + " not found in array: " + tojson(rolesArray)); +} + +function runTest(db) { + db.dropDatabase(); + db.dropAllUsers(); + + db.createUser({user: "spencer", pwd: "password", roles: ['readWrite']}); + db.createUser({user: "andy", pwd: "password", roles: ['readWrite']}); + + // Test getUser + let userObj = db.getUser('spencer'); + assert.eq(1, userObj.roles.length); + assertHasRole(userObj.roles, "readWrite", db.getName()); + + // Test getUsers + let users = db.getUsers(); + assert.eq(2, users.length); + assert(users[0].user == 'spencer' || users[1].user == 'spencer'); + assert(users[0].user == 'andy' || users[1].user == 'andy'); + assert.eq(1, users[0].roles.length); + assert.eq(1, users[1].roles.length); + assertHasRole(users[0].roles, "readWrite", db.getName()); + assertHasRole(users[1].roles, "readWrite", db.getName()); + + // Granting roles to nonexistent user fails + assert.throws(function() { + db.grantRolesToUser("fakeUser", ['dbAdmin']); + }); + // Granting non-existant role fails + assert.throws(function() { + db.grantRolesToUser("spencer", ['dbAdmin', 'fakeRole']); + }); + + userObj = db.getUser('spencer'); + assert.eq(1, userObj.roles.length); + assertHasRole(userObj.roles, "readWrite", db.getName()); + + // Granting a role you already have is no problem + db.grantRolesToUser("spencer", ['readWrite', 'dbAdmin']); + userObj = db.getUser('spencer'); + assert.eq(2, userObj.roles.length); + assertHasRole(userObj.roles, "readWrite", db.getName()); + assertHasRole(userObj.roles, "dbAdmin", db.getName()); + + // Revoking roles the user doesn't have is fine + db.revokeRolesFromUser("spencer", ['dbAdmin', 'read']); + userObj = db.getUser('spencer'); + assert.eq(1, userObj.roles.length); + assertHasRole(userObj.roles, "readWrite", db.getName()); + + // Update user + db.updateUser("spencer", {customData: {hello: 'world'}, roles: ['read']}); + userObj = db.getUser('spencer'); + assert.eq('world', userObj.customData.hello); + assert.eq(1, userObj.roles.length); + assertHasRole(userObj.roles, "read", db.getName()); + + // Test dropUser + db.dropUser('andy'); + assert.eq(null, db.getUser('andy')); + + // Test dropAllUsers + db.dropAllUsers(); + assert.eq(0, db.getUsers().length); + + // Test password digestion + assert.throws(function() { + db.createUser({user: 'user1', pwd: 'x', roles: [], digestPassword: true}); + }); + assert.throws(function() { + db.createUser({user: 'user1', pwd: 'x', roles: [], digestPassword: false}); + }); + assert.throws(function() { + db.createUser({user: 'user1', pwd: 'x', roles: [], passwordDigestor: 'foo'}); + }); + db.createUser({user: 'user1', pwd: 'x', roles: [], passwordDigestor: "server"}); + assert(db.auth('user1', 'x')); + assert.throws(function() { + db.updateUser('user1', {pwd: 'y', digestPassword: true}); + }); + assert.throws(function() { + db.updateUser('user1', {pwd: 'y', digestPassword: false}); + }); + assert.throws(function() { + db.updateUser('user1', {pwd: 'y', passwordDigestor: 'foo'}); + }); + + // Change password and reauth using new credentials. + db.updateUser('user1', {pwd: 'y', passwordDigestor: 'server'}); + assert(db.auth('user1', 'y')); + db.logout(); + + // Note that as of SERVER-32974, client-side digestion is only permitted under the SCRAM-SHA-1 + // mechanism. + db.createUser({ + user: 'user2', + pwd: 'x', + roles: [], + mechanisms: ['SCRAM-SHA-1'], + passwordDigestor: "client" + }); + assert(db.auth('user2', 'x')); + db.updateUser('user2', {pwd: 'y', mechanisms: ['SCRAM-SHA-1'], passwordDigestor: 'client'}); + assert(db.auth('user2', 'y')); + db.logout(); + + // Test createUser requires 'user' field + assert.throws(function() { + db.createUser({pwd: 'x', roles: ['dbAdmin']}); + }); + + // Test createUser disallows 'createUser' field + assert.throws(function() { + db.createUser({createUser: 'ben', pwd: 'x', roles: ['dbAdmin']}); + }); +} + +try { + runTest(db.getSiblingDB('user_management_helpers')); +} catch (x) { + // BF-836 Print current users on failure to aid debugging + db.getSiblingDB('admin').system.users.find().forEach(printjson); + throw x; +} +})(); |