You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.2 KiB
JavaScript

'use strict';
var async = require('async');
var _ = require('lodash');
var groups = require('../groups');
var user = require('../user');
var plugins = require('../plugins');
var helpers = module.exports;
helpers.some = function (tasks, callback) {
async.some(tasks, function (task, next) {
task(next);
}, callback);
};
helpers.isUserAllowedTo = function (privilege, uid, cid, callback) {
if (Array.isArray(privilege) && !Array.isArray(cid)) {
isUserAllowedToPrivileges(privilege, uid, cid, callback);
} else if (Array.isArray(cid) && !Array.isArray(privilege)) {
isUserAllowedToCids(privilege, uid, cid, callback);
} else {
return callback(new Error('[[error:invalid-data]]'));
}
};
function isUserAllowedToCids(privilege, uid, cids, callback) {
if (parseInt(uid, 10) === 0) {
return isGuestAllowedToCids(privilege, cids, callback);
}
var userKeys = [];
var groupKeys = [];
cids.forEach(function (cid) {
userKeys.push('cid:' + cid + ':privileges:' + privilege);
groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege);
});
checkIfAllowed(uid, userKeys, groupKeys, callback);
}
function isUserAllowedToPrivileges(privileges, uid, cid, callback) {
if (parseInt(uid, 10) === 0) {
return isGuestAllowedToPrivileges(privileges, cid, callback);
}
var userKeys = [];
var groupKeys = [];
privileges.forEach(function (privilege) {
userKeys.push('cid:' + cid + ':privileges:' + privilege);
groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege);
});
checkIfAllowed(uid, userKeys, groupKeys, callback);
}
function checkIfAllowed(uid, userKeys, groupKeys, callback) {
async.waterfall([
function (next) {
async.parallel({
hasUserPrivilege: function (next) {
groups.isMemberOfGroups(uid, userKeys, next);
},
hasGroupPrivilege: function (next) {
groups.isMemberOfGroupsList(uid, groupKeys, next);
},
}, next);
},
function (results, next) {
var result = userKeys.map(function (key, index) {
return results.hasUserPrivilege[index] || results.hasGroupPrivilege[index];
});
next(null, result);
},
], callback);
}
helpers.isUsersAllowedTo = function (privilege, uids, cid, callback) {
async.waterfall([
function (next) {
async.parallel({
hasUserPrivilege: function (next) {
groups.isMembers(uids, 'cid:' + cid + ':privileges:' + privilege, next);
},
hasGroupPrivilege: function (next) {
groups.isMembersOfGroupList(uids, 'cid:' + cid + ':privileges:groups:' + privilege, next);
},
}, next);
},
function (results, next) {
var result = uids.map(function (uid, index) {
return results.hasUserPrivilege[index] || results.hasGroupPrivilege[index];
});
next(null, result);
},
], callback);
};
function isGuestAllowedToCids(privilege, cids, callback) {
var groupKeys = cids.map(function (cid) {
return 'cid:' + cid + ':privileges:groups:' + privilege;
});
groups.isMemberOfGroups('guests', groupKeys, callback);
}
function isGuestAllowedToPrivileges(privileges, cid, callback) {
var groupKeys = privileges.map(function (privilege) {
return 'cid:' + cid + ':privileges:groups:' + privilege;
});
groups.isMemberOfGroups('guests', groupKeys, callback);
}
helpers.getUserPrivileges = function (cid, hookName, userPrivilegeList, callback) {
var userPrivileges;
var memberSets;
async.waterfall([
async.apply(plugins.fireHook, hookName, userPrivilegeList.slice()),
function (_privs, next) {
userPrivileges = _privs;
groups.getMembersOfGroups(userPrivileges.map(function (privilege) {
return 'cid:' + cid + ':privileges:' + privilege;
}), next);
},
function (_memberSets, next) {
memberSets = _memberSets.map(function (set) {
return set.map(function (uid) {
return parseInt(uid, 10);
});
});
var members = _.uniq(_.flatten(memberSets));
user.getUsersFields(members, ['picture', 'username'], next);
},
function (memberData, next) {
memberData.forEach(function (member) {
member.privileges = {};
for (var x = 0, numPrivs = userPrivileges.length; x < numPrivs; x += 1) {
member.privileges[userPrivileges[x]] = memberSets[x].indexOf(parseInt(member.uid, 10)) !== -1;
}
});
next(null, memberData);
},
], callback);
};
helpers.getGroupPrivileges = function (cid, hookName, groupPrivilegeList, callback) {
var groupPrivileges;
async.waterfall([
async.apply(plugins.fireHook, hookName, groupPrivilegeList.slice()),
function (_privs, next) {
groupPrivileges = _privs;
async.parallel({
memberSets: function (next) {
groups.getMembersOfGroups(groupPrivileges.map(function (privilege) {
return 'cid:' + cid + ':privileges:' + privilege;
}), next);
},
groupNames: function (next) {
groups.getGroups('groups:createtime', 0, -1, next);
},
}, next);
},
function (results, next) {
var memberSets = results.memberSets;
var uniqueGroups = _.uniq(_.flatten(memberSets));
var groupNames = results.groupNames.filter(function (groupName) {
return groupName.indexOf(':privileges:') === -1 && uniqueGroups.indexOf(groupName) !== -1;
});
groupNames = groups.ephemeralGroups.concat(groupNames);
var registeredUsersIndex = groupNames.indexOf('registered-users');
if (registeredUsersIndex !== -1) {
groupNames.splice(0, 0, groupNames.splice(registeredUsersIndex, 1)[0]);
} else {
groupNames = ['registered-users'].concat(groupNames);
}
var adminIndex = groupNames.indexOf('administrators');
if (adminIndex !== -1) {
groupNames.splice(adminIndex, 1);
}
var memberPrivs;
var memberData = groupNames.map(function (member) {
memberPrivs = {};
for (var x = 0, numPrivs = groupPrivileges.length; x < numPrivs; x += 1) {
memberPrivs[groupPrivileges[x]] = memberSets[x].indexOf(member) !== -1;
}
return {
name: member,
privileges: memberPrivs,
};
});
next(null, memberData);
},
function (memberData, next) {
// Grab privacy info for the groups as well
async.map(memberData, function (member, next) {
async.waterfall([
function (next) {
groups.isPrivate(member.name, next);
},
function (isPrivate, next) {
member.isPrivate = isPrivate;
next(null, member);
},
], next);
}, next);
},
], callback);
};