summaryrefslogtreecommitdiff
path: root/jstests/role_management_helpers.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/role_management_helpers.js')
-rw-r--r--jstests/role_management_helpers.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/jstests/role_management_helpers.js b/jstests/role_management_helpers.js
new file mode 100644
index 00000000000..1cb821975ef
--- /dev/null
+++ b/jstests/role_management_helpers.js
@@ -0,0 +1,137 @@
+// This test is a basic sanity check of the shell helpers for manipulating role objects
+// It is not a comprehensive test of the functionality of the role manipulation commands
+
+function assertHasRole(rolesArray, roleName, roleDB) {
+ for (i in rolesArray) {
+ var curRole = rolesArray[i];
+ if (curRole.role == roleName && curRole.db == roleDB) {
+ return;
+ }
+ }
+ assert(false, "role " + roleName + "@" + roleDB + " not found in array: " + tojson(rolesArray));
+}
+
+function assertHasPrivilege(privilegeArray, privilege) {
+ for (i in privilegeArray) {
+ var curPriv = privilegeArray[i];
+ if (curPriv.resource.cluster == privilege.resource.cluster &&
+ curPriv.resource.anyResource == privilege.resource.anyResource &&
+ curPriv.resource.db == privilege.resource.db &&
+ curPriv.resource.collection == privilege.resource.collection) {
+ // Same resource
+ assert.eq(curPriv.actions.length, privilege.actions.length);
+ for (k in curPriv.actions) {
+ assert.eq(curPriv.actions[k], privilege.actions[k]);
+ }
+ return;
+ }
+ }
+ assert(false, "Privilege " + tojson(privilege) + " not found in privilege array: " +
+ tojson(privilegeArray));
+}
+
+(function(db) {
+ var db = db.getSiblingDB("role_management_helpers");
+ db.dropDatabase();
+ db.dropAllRoles();
+
+ db.createRole({role:'roleA',
+ roles: [],
+ privileges: [{resource: {db:db.getName(), collection: "foo"},
+ actions: ['find']}]});
+ db.createRole({role:'roleB', privileges: [], roles: ["roleA"]});
+ db.createRole({role:'roleC', privileges: [], roles: []});
+
+ // Test getRole
+ var roleObj = db.getRole("roleA");
+ assert.eq(0, roleObj.roles.length);
+ assert.eq(null, roleObj.privileges);
+ roleObj = db.getRole("roleA", {showPrivileges: true});
+ assert.eq(1, roleObj.privileges.length);
+ assertHasPrivilege(roleObj.privileges,
+ {resource: {db:db.getName(), collection:"foo"}, actions:['find']});
+ roleObj = db.getRole("roleB", {showPrivileges: true});
+ assert.eq(1, roleObj.inheritedPrivileges.length); // inherited from roleA
+ assertHasPrivilege(roleObj.inheritedPrivileges,
+ {resource: {db:db.getName(), collection:"foo"}, actions:['find']});
+ assert.eq(1, roleObj.roles.length);
+ assertHasRole(roleObj.roles, "roleA", db.getName());
+
+ // Test getRoles
+ var roles = db.getRoles();
+ assert.eq(3, roles.length);
+ printjson(roles);
+ assert(roles[0].role == 'roleA' || roles[1].role == 'roleA' || roles[2].role == 'roleA');
+ assert(roles[0].role == 'roleB' || roles[1].role == 'roleB' || roles[2].role == 'roleB');
+ assert(roles[0].role == 'roleC' || roles[1].role == 'roleC' || roles[2].role == 'roleC');
+ assert.eq(null, roles[0].inheritedPrivileges);
+ var roles = db.getRoles({showPrivileges: true, showBuiltinRoles: true});
+ assert.eq(8, roles.length);
+ assert.neq(null, roles[0].inheritedPrivileges);
+
+
+ // Granting roles to nonexistent role fails
+ assert.throws(function() { db.grantRolesToRole("fakeRole", ['dbAdmin']); });
+ // Granting roles to built-in role fails
+ assert.throws(function() { db.grantRolesToRole("readWrite", ['dbAdmin']); });
+ // Granting non-existant role fails
+ assert.throws(function() { db.grantRolesToRole("roleB", ['dbAdmin', 'fakeRole']); });
+
+ roleObj = db.getRole("roleB", {showPrivileges: true});
+ assert.eq(1, roleObj.inheritedPrivileges.length);
+ assert.eq(1, roleObj.roles.length);
+ assertHasRole(roleObj.roles, "roleA", db.getName());
+
+ // Granting a role you already have is no problem
+ db.grantRolesToRole("roleB", ['readWrite', 'roleC']);
+ roleObj = db.getRole("roleB", {showPrivileges: true});
+ assert.gt(roleObj.inheritedPrivileges.length, 1); // Got privileges from readWrite role
+ assert.eq(3, roleObj.roles.length);
+ assertHasRole(roleObj.roles, "readWrite", db.getName());
+ assertHasRole(roleObj.roles, "roleA", db.getName());
+ assertHasRole(roleObj.roles, "roleC", db.getName());
+
+ // Revoking roles the role doesn't have is fine
+ db.revokeRolesFromRole("roleB", ['roleA', 'readWrite', 'dbAdmin']);
+ roleObj = db.getRole("roleB", {showPrivileges: true});
+ assert.eq(0, roleObj.inheritedPrivileges.length);
+ assert.eq(1, roleObj.roles.length);
+ assertHasRole(roleObj.roles, "roleC", db.getName());
+
+ // Privileges on the same resource get collapsed
+ db.grantPrivilegesToRole("roleA",
+ [{resource: {db:db.getName(), collection:""}, actions:['dropDatabase']},
+ {resource: {db:db.getName(), collection:"foo"}, actions:['insert']}]);
+ roleObj = db.getRole("roleA", {showPrivileges: true});
+ assert.eq(0, roleObj.roles.length);
+ assert.eq(2, roleObj.privileges.length);
+ assertHasPrivilege(roleObj.privileges,
+ {resource: {db:db.getName(), collection:"foo"}, actions:['find', 'insert']});
+ assertHasPrivilege(roleObj.privileges,
+ {resource: {db:db.getName(), collection:""}, actions:['dropDatabase']});
+
+ // Update role
+ db.updateRole("roleA", {roles:['roleB'],
+ privileges:[{resource: {db: db.getName(), collection:"foo"},
+ actions:['find']}]});
+ roleObj = db.getRole("roleA", {showPrivileges: true});
+ assert.eq(1, roleObj.roles.length);
+ assertHasRole(roleObj.roles, "roleB", db.getName());
+ assert.eq(1, roleObj.privileges.length);
+ assertHasPrivilege(roleObj.privileges,
+ {resource: {db:db.getName(), collection:"foo"}, actions:['find']});
+
+ // Test dropRole
+ db.dropRole('roleC');
+ assert.throws(function() {db.getRole('roleC')});
+ roleObj = db.getRole("roleB", {showPrivileges: true});
+ assert.eq(0, roleObj.privileges.length);
+ assert.eq(0, roleObj.roles.length);
+
+ // Test dropAllRoles
+ db.dropAllRoles();
+ assert.throws(function() {db.getRole('roleA')});
+ assert.throws(function() {db.getRole('roleB')});
+ assert.throws(function() {db.getRole('roleC')});
+
+}(db)); \ No newline at end of file