From 242dc41aca3aa6235eaf6b78b6d594838340ab87 Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Wed, 20 Dec 2017 14:49:20 -0500 Subject: [PATCH] move privileges to same page --- .../en-GB/admin/manage/privileges.json | 2 - public/src/admin/manage/category.js | 218 +----------------- public/src/admin/manage/privileges.js | 64 +++-- public/src/modules/categorySelector.js | 39 +++- src/controllers/admin/categories.js | 3 - src/controllers/admin/privileges.js | 17 +- src/privileges/categories.js | 109 +-------- src/privileges/global.js | 109 +-------- src/privileges/helpers.js | 110 +++++++++ src/routes/admin.js | 2 +- src/views/admin/manage/category.tpl | 25 +- src/views/admin/manage/privileges.tpl | 12 +- 12 files changed, 235 insertions(+), 475 deletions(-) diff --git a/public/language/en-GB/admin/manage/privileges.json b/public/language/en-GB/admin/manage/privileges.json index 119633a322..b5b4f35885 100644 --- a/public/language/en-GB/admin/manage/privileges.json +++ b/public/language/en-GB/admin/manage/privileges.json @@ -1,6 +1,4 @@ { "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": "Note: Privilege settings take effect immediately. It is not necessary to save after adjusting these settings.", "global.no-users": "No user-specific global privileges." } \ No newline at end of file diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 39ff6b6ddf..71470baf46 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -1,6 +1,5 @@ 'use strict'; - define('admin/manage/category', [ 'uploader', 'iconSelect', @@ -8,8 +7,7 @@ define('admin/manage/category', [ 'autocomplete', 'translator', 'categorySelector', - 'benchpress', -], function (uploader, iconSelect, colorpicker, autocomplete, translator, categorySelector, Benchpress) { +], function (uploader, iconSelect, colorpicker, autocomplete, translator, categorySelector) { var Category = {}; var modified_categories = {}; @@ -21,11 +19,7 @@ define('admin/manage/category', [ $('#category-selector').on('change', function () { var val = $(this).val(); - if (val === 'global') { - ajaxify.go('admin/manage/privileges'); - } else { - ajaxify.go('admin/manage/categories/' + $(this).val() + window.location.hash); - } + ajaxify.go('admin/manage/categories/' + $(this).val() + window.location.hash); }); function enableColorPicker(idx, inputEl) { @@ -105,7 +99,7 @@ define('admin/manage/category', [ }); $('.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) { if (err) { return app.alertError(err.message); @@ -174,8 +168,6 @@ define('admin/manage/category', [ $('button[data-action="setParent"]').removeClass('hide'); }); }); - - Category.setupPrivilegeTable(); }; 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(''); - Category.refreshPrivilegeTable(); - }); - }; - Category.launchParentSelector = function () { var categories = ajaxify.data.allCategories.filter(function (category) { 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 = {}; 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: '', - 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: '', - 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; }); diff --git a/public/src/admin/manage/privileges.js b/public/src/admin/manage/privileges.js index e7bf2bc849..98587fc87f 100644 --- a/public/src/admin/manage/privileges.js +++ b/public/src/admin/manage/privileges.js @@ -1,19 +1,21 @@ 'use strict'; - define('admin/manage/privileges', [ 'autocomplete', 'translator', 'benchpress', -], function (autocomplete, translator, Benchpress) { + 'categorySelector' +], function (autocomplete, translator, Benchpress, categorySelector) { var Privileges = {}; + var cid; + Privileges.init = function () { + cid = ajaxify.data.cid || 0; + $('#category-selector').on('change', function () { var val = $(this).val(); - if (val !== 'global') { - ajaxify.go('admin/manage/categories/' + $(this).val() + '#privileges'); - } + ajaxify.go('admin/manage/privileges/' + (val === 'global' ? '' : $(this).val())); }); @@ -31,7 +33,17 @@ define('admin/manage/privileges', [ var isGroup = rowEl.attr('data-group-name') !== undefined; 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 { 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.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.refreshPrivilegeTable = function () { - socket.emit('admin.categories.getPrivilegeSettings', function (err, privileges) { + socket.emit('admin.categories.getPrivilegeSettings', cid, function (err, privileges) { if (err) { return app.alertError(err.message); } - - Benchpress.parse('admin/partials/global/privileges', { + var tpl = cid ? 'admin/partials/categories/privileges' : 'admin/manage/privileges'; + Benchpress.parse(tpl, { privileges: privileges, }, function (html) { translator.translate(html, function (html) { @@ -84,7 +98,7 @@ define('admin/manage/privileges', [ Privileges.setPrivilege = function (member, privilege, state, checkboxEl) { socket.emit('admin.categories.setPrivilege', { - cid: 0, + cid: cid, privilege: privilege, set: state, member: member, @@ -109,9 +123,10 @@ define('admin/manage/privileges', [ var inputEl = modal.find('input'); autocomplete.user(inputEl, function (ev, ui) { + var defaultPrivileges = cid ? ['find', 'read', 'topics:read'] : ['chat']; socket.emit('admin.categories.setPrivilege', { - cid: 0, - privilege: ['chat'], + cid: cid, + privilege: defaultPrivileges, set: true, member: ui.item.user.uid, }, function (err) { @@ -137,9 +152,10 @@ define('admin/manage/privileges', [ var inputEl = modal.find('input'); autocomplete.group(inputEl, function (ev, ui) { + var defaultPrivileges = cid ? ['groups:find', 'groups:read', 'groups:topics:read'] : ['groups:chat']; socket.emit('admin.categories.setPrivilege', { - cid: 0, - privilege: ['groups:chat'], + cid: cid, + privilege: defaultPrivileges, set: true, member: ui.item.group.name, }, 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; }); diff --git a/public/src/modules/categorySelector.js b/public/src/modules/categorySelector.js index 882206a42d..b9b8c9e3a4 100644 --- a/public/src/modules/categorySelector.js +++ b/public/src/modules/categorySelector.js @@ -1,7 +1,6 @@ 'use strict'; - -define('categorySelector', function () { +define('categorySelector', ['benchpress', 'translator'], function (Benchpress, translator) { var categorySelector = {}; var selectedCategory; var el; @@ -29,6 +28,42 @@ define('categorySelector', function () { 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; }); diff --git a/src/controllers/admin/categories.js b/src/controllers/admin/categories.js index 0b78912644..b3564afcef 100644 --- a/src/controllers/admin/categories.js +++ b/src/controllers/admin/categories.js @@ -15,7 +15,6 @@ categoriesController.get = function (req, res, callback) { function (next) { async.parallel({ 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'), }, next); }, @@ -36,7 +35,6 @@ categoriesController.get = function (req, res, callback) { req: req, res: res, category: category, - privileges: data.privileges, allCategories: data.allCategories, }, next); }, @@ -44,7 +42,6 @@ categoriesController.get = function (req, res, callback) { data.category.name = translator.escape(String(data.category.name)); res.render('admin/manage/category', { category: data.category, - privileges: data.privileges, allCategories: data.allCategories, }); }, diff --git a/src/controllers/admin/privileges.js b/src/controllers/admin/privileges.js index a1fdd4acf8..1fad4cfd06 100644 --- a/src/controllers/admin/privileges.js +++ b/src/controllers/admin/privileges.js @@ -8,17 +8,32 @@ var privileges = require('../../privileges'); var privilegesController = module.exports; privilegesController.get = function (req, res, callback) { + var cid = req.params.cid ? req.params.cid : 0; async.waterfall([ function (next) { 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'), }, next); }, function (data) { + + data.allCategories.forEach(function (category) { + if (category) { + category.selected = parseInt(category.cid, 10) === parseInt(cid, 10); + } + }); + res.render('admin/manage/privileges', { privileges: data.privileges, allCategories: data.allCategories, + cid: cid, }); }, ], callback); diff --git a/src/privileges/categories.js b/src/privileges/categories.js index 69aec85135..610ff7b711 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -15,121 +15,20 @@ module.exports = function (privileges) { privileges.categories.list = function (cid, callback) { // 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([ function (next) { async.parallel({ labels: function (next) { async.parallel({ - users: async.apply(plugins.fireHook, 'filter:privileges.list_human', privilegeLabels), - groups: async.apply(plugins.fireHook, 'filter:privileges.groups.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', privileges.privilegeLabels.slice()), }, next); }, users: function (next) { - var userPrivileges; - 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); + helpers.getUserPrivileges(cid, 'filter:privileges.list', privileges.userPrivilegeList, next); }, groups: function (next) { - var groupPrivileges; - 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); + helpers.getGroupPrivileges(cid, 'filter:privileges.groups.list', privileges.groupPrivilegeList, next); }, }, next); }, diff --git a/src/privileges/global.js b/src/privileges/global.js index 3047cdc55a..0ca4ac4347 100644 --- a/src/privileges/global.js +++ b/src/privileges/global.js @@ -25,121 +25,20 @@ module.exports = function (privileges) { }); 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([ function (next) { async.parallel({ labels: function (next) { async.parallel({ - users: async.apply(plugins.fireHook, 'filter:privileges.global.list_human', privilegeLabels), - groups: async.apply(plugins.fireHook, 'filter:privileges.global.groups.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', privileges.global.privilegeLabels.slice()), }, next); }, users: function (next) { - var userPrivileges; - 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); + helpers.getUserPrivileges(0, 'filter:privileges.global.list', privileges.global.userPrivilegeList, next); }, groups: function (next) { - var groupPrivileges; - 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); + helpers.getGroupPrivileges(0, 'filter:privileges.global.groups.list', privileges.global.groupPrivilegeList, next); }, }, next); }, diff --git a/src/privileges/helpers.js b/src/privileges/helpers.js index 0f56e4f9c8..8f2f21f0f7 100644 --- a/src/privileges/helpers.js +++ b/src/privileges/helpers.js @@ -2,7 +2,11 @@ '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; @@ -111,3 +115,109 @@ function isGuestAllowedToPrivileges(privileges, cid, 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); +}; \ No newline at end of file diff --git a/src/routes/admin.js b/src/routes/admin.js index ac90b89b97..ae90f4716b 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -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/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/post-queue', middlewares, controllers.admin.postQueue.get); router.get('/manage/ip-blacklist', middlewares, controllers.admin.blacklist.get); diff --git a/src/views/admin/manage/category.tpl b/src/views/admin/manage/category.tpl index 4addee15ba..cf8ab89312 100644 --- a/src/views/admin/manage/category.tpl +++ b/src/views/admin/manage/category.tpl @@ -2,18 +2,8 @@
- -
+
- + - +
@@ -16,14 +16,18 @@

- [[admin/manage/privileges:global.description]] + [[admin/manage/categories:privileges.description]]

- [[admin/manage/privileges:global.warning]] + [[admin/manage/categories:privileges.warning]]


+ + + +