MDL-70320 permission overrides: role names were double-escaped
[moodle.git] / lib / amd / src / permissionmanager.js
CommitLineData
24935689
MM
1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15/*
16 * @package core
17 * @class permissionmanager
18 * @copyright 2015 Martin Mastny <mastnym@vscht.cz>
19 * @since 3.0
20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21 */
22
23 /**
24 * @module admin/permissionmanager
25 */
e7ecb4a9
DP
26define(['jquery', 'core/config', 'core/notification', 'core/templates', 'core/yui'],
27 function($, config, notification, templates, Y) {
24935689
MM
28
29 /**
30 * Used CSS selectors
31 * @access private
32 */
33 var SELECTORS = {
34 ADDROLE: 'a.allowlink, a.prohibitlink',
35 REMOVEROLE: 'a.preventlink, a.unprohibitlink',
36 UNPROHIBIT: 'a.unprohibitlink'
37 };
38 var rolesloadedevent = $.Event('rolesloaded');
39 var contextid;
40 var contextname;
41 var adminurl;
42 var overideableroles;
43 var panel = null;
44
45 /**
46 * Load all possible roles, which could be assigned from server
47 *
48 * @access private
49 * @method loadOverideableRoles
50 */
51 var loadOverideableRoles = function() {
52 var params = {
53 contextid: contextid,
54 getroles: 1,
55 sesskey: config.sesskey
56 };
57
4d9036d6
MJ
58 // Need to tell jQuery to expect JSON as the content type may not be correct (MDL-55041).
59 $.post(adminurl + 'roles/ajax.php', params, null, 'json')
24935689
MM
60 .done(function(data) {
61 try {
62 overideableroles = data;
63 loadOverideableRoles = function() {
64 $('body').trigger(rolesloadedevent);
65 };
66 loadOverideableRoles();
c96f55e6 67 } catch (err) {
24935689
MM
68 notification.exception(err);
69 }
70 })
71 .fail(function(jqXHR, status, error) {
72 notification.exception(error);
73 });
74 };
75
76 /**
77 * Perform the UI changes after server change
78 *
79 * @access private
80 * @method changePermissions
c96f55e6 81 * @param {JQuery} row
24935689
MM
82 * @param {int} roleid
83 * @param {string} action
84 */
85 var changePermissions = function(row, roleid, action) {
86 var params = {
87 contextid: contextid,
88 roleid: roleid,
89 sesskey: M.cfg.sesskey,
90 action: action,
91 capability: row.data('name')
92 };
4d9036d6 93 $.post(adminurl + 'roles/ajax.php', params, null, 'json')
24935689
MM
94 .done(function(data) {
95 var action = data;
96 try {
97 var templatedata = {rolename: overideableroles[roleid],
98 roleid: roleid,
99 adminurl: adminurl,
100 imageurl: M.util.image_url('t/delete', 'moodle')
101 };
102 switch (action) {
103 case 'allow':
104 templatedata.spanclass = 'allowed';
105 templatedata.linkclass = 'preventlink';
106 templatedata.action = 'prevent';
06ced40c 107 templatedata.icon = 't/delete';
6786f6b6 108 templatedata.iconalt = M.util.get_string('deletexrole', 'core_role', overideableroles[roleid]);
24935689
MM
109 break;
110 case 'prohibit':
111 templatedata.spanclass = 'forbidden';
112 templatedata.linkclass = 'unprohibitlink';
113 templatedata.action = 'unprohibit';
06ced40c 114 templatedata.icon = 't/delete';
6786f6b6 115 templatedata.iconalt = M.util.get_string('deletexrole', 'core_role', overideableroles[roleid]);
24935689
MM
116 break;
117 case 'prevent':
118 row.find('a[data-role-id="' + roleid + '"]').first().closest('.allowed').remove();
119 return;
120 case 'unprohibit':
121 row.find('a[data-role-id="' + roleid + '"]').first().closest('.forbidden').remove();
122 return;
123 default:
124 return;
125 }
35be5826
DP
126 templates.render('core/permissionmanager_role', templatedata)
127 .done(function(content) {
128 if (action == 'allow') {
24935689 129 $(content).insertBefore(row.find('.allowmore:first'));
35be5826 130 } else if (action == 'prohibit') {
24935689
MM
131 $(content).insertBefore(row.find('.prohibitmore:first'));
132 // Remove allowed link
133 var allowedLink = row.find('.allowedroles').first().find('a[data-role-id="' + roleid + '"]');
134 if (allowedLink) {
135 allowedLink.first().closest('.allowed').remove();
136 }
137 }
138 panel.hide();
139 })
140 .fail(notification.exception);
c96f55e6 141 } catch (err) {
24935689
MM
142 notification.exception(err);
143 }
144 })
145 .fail(function(jqXHR, status, error) {
146 notification.exception(error);
147 });
148 };
149
150 /**
151 * Prompts user for selecting a role which is permitted
152 *
153 * @access private
154 * @method handleAddRole
155 * @param {event} e
156 */
35be5826 157 var handleAddRole = function(e) {
24935689
MM
158 e.preventDefault();
159
b1078b18
SR
160 var link = $(e.currentTarget);
161
e7ecb4a9 162 // TODO: MDL-57778 Convert to core/modal.
b1078b18
SR
163 $('body').one('rolesloaded', function() {
164 Y.use('moodle-core-notification-dialogue', function() {
e7ecb4a9
DP
165 var action = link.data('action');
166 var row = link.closest('tr.rolecap');
167 var confirmationDetails = {
168 cap: row.data('humanname'),
169 context: contextname
170 };
171 var message = M.util.get_string('role' + action + 'info', 'core_role', confirmationDetails);
172 if (panel === null) {
173 panel = new M.core.dialogue({
174 draggable: true,
175 modal: true,
176 closeButton: true,
177 width: '450px'
178 });
179 }
180 panel.set('headerContent', M.util.get_string('role' + action + 'header', 'core_role'));
24935689 181
e7ecb4a9 182 var i, existingrolelinks;
24935689 183
e7ecb4a9
DP
184 var roles = [];
185 switch (action) {
186 case 'allow':
187 existingrolelinks = row.find(SELECTORS.REMOVEROLE);
188 break;
189 case 'prohibit':
190 existingrolelinks = row.find(SELECTORS.UNPROHIBIT);
191 break;
192 }
193 for (i in overideableroles) {
194 var disabled = '';
195 var disable = existingrolelinks.filter("[data-role-id='" + i + "']").length;
196 if (disable) {
197 disabled = 'disabled';
198 }
199 var roledetails = {roleid: i, rolename: overideableroles[i], disabled: disabled};
200 roles.push(roledetails);
24935689 201 }
24935689 202
e7ecb4a9
DP
203 templates.render('core/permissionmanager_panelcontent', {message: message, roles: roles})
204 .done(function(content) {
205 panel.set('bodyContent', content);
206 panel.show();
374d3e77 207 $('div.role_buttons').on('click', 'button', function(e) {
e7ecb4a9
DP
208 var roleid = $(e.currentTarget).data('role-id');
209 changePermissions(row, roleid, action);
210 });
211 })
212 .fail(notification.exception);
24935689 213
e7ecb4a9 214 });
24935689
MM
215 });
216 loadOverideableRoles();
217 };
218
219 /**
220 * Prompts user when removing permission
221 *
222 * @access private
223 * @method handleRemoveRole
224 * @param {event} e
225 */
35be5826 226 var handleRemoveRole = function(e) {
24935689 227 e.preventDefault();
b1078b18 228 var link = $(e.currentTarget);
24935689 229 $('body').one('rolesloaded', function() {
24935689
MM
230 var action = link.data('action');
231 var roleid = link.data('role-id');
232 var row = link.closest('tr.rolecap');
233 var questionDetails = {
234 role: overideableroles[roleid],
235 cap: row.data('humanname'),
236 context: contextname
237 };
238
239 notification.confirm(M.util.get_string('confirmunassigntitle', 'core_role'),
35be5826 240 M.util.get_string('confirmrole' + action, 'core_role', questionDetails),
24935689
MM
241 M.util.get_string('confirmunassignyes', 'core_role'),
242 M.util.get_string('confirmunassignno', 'core_role'),
35be5826 243 function() {
24935689
MM
244 changePermissions(row, roleid, action);
245 }
246 );
247 });
248 loadOverideableRoles();
249 };
250
251 return /** @alias module:core/permissionmanager */ {
252 /**
253 * Initialize permissionmanager
254 * @access public
c96f55e6 255 * @param {Object} args
24935689 256 */
35be5826 257 initialize: function(args) {
24935689
MM
258 contextid = args.contextid;
259 contextname = args.contextname;
260 adminurl = args.adminurl;
261 var body = $('body');
f12bc65f
SR
262 body.on('click', SELECTORS.ADDROLE, handleAddRole);
263 body.on('click', SELECTORS.REMOVEROLE, handleRemoveRole);
24935689
MM
264 }
265 };
c96f55e6 266});