summaryrefslogtreecommitdiff
path: root/jstests/core/shell/user_management_helpers.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core/shell/user_management_helpers.js')
-rw-r--r--jstests/core/shell/user_management_helpers.js152
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;
+}
+})();