move privileges to same page

v1.18.x
Baris Usakli 7 years ago
parent 63b9255fa1
commit 242dc41aca

@ -1,6 +1,4 @@
{ {
"global": "Global", "global": "Global",
"global.description": "You can configure the global privileges in this section. Privileges can be granted on a per-user or a per-group basis. You can add a new user to this table by searching for them in the form below.",
"global.warning": "<strong>Note</strong>: Privilege settings take effect immediately. It is not necessary to save after adjusting these settings.",
"global.no-users": "No user-specific global privileges." "global.no-users": "No user-specific global privileges."
} }

@ -1,6 +1,5 @@
'use strict'; 'use strict';
define('admin/manage/category', [ define('admin/manage/category', [
'uploader', 'uploader',
'iconSelect', 'iconSelect',
@ -8,8 +7,7 @@ define('admin/manage/category', [
'autocomplete', 'autocomplete',
'translator', 'translator',
'categorySelector', 'categorySelector',
'benchpress', ], function (uploader, iconSelect, colorpicker, autocomplete, translator, categorySelector) {
], function (uploader, iconSelect, colorpicker, autocomplete, translator, categorySelector, Benchpress) {
var Category = {}; var Category = {};
var modified_categories = {}; var modified_categories = {};
@ -21,11 +19,7 @@ define('admin/manage/category', [
$('#category-selector').on('change', function () { $('#category-selector').on('change', function () {
var val = $(this).val(); var val = $(this).val();
if (val === 'global') { ajaxify.go('admin/manage/categories/' + $(this).val() + window.location.hash);
ajaxify.go('admin/manage/privileges');
} else {
ajaxify.go('admin/manage/categories/' + $(this).val() + window.location.hash);
}
}); });
function enableColorPicker(idx, inputEl) { function enableColorPicker(idx, inputEl) {
@ -105,7 +99,7 @@ define('admin/manage/category', [
}); });
$('.copy-settings').on('click', function () { $('.copy-settings').on('click', function () {
selectCategoryModal(function (cid) { categorySelector.modal(function (cid) {
socket.emit('admin.categories.copySettingsFrom', { fromCid: cid, toCid: ajaxify.data.category.cid }, function (err) { socket.emit('admin.categories.copySettingsFrom', { fromCid: cid, toCid: ajaxify.data.category.cid }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -174,8 +168,6 @@ define('admin/manage/category', [
$('button[data-action="setParent"]').removeClass('hide'); $('button[data-action="setParent"]').removeClass('hide');
}); });
}); });
Category.setupPrivilegeTable();
}; };
function modified(el) { function modified(el) {
@ -213,102 +205,12 @@ define('admin/manage/category', [
}); });
} }
Category.setupPrivilegeTable = function () {
$('.privilege-table-container').on('change', 'input[type="checkbox"]', function () {
var checkboxEl = $(this);
var privilege = checkboxEl.parent().attr('data-privilege');
var state = checkboxEl.prop('checked');
var rowEl = checkboxEl.parents('tr');
var member = rowEl.attr('data-group-name') || rowEl.attr('data-uid');
var isPrivate = parseInt(rowEl.attr('data-private') || 0, 10);
var isGroup = rowEl.attr('data-group-name') !== undefined;
if (member) {
if (isGroup && privilege === 'groups:moderate' && !isPrivate && state) {
bootbox.confirm('[[admin/manage/categories:alert.confirm-moderate]]', function (confirm) {
if (confirm) {
Category.setPrivilege(member, privilege, state, checkboxEl);
} else {
checkboxEl.prop('checked', !checkboxEl.prop('checked'));
}
});
} else {
Category.setPrivilege(member, privilege, state, checkboxEl);
}
} else {
app.alertError('[[error:invalid-data]]');
}
});
$('.privilege-table-container').on('click', '[data-action="search.user"]', Category.addUserToPrivilegeTable);
$('.privilege-table-container').on('click', '[data-action="search.group"]', Category.addGroupToPrivilegeTable);
$('.privilege-table-container').on('click', '[data-action="copyToChildren"]', Category.copyPrivilegesToChildren);
$('.privilege-table-container').on('click', '[data-action="copyPrivilegesFrom"]', Category.copyPrivilegesFromCategory);
Category.exposeAssumedPrivileges();
};
Category.refreshPrivilegeTable = function () {
socket.emit('admin.categories.getPrivilegeSettings', ajaxify.data.category.cid, function (err, privileges) {
if (err) {
return app.alertError(err.message);
}
Benchpress.parse('admin/partials/categories/privileges', {
privileges: privileges,
}, function (html) {
translator.translate(html, function (html) {
$('.privilege-table-container').html(html);
Category.exposeAssumedPrivileges();
});
});
});
};
Category.exposeAssumedPrivileges = function () {
/*
If registered-users has a privilege enabled, then all users and groups of that privilege
should be assumed to have that privilege as well, even if not set in the db, so reflect
this arrangement in the table
*/
var privs = [];
$('.privilege-table tr[data-group-name="registered-users"] td input[type="checkbox"]').parent().each(function (idx, el) {
if ($(el).find('input').prop('checked')) {
privs.push(el.getAttribute('data-privilege'));
}
});
for (var x = 0, numPrivs = privs.length; x < numPrivs; x += 1) {
var inputs = $('.privilege-table tr[data-group-name]:not([data-group-name="registered-users"],[data-group-name="guests"]) td[data-privilege="' + privs[x] + '"] input');
inputs.each(function (idx, el) {
if (!el.checked) {
el.indeterminate = true;
}
});
}
};
Category.setPrivilege = function (member, privilege, state, checkboxEl) {
socket.emit('admin.categories.setPrivilege', {
cid: ajaxify.data.category.cid,
privilege: privilege,
set: state,
member: member,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
checkboxEl.replaceWith('<i class="fa fa-spin fa-spinner"></i>');
Category.refreshPrivilegeTable();
});
};
Category.launchParentSelector = function () { Category.launchParentSelector = function () {
var categories = ajaxify.data.allCategories.filter(function (category) { var categories = ajaxify.data.allCategories.filter(function (category) {
return category && !category.disabled && parseInt(category.cid, 10) !== parseInt(ajaxify.data.category.cid, 10); return category && !category.disabled && parseInt(category.cid, 10) !== parseInt(ajaxify.data.category.cid, 10);
}); });
selectCategoryModal(categories, function (parentCid) { categorySelector.modal(categories, function (parentCid) {
var payload = {}; var payload = {};
payload[ajaxify.data.category.cid] = { payload[ajaxify.data.category.cid] = {
@ -332,117 +234,5 @@ define('admin/manage/category', [
}); });
}; };
Category.addUserToPrivilegeTable = function () {
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-user]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.user-search]]" />',
show: true,
});
modal.on('shown.bs.modal', function () {
var inputEl = modal.find('input');
autocomplete.user(inputEl, function (ev, ui) {
socket.emit('admin.categories.setPrivilege', {
cid: ajaxify.data.category.cid,
privilege: ['find', 'read', 'topics:read'],
set: true,
member: ui.item.user.uid,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
Category.refreshPrivilegeTable();
modal.modal('hide');
});
});
});
};
Category.addGroupToPrivilegeTable = function () {
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-group]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.group-search]]" />',
show: true,
});
modal.on('shown.bs.modal', function () {
var inputEl = modal.find('input');
autocomplete.group(inputEl, function (ev, ui) {
socket.emit('admin.categories.setPrivilege', {
cid: ajaxify.data.category.cid,
privilege: ['groups:find', 'groups:read', 'groups:topics:read'],
set: true,
member: ui.item.group.name,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
Category.refreshPrivilegeTable();
modal.modal('hide');
});
});
});
};
Category.copyPrivilegesToChildren = function () {
socket.emit('admin.categories.copyPrivilegesToChildren', ajaxify.data.category.cid, function (err) {
if (err) {
return app.alertError(err.message);
}
app.alertSuccess('Privileges copied!');
});
};
Category.copyPrivilegesFromCategory = function () {
selectCategoryModal(function (cid) {
socket.emit('admin.categories.copyPrivilegesFrom', { toCid: ajaxify.data.category.cid, fromCid: cid }, function (err) {
if (err) {
return app.alertError(err.message);
}
ajaxify.refresh();
});
});
};
function selectCategoryModal(categories, callback) {
if (typeof categories === 'function') {
callback = categories;
categories = ajaxify.data.allCategories;
}
Benchpress.parse('admin/partials/categories/select-category', {
categories: categories,
}, function (html) {
translator.translate(html, function (html) {
var modal = bootbox.dialog({
title: '[[modules:composer.select_category]]',
message: html,
buttons: {
save: {
label: '[[global:select]]',
className: 'btn-primary',
callback: submit,
},
},
});
categorySelector.init(modal.find('[component="category-selector"]'));
function submit(ev) {
ev.preventDefault();
var selectedCategory = categorySelector.getSelectedCategory();
if (selectedCategory) {
callback(selectedCategory.cid);
modal.modal('hide');
}
return false;
}
modal.find('form').on('submit', submit);
});
});
}
return Category; return Category;
}); });

@ -1,19 +1,21 @@
'use strict'; 'use strict';
define('admin/manage/privileges', [ define('admin/manage/privileges', [
'autocomplete', 'autocomplete',
'translator', 'translator',
'benchpress', 'benchpress',
], function (autocomplete, translator, Benchpress) { 'categorySelector'
], function (autocomplete, translator, Benchpress, categorySelector) {
var Privileges = {}; var Privileges = {};
var cid;
Privileges.init = function () { Privileges.init = function () {
cid = ajaxify.data.cid || 0;
$('#category-selector').on('change', function () { $('#category-selector').on('change', function () {
var val = $(this).val(); var val = $(this).val();
if (val !== 'global') { ajaxify.go('admin/manage/privileges/' + (val === 'global' ? '' : $(this).val()));
ajaxify.go('admin/manage/categories/' + $(this).val() + '#privileges');
}
}); });
@ -31,7 +33,17 @@ define('admin/manage/privileges', [
var isGroup = rowEl.attr('data-group-name') !== undefined; var isGroup = rowEl.attr('data-group-name') !== undefined;
if (member) { if (member) {
Privileges.setPrivilege(member, privilege, state, checkboxEl); if (isGroup && privilege === 'groups:moderate' && !isPrivate && state) {
bootbox.confirm('[[admin/manage/categories:alert.confirm-moderate]]', function (confirm) {
if (confirm) {
Privileges.setPrivilege(member, privilege, state, checkboxEl);
} else {
checkboxEl.prop('checked', !checkboxEl.prop('checked'));
}
});
} else {
Privileges.setPrivilege(member, privilege, state, checkboxEl);
}
} else { } else {
app.alertError('[[error:invalid-data]]'); app.alertError('[[error:invalid-data]]');
} }
@ -39,17 +51,19 @@ define('admin/manage/privileges', [
$('.privilege-table-container').on('click', '[data-action="search.user"]', Privileges.addUserToPrivilegeTable); $('.privilege-table-container').on('click', '[data-action="search.user"]', Privileges.addUserToPrivilegeTable);
$('.privilege-table-container').on('click', '[data-action="search.group"]', Privileges.addGroupToPrivilegeTable); $('.privilege-table-container').on('click', '[data-action="search.group"]', Privileges.addGroupToPrivilegeTable);
$('.privilege-table-container').on('click', '[data-action="copyToChildren"]', Privileges.copyPrivilegesToChildren);
$('.privilege-table-container').on('click', '[data-action="copyPrivilegesFrom"]', Privileges.copyPrivilegesFromCategory);
Privileges.exposeAssumedPrivileges(); Privileges.exposeAssumedPrivileges();
}; };
Privileges.refreshPrivilegeTable = function () { Privileges.refreshPrivilegeTable = function () {
socket.emit('admin.categories.getPrivilegeSettings', function (err, privileges) { socket.emit('admin.categories.getPrivilegeSettings', cid, function (err, privileges) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
var tpl = cid ? 'admin/partials/categories/privileges' : 'admin/manage/privileges';
Benchpress.parse('admin/partials/global/privileges', { Benchpress.parse(tpl, {
privileges: privileges, privileges: privileges,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
@ -84,7 +98,7 @@ define('admin/manage/privileges', [
Privileges.setPrivilege = function (member, privilege, state, checkboxEl) { Privileges.setPrivilege = function (member, privilege, state, checkboxEl) {
socket.emit('admin.categories.setPrivilege', { socket.emit('admin.categories.setPrivilege', {
cid: 0, cid: cid,
privilege: privilege, privilege: privilege,
set: state, set: state,
member: member, member: member,
@ -109,9 +123,10 @@ define('admin/manage/privileges', [
var inputEl = modal.find('input'); var inputEl = modal.find('input');
autocomplete.user(inputEl, function (ev, ui) { autocomplete.user(inputEl, function (ev, ui) {
var defaultPrivileges = cid ? ['find', 'read', 'topics:read'] : ['chat'];
socket.emit('admin.categories.setPrivilege', { socket.emit('admin.categories.setPrivilege', {
cid: 0, cid: cid,
privilege: ['chat'], privilege: defaultPrivileges,
set: true, set: true,
member: ui.item.user.uid, member: ui.item.user.uid,
}, function (err) { }, function (err) {
@ -137,9 +152,10 @@ define('admin/manage/privileges', [
var inputEl = modal.find('input'); var inputEl = modal.find('input');
autocomplete.group(inputEl, function (ev, ui) { autocomplete.group(inputEl, function (ev, ui) {
var defaultPrivileges = cid ? ['groups:find', 'groups:read', 'groups:topics:read'] : ['groups:chat'];
socket.emit('admin.categories.setPrivilege', { socket.emit('admin.categories.setPrivilege', {
cid: 0, cid: cid,
privilege: ['groups:chat'], privilege: defaultPrivileges,
set: true, set: true,
member: ui.item.group.name, member: ui.item.group.name,
}, function (err) { }, function (err) {
@ -154,5 +170,25 @@ define('admin/manage/privileges', [
}); });
}; };
Privileges.copyPrivilegesToChildren = function () {
socket.emit('admin.categories.copyPrivilegesToChildren', cid, function (err) {
if (err) {
return app.alertError(err.message);
}
app.alertSuccess('Privileges copied!');
});
};
Privileges.copyPrivilegesFromCategory = function () {
categorySelector.modal(function (fromCid) {
socket.emit('admin.categories.copyPrivilegesFrom', { toCid: cid, fromCid: fromCid }, function (err) {
if (err) {
return app.alertError(err.message);
}
ajaxify.refresh();
});
});
};
return Privileges; return Privileges;
}); });

@ -1,7 +1,6 @@
'use strict'; 'use strict';
define('categorySelector', ['benchpress', 'translator'], function (Benchpress, translator) {
define('categorySelector', function () {
var categorySelector = {}; var categorySelector = {};
var selectedCategory; var selectedCategory;
var el; var el;
@ -29,6 +28,42 @@ define('categorySelector', function () {
el.find('[component="category-selector-selected"]').html(categoryEl.find('[component="category-markup"]').html()); el.find('[component="category-selector-selected"]').html(categoryEl.find('[component="category-markup"]').html());
}; };
categorySelector.modal = function (categories, callback) {
if (typeof categories === 'function') {
callback = categories;
categories = ajaxify.data.allCategories;
}
Benchpress.parse('admin/partials/categories/select-category', {
categories: categories,
}, function (html) {
translator.translate(html, function (html) {
var modal = bootbox.dialog({
title: '[[modules:composer.select_category]]',
message: html,
buttons: {
save: {
label: '[[global:select]]',
className: 'btn-primary',
callback: submit,
},
},
});
categorySelector.init(modal.find('[component="category-selector"]'));
function submit(ev) {
ev.preventDefault();
var selectedCategory = categorySelector.getSelectedCategory();
if (selectedCategory) {
callback(selectedCategory.cid);
modal.modal('hide');
}
return false;
}
modal.find('form').on('submit', submit);
});
});
};
return categorySelector; return categorySelector;
}); });

@ -15,7 +15,6 @@ categoriesController.get = function (req, res, callback) {
function (next) { function (next) {
async.parallel({ async.parallel({
category: async.apply(categories.getCategories, [req.params.category_id], req.user.uid), category: async.apply(categories.getCategories, [req.params.category_id], req.user.uid),
privileges: async.apply(privileges.categories.list, req.params.category_id),
allCategories: async.apply(categories.buildForSelect, req.uid, 'read'), allCategories: async.apply(categories.buildForSelect, req.uid, 'read'),
}, next); }, next);
}, },
@ -36,7 +35,6 @@ categoriesController.get = function (req, res, callback) {
req: req, req: req,
res: res, res: res,
category: category, category: category,
privileges: data.privileges,
allCategories: data.allCategories, allCategories: data.allCategories,
}, next); }, next);
}, },
@ -44,7 +42,6 @@ categoriesController.get = function (req, res, callback) {
data.category.name = translator.escape(String(data.category.name)); data.category.name = translator.escape(String(data.category.name));
res.render('admin/manage/category', { res.render('admin/manage/category', {
category: data.category, category: data.category,
privileges: data.privileges,
allCategories: data.allCategories, allCategories: data.allCategories,
}); });
}, },

@ -8,17 +8,32 @@ var privileges = require('../../privileges');
var privilegesController = module.exports; var privilegesController = module.exports;
privilegesController.get = function (req, res, callback) { privilegesController.get = function (req, res, callback) {
var cid = req.params.cid ? req.params.cid : 0;
async.waterfall([ async.waterfall([
function (next) { function (next) {
async.parallel({ async.parallel({
privileges: async.apply(privileges.global.list), privileges: function (next) {
if (!cid) {
privileges.global.list(next);
} else {
privileges.categories.list(cid, next);
}
},
allCategories: async.apply(categories.buildForSelect, req.uid, 'read'), allCategories: async.apply(categories.buildForSelect, req.uid, 'read'),
}, next); }, next);
}, },
function (data) { function (data) {
data.allCategories.forEach(function (category) {
if (category) {
category.selected = parseInt(category.cid, 10) === parseInt(cid, 10);
}
});
res.render('admin/manage/privileges', { res.render('admin/manage/privileges', {
privileges: data.privileges, privileges: data.privileges,
allCategories: data.allCategories, allCategories: data.allCategories,
cid: cid,
}); });
}, },
], callback); ], callback);

@ -15,121 +15,20 @@ module.exports = function (privileges) {
privileges.categories.list = function (cid, callback) { privileges.categories.list = function (cid, callback) {
// Method used in admin/category controller to show all users/groups with privs in that given cid // Method used in admin/category controller to show all users/groups with privs in that given cid
var privilegeLabels = privileges.privilegeLabels.slice();
var userPrivilegeList = privileges.userPrivilegeList.slice();
var groupPrivilegeList = privileges.groupPrivilegeList.slice();
async.waterfall([ async.waterfall([
function (next) { function (next) {
async.parallel({ async.parallel({
labels: function (next) { labels: function (next) {
async.parallel({ async.parallel({
users: async.apply(plugins.fireHook, 'filter:privileges.list_human', privilegeLabels), users: async.apply(plugins.fireHook, 'filter:privileges.list_human', privileges.privilegeLabels.slice()),
groups: async.apply(plugins.fireHook, 'filter:privileges.groups.list_human', privilegeLabels), groups: async.apply(plugins.fireHook, 'filter:privileges.groups.list_human', privileges.privilegeLabels.slice()),
}, next); }, next);
}, },
users: function (next) { users: function (next) {
var userPrivileges; helpers.getUserPrivileges(cid, 'filter:privileges.list', privileges.userPrivilegeList, next);
var memberSets;
async.waterfall([
async.apply(plugins.fireHook, 'filter:privileges.list', userPrivilegeList),
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);
},
], next);
}, },
groups: function (next) { groups: function (next) {
var groupPrivileges; helpers.getGroupPrivileges(cid, 'filter:privileges.groups.list', privileges.groupPrivilegeList, next);
async.waterfall([
async.apply(plugins.fireHook, 'filter:privileges.groups.list', groupPrivilegeList),
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);
},
], next);
}, },
}, next); }, next);
}, },

@ -25,121 +25,20 @@ module.exports = function (privileges) {
}); });
privileges.global.list = function (callback) { privileges.global.list = function (callback) {
var privilegeLabels = privileges.global.privilegeLabels.slice();
var userPrivilegeList = privileges.global.userPrivilegeList.slice();
var groupPrivilegeList = privileges.global.groupPrivilegeList.slice();
async.waterfall([ async.waterfall([
function (next) { function (next) {
async.parallel({ async.parallel({
labels: function (next) { labels: function (next) {
async.parallel({ async.parallel({
users: async.apply(plugins.fireHook, 'filter:privileges.global.list_human', privilegeLabels), users: async.apply(plugins.fireHook, 'filter:privileges.global.list_human', privileges.global.privilegeLabels.slice()),
groups: async.apply(plugins.fireHook, 'filter:privileges.global.groups.list_human', privilegeLabels), groups: async.apply(plugins.fireHook, 'filter:privileges.global.groups.list_human', privileges.global.privilegeLabels.slice()),
}, next); }, next);
}, },
users: function (next) { users: function (next) {
var userPrivileges; helpers.getUserPrivileges(0, 'filter:privileges.global.list', privileges.global.userPrivilegeList, next);
var memberSets;
async.waterfall([
async.apply(plugins.fireHook, 'filter:privileges.global.list', userPrivilegeList),
function (_privs, next) {
userPrivileges = _privs;
groups.getMembersOfGroups(userPrivileges.map(function (privilege) {
return 'cid:0: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);
},
], next);
}, },
groups: function (next) { groups: function (next) {
var groupPrivileges; helpers.getGroupPrivileges(0, 'filter:privileges.global.groups.list', privileges.global.groupPrivilegeList, next);
async.waterfall([
async.apply(plugins.fireHook, 'filter:privileges.global.groups.list', groupPrivilegeList),
function (_privs, next) {
groupPrivileges = _privs;
async.parallel({
memberSets: function (next) {
groups.getMembersOfGroups(groupPrivileges.map(function (privilege) {
return 'cid:0: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;
});
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);
},
], next);
}, },
}, next); }, next);
}, },

@ -2,7 +2,11 @@
'use strict'; 'use strict';
var async = require('async'); var async = require('async');
var _ = require('lodash');
var groups = require('../groups'); var groups = require('../groups');
var user = require('../user');
var plugins = require('../plugins');
var helpers = module.exports; var helpers = module.exports;
@ -111,3 +115,109 @@ function isGuestAllowedToPrivileges(privileges, cid, callback) {
groups.isMemberOfGroups('guests', groupKeys, callback); 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);
};

@ -55,7 +55,7 @@ function addRoutes(router, middleware, controllers) {
router.get('/manage/categories/:category_id', middlewares, controllers.admin.categories.get); router.get('/manage/categories/:category_id', middlewares, controllers.admin.categories.get);
router.get('/manage/categories/:category_id/analytics', middlewares, controllers.admin.categories.getAnalytics); router.get('/manage/categories/:category_id/analytics', middlewares, controllers.admin.categories.getAnalytics);
router.get('/manage/privileges', middlewares, controllers.admin.privileges.get); router.get('/manage/privileges/:cid?', middlewares, controllers.admin.privileges.get);
router.get('/manage/tags', middlewares, controllers.admin.tags.get); router.get('/manage/tags', middlewares, controllers.admin.tags.get);
router.get('/manage/post-queue', middlewares, controllers.admin.postQueue.get); router.get('/manage/post-queue', middlewares, controllers.admin.postQueue.get);
router.get('/manage/ip-blacklist', middlewares, controllers.admin.blacklist.get); router.get('/manage/ip-blacklist', middlewares, controllers.admin.blacklist.get);

@ -2,18 +2,8 @@
<form role="form" class="category" data-cid="{category.cid}"> <form role="form" class="category" data-cid="{category.cid}">
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-3 pull-right">
<ul class="nav nav-pills">
<li class="active"><a href="#category-settings" data-toggle="tab">
[[admin/manage/categories:settings]]
</a></li>
<li><a href="#privileges" data-toggle="tab">[[admin/manage/categories:privileges]]</a></li>
</ul>
</div>
<div class="col-md-3">
<select id="category-selector" class="form-control"> <select id="category-selector" class="form-control">
<option value="global" selected>[[admin/manage/privileges:global]]</option>
<option disabled>_____________</option>
<!-- BEGIN allCategories --> <!-- BEGIN allCategories -->
<option value="{allCategories.value}" <!-- IF allCategories.selected -->selected<!-- ENDIF allCategories.selected -->>{allCategories.text}</option> <option value="{allCategories.value}" <!-- IF allCategories.selected -->selected<!-- ENDIF allCategories.selected -->>{allCategories.text}</option>
<!-- END allCategories --> <!-- END allCategories -->
@ -176,19 +166,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tab-pane fade col-xs-12" id="privileges">
<p>
[[admin/manage/categories:privileges.description]]
</p>
<p class="text-warning">
[[admin/manage/categories:privileges.warning]]
</p>
<hr />
<div class="privilege-table-container">
<!-- IMPORT admin/partials/categories/privileges.tpl -->
</div>
</div>
</div> </div>
</form> </form>
</div> </div>

@ -3,10 +3,10 @@
<div class="row"> <div class="row">
<div class="col-md-3 pull-right"> <div class="col-md-3 pull-right">
<select id="category-selector" class="form-control"> <select id="category-selector" class="form-control">
<option value="global" selected>[[admin/manage/privileges:global]]</option> <option value="global" <!-- IF !cid --> selected <!-- ENDIF !cid -->>[[admin/manage/privileges:global]]</option>
<option disabled>_____________</option> <option disabled>_____________</option>
<!-- BEGIN allCategories --> <!-- BEGIN allCategories -->
<option value="{allCategories.value}">{allCategories.text}</option> <option value="{allCategories.value}" <!-- IF allCategories.selected -->selected<!-- ENDIF allCategories.selected -->>{allCategories.text}</option>
<!-- END allCategories --> <!-- END allCategories -->
</select> </select>
</div> </div>
@ -16,14 +16,18 @@
<div class=""> <div class="">
<p> <p>
[[admin/manage/privileges:global.description]] [[admin/manage/categories:privileges.description]]
</p> </p>
<p class="text-warning"> <p class="text-warning">
[[admin/manage/privileges:global.warning]] [[admin/manage/categories:privileges.warning]]
</p> </p>
<hr /> <hr />
<div class="privilege-table-container"> <div class="privilege-table-container">
<!-- IF cid -->
<!-- IMPORT admin/partials/categories/privileges.tpl -->
<!-- ELSE -->
<!-- IMPORT admin/partials/global/privileges.tpl --> <!-- IMPORT admin/partials/global/privileges.tpl -->
<!-- ENDIF cid -->
</div> </div>
</div> </div>
</form> </form>

Loading…
Cancel
Save