Fix reversed roles lookup
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
// Roles are not accessible without the master key, so they are not intended
|
// 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.
|
// for use by clients. We can manually test them using the master key.
|
||||||
@@ -64,26 +64,30 @@ describe('Parse Role testing', () => {
|
|||||||
|
|
||||||
var rolesNames = ["FooRole", "BarRole", "BazRole"];
|
var rolesNames = ["FooRole", "BarRole", "BazRole"];
|
||||||
|
|
||||||
var createRole = function(name, parent, user) {
|
var createRole = function(name, sibling, user) {
|
||||||
var role = new Parse.Role(name, new Parse.ACL());
|
var role = new Parse.Role(name, new Parse.ACL());
|
||||||
if (user) {
|
if (user) {
|
||||||
var users = role.relation('users');
|
var users = role.relation('users');
|
||||||
users.add(user);
|
users.add(user);
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (sibling) {
|
||||||
role.relation('roles').add(parent);
|
role.relation('roles').add(sibling);
|
||||||
}
|
}
|
||||||
return role.save({}, { useMasterKey: true });
|
return role.save({}, { useMasterKey: true });
|
||||||
}
|
}
|
||||||
var roleIds = {};
|
var roleIds = {};
|
||||||
createTestUser().then( (user) => {
|
createTestUser().then( (user) => {
|
||||||
|
// Put the user on the 1st role
|
||||||
return createRole(rolesNames[0], null, null).then( (aRole) => {
|
return createRole(rolesNames[0], null, user).then( (aRole) => {
|
||||||
roleIds[aRole.get("name")] = aRole.id;
|
roleIds[aRole.get("name")] = aRole.id;
|
||||||
|
// set the 1st role as a sibling of the second
|
||||||
|
// user will should have 2 role now
|
||||||
return createRole(rolesNames[1], aRole, null);
|
return createRole(rolesNames[1], aRole, null);
|
||||||
}).then( (anotherRole) => {
|
}).then( (anotherRole) => {
|
||||||
roleIds[anotherRole.get("name")] = anotherRole.id;
|
roleIds[anotherRole.get("name")] = anotherRole.id;
|
||||||
return createRole(rolesNames[2], anotherRole, user);
|
// set this role as a sibling of the last
|
||||||
|
// the user should now have 3 roles
|
||||||
|
return createRole(rolesNames[2], anotherRole, null);
|
||||||
}).then( (lastRole) => {
|
}).then( (lastRole) => {
|
||||||
roleIds[lastRole.get("name")] = lastRole.id;
|
roleIds[lastRole.get("name")] = lastRole.id;
|
||||||
var auth = new Auth({ config: new Config("test"), isMaster: true, user: user });
|
var auth = new Auth({ config: new Config("test"), isMaster: true, user: user });
|
||||||
@@ -118,6 +122,53 @@ describe('Parse Role testing', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should properly resolve roles", (done) => {
|
||||||
|
let admin = new Parse.Role("Admin", new Parse.ACL());
|
||||||
|
let moderator = new Parse.Role("Moderator", new Parse.ACL());
|
||||||
|
let contentCreator = new Parse.Role('ContentManager', new Parse.ACL());
|
||||||
|
|
||||||
|
Parse.Object.saveAll([admin, moderator, contentCreator], {useMasterKey: true}).then(() => {
|
||||||
|
contentCreator.getRoles().add(moderator);
|
||||||
|
moderator.getRoles().add(admin);
|
||||||
|
return Parse.Object.saveAll([admin, moderator, contentCreator], {useMasterKey: true});
|
||||||
|
}).then(() => {
|
||||||
|
var auth = new Auth({ config: new Config("test"), isMaster: true });
|
||||||
|
// For each role, fetch their sibling, what they inherit
|
||||||
|
// return with result and roleId for later comparison
|
||||||
|
let promises = [admin, moderator, contentCreator].map((role) => {
|
||||||
|
return auth._getAllRoleNamesForId(role.id).then((result) => {
|
||||||
|
return Parse.Promise.as({
|
||||||
|
id: role.id,
|
||||||
|
roleIds: result
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return Parse.Promise.when(promises);
|
||||||
|
}).then((results) => {
|
||||||
|
|
||||||
|
results.forEach((result) => {
|
||||||
|
let id = result.id;
|
||||||
|
let roleIds = result.roleIds;
|
||||||
|
if (id == admin.id) {
|
||||||
|
expect(roleIds.length).toBe(2);
|
||||||
|
expect(roleIds.indexOf(moderator.id)).not.toBe(-1);
|
||||||
|
expect(roleIds.indexOf(contentCreator.id)).not.toBe(-1);
|
||||||
|
} else if (id == moderator.id) {
|
||||||
|
expect(roleIds.length).toBe(1);
|
||||||
|
expect(roleIds.indexOf(contentCreator.id)).toBe(0);
|
||||||
|
} else if (id == contentCreator.id) {
|
||||||
|
expect(roleIds.length).toBe(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
}).fail((err) => {
|
||||||
|
console.error(err);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
14
src/Auth.js
14
src/Auth.js
@@ -139,18 +139,18 @@ Auth.prototype._loadRoles = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Given a role object id, get any other roles it is part of
|
// Given a role object id, get any other roles it is part of
|
||||||
// TODO: Make recursive to support role nesting beyond 1 level deep
|
|
||||||
Auth.prototype._getAllRoleNamesForId = function(roleID) {
|
Auth.prototype._getAllRoleNamesForId = function(roleID) {
|
||||||
|
|
||||||
|
// As per documentation, a Role inherits AnotherRole
|
||||||
|
// if this Role is in the roles pointer of this AnotherRole
|
||||||
|
// Let's find all the roles where this role is in a roles relation
|
||||||
var rolePointer = {
|
var rolePointer = {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_Role',
|
className: '_Role',
|
||||||
objectId: roleID
|
objectId: roleID
|
||||||
};
|
};
|
||||||
var restWhere = {
|
var restWhere = {
|
||||||
'$relatedTo': {
|
'roles': rolePointer
|
||||||
key: 'roles',
|
|
||||||
object: rolePointer
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
var query = new RestQuery(this.config, master(this.config), '_Role',
|
var query = new RestQuery(this.config, master(this.config), '_Role',
|
||||||
restWhere, {});
|
restWhere, {});
|
||||||
@@ -161,6 +161,10 @@ Auth.prototype._getAllRoleNamesForId = function(roleID) {
|
|||||||
}
|
}
|
||||||
var roleIDs = results.map(r => r.objectId);
|
var roleIDs = results.map(r => r.objectId);
|
||||||
|
|
||||||
|
// we found a list of roles where the roleID
|
||||||
|
// is referenced in the roles relation,
|
||||||
|
// Get the roles where those found roles are also
|
||||||
|
// referenced the same way
|
||||||
var parentRolesPromises = roleIDs.map( (roleId) => {
|
var parentRolesPromises = roleIDs.map( (roleId) => {
|
||||||
return this._getAllRoleNamesForId(roleId);
|
return this._getAllRoleNamesForId(roleId);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user