mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
chat privilege
This commit is contained in:
6
public/language/en-GB/admin/manage/privileges.json
Normal file
6
public/language/en-GB/admin/manage/privileges.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"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."
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
"section-manage": "Manage",
|
||||
"manage/categories": "Categories",
|
||||
"manage/privileges": "Privileges",
|
||||
"manage/tags": "Tags",
|
||||
"manage/users": "Users",
|
||||
"manage/registration": "Registration Queue",
|
||||
|
||||
@@ -20,7 +20,12 @@ 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);
|
||||
}
|
||||
});
|
||||
|
||||
function enableColorPicker(idx, inputEl) {
|
||||
|
||||
158
public/src/admin/manage/privileges.js
Normal file
158
public/src/admin/manage/privileges.js
Normal file
@@ -0,0 +1,158 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
define('admin/manage/privileges', [
|
||||
'autocomplete',
|
||||
'translator',
|
||||
'benchpress',
|
||||
], function (autocomplete, translator, Benchpress) {
|
||||
var Privileges = {};
|
||||
|
||||
Privileges.init = function () {
|
||||
$('#category-selector').on('change', function () {
|
||||
var val = $(this).val();
|
||||
if (val !== 'global') {
|
||||
ajaxify.go('admin/manage/categories/' + $(this).val() + '#privileges');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Privileges.setupPrivilegeTable();
|
||||
};
|
||||
|
||||
Privileges.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) {
|
||||
Privileges.setPrivilege(member, privilege, state, checkboxEl);
|
||||
} else {
|
||||
app.alertError('[[error:invalid-data]]');
|
||||
}
|
||||
});
|
||||
|
||||
$('.privilege-table-container').on('click', '[data-action="search.user"]', Privileges.addUserToPrivilegeTable);
|
||||
$('.privilege-table-container').on('click', '[data-action="search.group"]', Privileges.addGroupToPrivilegeTable);
|
||||
|
||||
Privileges.exposeAssumedPrivileges();
|
||||
};
|
||||
|
||||
Privileges.refreshPrivilegeTable = function () {
|
||||
socket.emit('admin.categories.getPrivilegeSettings', function (err, privileges) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
Benchpress.parse('admin/partials/global/privileges', {
|
||||
privileges: privileges,
|
||||
}, function (html) {
|
||||
translator.translate(html, function (html) {
|
||||
$('.privilege-table-container').html(html);
|
||||
Privileges.exposeAssumedPrivileges();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Privileges.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;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Privileges.setPrivilege = function (member, privilege, state, checkboxEl) {
|
||||
socket.emit('admin.categories.setPrivilege', {
|
||||
cid: 0,
|
||||
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>');
|
||||
Privileges.refreshPrivilegeTable();
|
||||
});
|
||||
};
|
||||
|
||||
Privileges.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: 0,
|
||||
privilege: ['chat'],
|
||||
set: true,
|
||||
member: ui.item.user.uid,
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
Privileges.refreshPrivilegeTable();
|
||||
modal.modal('hide');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Privileges.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: 0,
|
||||
privilege: ['groups:chat'],
|
||||
set: true,
|
||||
member: ui.item.group.name,
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
Privileges.refreshPrivilegeTable();
|
||||
modal.modal('hide');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return Privileges;
|
||||
});
|
||||
@@ -5,6 +5,7 @@ var async = require('async');
|
||||
var messaging = require('../../messaging');
|
||||
var meta = require('../../meta');
|
||||
var user = require('../../user');
|
||||
var privileges = require('../../privileges');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
var chatsController = module.exports;
|
||||
@@ -19,6 +20,12 @@ chatsController.get = function (req, res, callback) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.global.can('chat', req.uid, next);
|
||||
},
|
||||
function (canChat, next) {
|
||||
if (!canChat) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
user.getUidByUserslug(req.params.userslug, next);
|
||||
},
|
||||
function (_uid, next) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
var adminController = {
|
||||
dashboard: require('./admin/dashboard'),
|
||||
categories: require('./admin/categories'),
|
||||
privileges: require('./admin/privileges'),
|
||||
tags: require('./admin/tags'),
|
||||
postQueue: require('./admin/postqueue'),
|
||||
blacklist: require('./admin/blacklist'),
|
||||
|
||||
25
src/controllers/admin/privileges.js
Normal file
25
src/controllers/admin/privileges.js
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async');
|
||||
|
||||
var categories = require('../../categories');
|
||||
var privileges = require('../../privileges');
|
||||
|
||||
var privilegesController = module.exports;
|
||||
|
||||
privilegesController.get = function (req, res, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
async.parallel({
|
||||
privileges: async.apply(privileges.global.list),
|
||||
allCategories: async.apply(categories.buildForSelect, req.uid, 'read'),
|
||||
}, next);
|
||||
},
|
||||
function (data) {
|
||||
res.render('admin/manage/privileges', {
|
||||
privileges: data.privileges,
|
||||
allCategories: data.allCategories,
|
||||
});
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
@@ -10,6 +10,7 @@ var meta = require('../meta');
|
||||
var plugins = require('../plugins');
|
||||
var navigation = require('../navigation');
|
||||
var translator = require('../translator');
|
||||
var privileges = require('../privileges');
|
||||
var utils = require('../utils');
|
||||
|
||||
var controllers = {
|
||||
@@ -75,6 +76,9 @@ module.exports = function (middleware) {
|
||||
isModerator: function (next) {
|
||||
user.isModeratorOfAnyCategory(req.uid, next);
|
||||
},
|
||||
canChat: function (next) {
|
||||
privileges.global.can('chat', req.uid, next);
|
||||
},
|
||||
user: function (next) {
|
||||
var userData = {
|
||||
uid: 0,
|
||||
@@ -124,6 +128,7 @@ module.exports = function (middleware) {
|
||||
results.user.isAdmin = results.isAdmin;
|
||||
results.user.isGlobalMod = results.isGlobalMod;
|
||||
results.user.isMod = !!results.isModerator;
|
||||
|
||||
results.user.uid = parseInt(results.user.uid, 10);
|
||||
results.user.email = String(results.user.email);
|
||||
results.user['email:confirmed'] = parseInt(results.user['email:confirmed'], 10) === 1;
|
||||
@@ -138,6 +143,7 @@ module.exports = function (middleware) {
|
||||
templateValues.isAdmin = results.user.isAdmin;
|
||||
templateValues.isGlobalMod = results.user.isGlobalMod;
|
||||
templateValues.showModMenu = results.user.isAdmin || results.user.isGlobalMod || results.user.isMod;
|
||||
templateValues.canChat = results.canChat;
|
||||
templateValues.user = results.user;
|
||||
templateValues.userJSON = jsesc(JSON.stringify(results.user), { isScriptContext: true });
|
||||
templateValues.useCustomCSS = parseInt(meta.config.useCustomCSS, 10) === 1 && meta.config.customCSS;
|
||||
|
||||
@@ -40,6 +40,7 @@ privileges.groupPrivilegeList = privileges.userPrivilegeList.map(function (privi
|
||||
|
||||
privileges.privilegeList = privileges.userPrivilegeList.concat(privileges.groupPrivilegeList);
|
||||
|
||||
require('./privileges/global')(privileges);
|
||||
require('./privileges/categories')(privileges);
|
||||
require('./privileges/topics')(privileges);
|
||||
require('./privileges/posts')(privileges);
|
||||
|
||||
171
src/privileges/global.js
Normal file
171
src/privileges/global.js
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async');
|
||||
var _ = require('lodash');
|
||||
|
||||
var user = require('../user');
|
||||
var groups = require('../groups');
|
||||
var helpers = require('./helpers');
|
||||
var plugins = require('../plugins');
|
||||
|
||||
module.exports = function (privileges) {
|
||||
privileges.global = {};
|
||||
|
||||
privileges.global.privilegeLabels = [
|
||||
{ name: 'Chat' },
|
||||
];
|
||||
|
||||
privileges.global.userPrivilegeList = [
|
||||
'chat',
|
||||
];
|
||||
|
||||
privileges.global.groupPrivilegeList = privileges.global.userPrivilegeList.map(function (privilege) {
|
||||
return 'groups:' + privilege;
|
||||
});
|
||||
|
||||
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),
|
||||
}, 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);
|
||||
},
|
||||
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);
|
||||
},
|
||||
}, next);
|
||||
},
|
||||
function (payload, next) {
|
||||
// This is a hack because I can't do {labels.users.length} to echo the count in templates.js
|
||||
payload.columnCount = payload.labels.users.length + 2;
|
||||
next(null, payload);
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
|
||||
privileges.global.can = function (privilege, uid, callback) {
|
||||
helpers.some([
|
||||
function (next) {
|
||||
helpers.isUserAllowedTo(privilege, uid, [0], function (err, results) {
|
||||
next(err, Array.isArray(results) && results.length ? results[0] : false);
|
||||
});
|
||||
},
|
||||
function (next) {
|
||||
user.isGlobalModerator(uid, next);
|
||||
},
|
||||
function (next) {
|
||||
user.isAdministrator(uid, next);
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@@ -55,6 +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/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);
|
||||
|
||||
@@ -83,7 +83,11 @@ Categories.setPrivilege = function (socket, data, callback) {
|
||||
};
|
||||
|
||||
Categories.getPrivilegeSettings = function (socket, cid, callback) {
|
||||
if (!parseInt(cid, 10)) {
|
||||
privileges.global.list(callback);
|
||||
} else {
|
||||
privileges.categories.list(cid, callback);
|
||||
}
|
||||
};
|
||||
|
||||
Categories.copyPrivilegesToChildren = function (socket, cid, callback) {
|
||||
|
||||
@@ -11,6 +11,7 @@ var Messaging = require('../messaging');
|
||||
var utils = require('../utils');
|
||||
var server = require('./');
|
||||
var user = require('../user');
|
||||
var privileges = require('../privileges');
|
||||
|
||||
var SocketModules = module.exports;
|
||||
|
||||
@@ -73,6 +74,12 @@ SocketModules.chats.newRoom = function (socket, data, callback) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.global.can('chat', socket.uid, next);
|
||||
},
|
||||
function (canChat, next) {
|
||||
if (!canChat) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
Messaging.canMessageUser(socket.uid, data.touid, next);
|
||||
},
|
||||
function (next) {
|
||||
@@ -92,6 +99,13 @@ SocketModules.chats.send = function (socket, data, callback) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.global.can('chat', socket.uid, next);
|
||||
},
|
||||
function (canChat, next) {
|
||||
if (!canChat) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
plugins.fireHook('filter:messaging.send', {
|
||||
data: data,
|
||||
uid: socket.uid,
|
||||
@@ -133,6 +147,13 @@ SocketModules.chats.loadRoom = function (socket, data, callback) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.global.can('chat', socket.uid, next);
|
||||
},
|
||||
function (canChat, next) {
|
||||
if (!canChat) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
Messaging.isUserInRoom(socket.uid, data.roomId, next);
|
||||
},
|
||||
function (inRoom, next) {
|
||||
@@ -174,6 +195,13 @@ SocketModules.chats.addUserToRoom = function (socket, data, callback) {
|
||||
var uid;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.global.can('chat', socket.uid, next);
|
||||
},
|
||||
function (canChat, next) {
|
||||
if (!canChat) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
Messaging.getUserCountInRoom(data.roomId, next);
|
||||
},
|
||||
function (userCount, next) {
|
||||
|
||||
12
src/upgrades/1.8.0/chat_privilege.js
Normal file
12
src/upgrades/1.8.0/chat_privilege.js
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
var groups = require('../../groups');
|
||||
|
||||
module.exports = {
|
||||
name: 'Give chat privilege to registered-users',
|
||||
timestamp: Date.UTC(2017, 11, 18),
|
||||
method: function (callback) {
|
||||
groups.join('cid:0:privileges:group:chat', 'registered-users', callback);
|
||||
},
|
||||
};
|
||||
@@ -12,6 +12,8 @@
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select id="category-selector" class="form-control">
|
||||
<option value="global" selected>[[admin/manage/privileges:global]]</option>
|
||||
<option disabled>_____________</option>
|
||||
<!-- BEGIN allCategories -->
|
||||
<option value="{allCategories.value}" <!-- IF allCategories.selected -->selected<!-- ENDIF allCategories.selected -->>{allCategories.text}</option>
|
||||
<!-- END allCategories -->
|
||||
|
||||
34
src/views/admin/manage/privileges.tpl
Normal file
34
src/views/admin/manage/privileges.tpl
Normal file
@@ -0,0 +1,34 @@
|
||||
<div class="row">
|
||||
<form role="form" class="category">
|
||||
<div class="row">
|
||||
<div class="col-md-3 pull-right">
|
||||
<select id="category-selector" class="form-control">
|
||||
<option value="global" selected>[[admin/manage/privileges:global]]</option>
|
||||
<option disabled>_____________</option>
|
||||
<!-- BEGIN allCategories -->
|
||||
<option value="{allCategories.value}">{allCategories.text}</option>
|
||||
<!-- END allCategories -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="">
|
||||
<p>
|
||||
[[admin/manage/privileges:global.description]]
|
||||
</p>
|
||||
<p class="text-warning">
|
||||
[[admin/manage/privileges:global.warning]]
|
||||
</p>
|
||||
<hr />
|
||||
<div class="privilege-table-container">
|
||||
<!-- IMPORT admin/partials/global/privileges.tpl -->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
|
||||
<i class="material-icons">save</i>
|
||||
</button>
|
||||
86
src/views/admin/partials/global/privileges.tpl
Normal file
86
src/views/admin/partials/global/privileges.tpl
Normal file
@@ -0,0 +1,86 @@
|
||||
<table class="table table-striped privilege-table">
|
||||
<thead>
|
||||
<tr class="privilege-table-header">
|
||||
<th colspan="3"></th>
|
||||
</tr><tr><!-- zebrastripe reset --></tr>
|
||||
<tr>
|
||||
<th colspan="2">[[admin/manage/categories:privileges.section-user]]</th>
|
||||
<!-- BEGIN privileges.labels.users -->
|
||||
<th class="text-center">{privileges.labels.users.name}</th>
|
||||
<!-- END privileges.labels.users -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- IF privileges.users.length -->
|
||||
<!-- BEGIN privileges.users -->
|
||||
<tr data-uid="{privileges.users.uid}">
|
||||
<td>
|
||||
<!-- IF ../picture -->
|
||||
<img class="avatar avatar-sm" src="{privileges.users.picture}" title="{privileges.users.username}" />
|
||||
<!-- ELSE -->
|
||||
<div class="avatar avatar-sm" style="background-color: {../icon:bgColor};">{../icon:text}</div>
|
||||
<!-- ENDIF ../picture -->
|
||||
</td>
|
||||
<td>{privileges.users.username}</td>
|
||||
{function.spawnPrivilegeStates, privileges.users.username, ../privileges}
|
||||
</tr>
|
||||
<!-- END privileges.users -->
|
||||
<tr>
|
||||
<td colspan="{privileges.columnCount}">
|
||||
<button type="button" class="btn btn-primary pull-right" data-ajaxify="false" data-action="search.user">
|
||||
[[admin/manage/categories:privileges.search-user]]
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- ELSE -->
|
||||
<tr>
|
||||
<td colspan="{privileges.columnCount}">
|
||||
[[admin/manage/privileges:global.no-users]]
|
||||
<button type="button" class="btn btn-primary pull-right" data-ajaxify="false" data-action="search.user">
|
||||
[[admin/manage/categories:privileges.search-user]]
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- ENDIF privileges.users.length -->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table table-striped privilege-table">
|
||||
<thead>
|
||||
<tr class="privilege-table-header">
|
||||
<th colspan="3"></th>
|
||||
</tr><tr><!-- zebrastripe reset --></tr>
|
||||
<tr>
|
||||
<th colspan="2">[[admin/manage/categories:privileges.section-group]]</th>
|
||||
<!-- BEGIN privileges.labels.groups -->
|
||||
<th class="text-center">{privileges.labels.groups.name}</th>
|
||||
<!-- END privileges.labels.groups -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- BEGIN privileges.groups -->
|
||||
<tr data-group-name="{privileges.groups.name}" data-private="<!-- IF privileges.groups.isPrivate -->1<!-- ELSE -->0<!-- ENDIF privileges.groups.isPrivate -->">
|
||||
<td>
|
||||
<!-- IF privileges.groups.isPrivate -->
|
||||
<i class="fa fa-lock text-muted" title="[[admin/manage/categories:privileges.group-private]]"></i>
|
||||
<!-- ENDIF privileges.groups.isPrivate -->
|
||||
{privileges.groups.name}
|
||||
</td>
|
||||
<td></td>
|
||||
{function.spawnPrivilegeStates, privileges.groups.name, ../privileges}
|
||||
</tr>
|
||||
<!-- END privileges.groups -->
|
||||
<tr>
|
||||
<td colspan="{privileges.columnCount}">
|
||||
<div class="btn-toolbar">
|
||||
<button type="button" class="btn btn-primary pull-right" data-ajaxify="false" data-action="search.group">
|
||||
[[admin/manage/categories:privileges.search-group]]
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="help-block">
|
||||
[[admin/manage/categories:privileges.inherit]]
|
||||
</div>
|
||||
@@ -15,6 +15,7 @@
|
||||
<h3 class="menu-section-title">[[admin/menu:section-manage]]</h3>
|
||||
<ul class="menu-section-list">
|
||||
<li><a href="{relative_path}/admin/manage/categories">[[admin/menu:manage/categories]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/privileges">[[admin/menu:manage/privileges]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/users">[[admin/menu:manage/users]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/groups">[[admin/menu:manage/groups]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
|
||||
@@ -188,6 +189,7 @@
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">[[admin/menu:section-manage]]</a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{relative_path}/admin/manage/categories">[[admin/menu:manage/categories]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/privileges">[[admin/menu:manage/privileges]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/users">[[admin/menu:manage/users]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/groups">[[admin/menu:manage/groups]]</a></li>
|
||||
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
|
||||
|
||||
Reference in New Issue
Block a user