Skip to content

Commit

Permalink
More efficient user.can() algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
Zarel committed Apr 29, 2012
1 parent 911a065 commit c0cbb9b
Showing 1 changed file with 33 additions and 46 deletions.
79 changes: 33 additions & 46 deletions users.js
Expand Up @@ -147,56 +147,43 @@ function User(name, person, token) {
}
return selfP.group+selfP.name;
};
this.can = function(permission, targetUser) {
var group = config.groups[selfP.group];
if (!group) return false;

function permissionLookup(permission, curGroup, groupsBeenTo) {
// Finds the permission taking in account for inheritance
if (!curGroup) curGroup = group;
if (!groupsBeenTo) groupsBeenTo = new Array();
if (groupsBeenTo.indexOf(curGroup) !== -1)
throw new Error("Cycle detected in the group inheritance graph.");
groupsBeenTo.push(curGroup);

if (curGroup[permission]) {
var jurisdiction;
if (typeof curGroup[permission] === 'string') {
jurisdiction = curGroup[permission];
} else {
jurisdiction = permissionLookup('jurisdiction', group);
if (!jurisdiction) jurisdiction = true;
this.can = function(permission, target) {
var group = selfP.group;
var groupData = config.groups[group];
var checkedGroups = {};
while (groupData) {
// Cycle checker
if (checkedGroups[group]) return false;
checkedGroups[group] = true;

if (groupData['root']) {
return true;
}
if (groupData[permission]) {
var jurisdiction = groupData[permission];
if (!target) {
return !!jurisdiction;
}
if (jurisdiction === true) return true;
if (typeof jurisdiction === 'string') jurisdiction = jurisdiction.split('');

// Expand the special group 'u'
if (jurisdiction.indexOf('u') !== -1) {
var groupRank = config.groupsranking.indexOf(selfP.group);
var groupsToAdd = [];
if (groupRank !== -1) {
groupsToAdd = config.groupsranking.slice(0, groupRank);
}
groupsToAdd.unshift(jurisdiction.indexOf('u'), 1);
Array.prototype.splice.apply(jurisdiction, groupsToAdd);
if (jurisdiction === true && permission !== 'jurisdiction') {
return selfP.can('jurisdiction', target);
}
if (typeof jurisdiction !== 'string') {
return !!jurisdiction;
}
if (jurisdiction.indexOf(target.group) >= 0) {
return true;
}
if (jurisdiction.indexOf('s') >= 0 && target === selfP) {
return true;
}
if (jurisdiction.indexOf('u') >= 0 && config.groupsranking.indexOf(selfP.group) > config.groupsranking.indexOf(target.group)) {
return true;
}
return jurisdiction;
} else if (curGroup[permission] === false) {
return false;
}
if (!curGroup['inherit']) return false;
var nextGroup = config.groups[curGroup['inherit']];
if (!nextGroup) return false;
return permissionLookup(permission, nextGroup);
}

if (permissionLookup('root')) return true;
var jurisdiction = permissionLookup(permission);
if (!jurisdiction) return false;
if (!targetUser) return true;
if (targetUser && typeof jurisdiction === 'boolean') return false;
if (targetUser === selfP && jurisdiction.indexOf('s') !== -1) return true;
if (jurisdiction.indexOf(targetUser.group) !== -1) return true;
group = groupData['inherit'];
groupData = config.groups[group];
}
return false;
};
// Special permission check is needed for promoting and demoting
Expand Down

0 comments on commit c0cbb9b

Please sign in to comment.