diff --git a/spec/ParseRole.spec.js b/spec/ParseRole.spec.js index 919e0b5544..83a5a59e30 100644 --- a/spec/ParseRole.spec.js +++ b/spec/ParseRole.spec.js @@ -2,6 +2,8 @@ // Roles are not accessible without the master key, so they are not intended // for use by clients. We can manually test them using the master key. +var Auth = require("../src/Auth").Auth; +var Config = require("../src/Config"); describe('Parse Role testing', () => { @@ -57,6 +59,48 @@ describe('Parse Role testing', () => { }); }); + + it("should recursively load roles", (done) => { + + var rolesNames = ["FooRole", "BarRole", "BazRole"]; + + var createRole = function(name, parent, user) { + var role = new Parse.Object("_Role") + role.set("name", name); + if (user) { + var users = role.relation('users'); + users.add(user); + } + if (parent) { + role.relation('roles').add(parent); + } + return role.save({}, { useMasterKey: true }); + } + var roleIds = {}; + createTestUser().then( (user) => { + + return createRole(rolesNames[0], null, null).then( (aRole) => { + roleIds[aRole.get("name")] = aRole.id; + return createRole(rolesNames[1], aRole, null); + }).then( (anotherRole) => { + roleIds[anotherRole.get("name")] = anotherRole.id; + return createRole(rolesNames[2], anotherRole, user); + }).then( (lastRole) => { + roleIds[lastRole.get("name")] = lastRole.id; + var auth = new Auth(new Config("test") , true, user); + return auth._loadRoles(); + }) + }).then( (roles) => { + expect(roles.length).toEqual(3); + rolesNames.forEach( (name) => { + expect(roles.indexOf('role:'+name)).not.toBe(-1); + }) + done(); + }, function(err){ + fail("should succeed") + done(); + }); + }); }); diff --git a/src/Auth.js b/src/Auth.js index 642f34ab84..a51c394a19 100644 --- a/src/Auth.js +++ b/src/Auth.js @@ -159,6 +159,22 @@ Auth.prototype._getAllRoleNamesForId = function(roleID) { return Promise.resolve([]); } var roleIDs = results.map(r => r.objectId); + + var parentRolesPromises = roleIDs.map( (roleId) => { + return this._getAllRoleNamesForId(roleId); + }); + parentRolesPromises.push(Promise.resolve(roleIDs)); + return Promise.all(parentRolesPromises); + }).then(function(results){ + // Flatten + let roleIDs = results.reduce( (memo, result) => { + if (typeof result == "object") { + memo = memo.concat(result); + } else { + memo.push(result); + } + return memo; + }, []); return Promise.resolve(roleIDs); }); };