blob: d4744829f010b8c8f316f849542a049d22b5a2df [file] [log] [blame]
Valentin Valcheveddfbc42012-08-21 20:06:24 +00001/* your java script code here */
2
3var userTree = false;
4var selectedRole = false;
5var newDialogRole = false;
6var roleDetails = false;
7var roleDetailsHelp = false;
8var roleDetailsTable = false;
9var roleDetailsBody = false;
10var roleDetailsTemplate = false;
11var roleDetailsTemplateP = false;
12var roleDetailsTemplateC = false;
13
14function roleObj(node) {
15 node = node && node.attr ? node.attr('role') : false;
16 return node ? JSON.parse(node) : false;
17}
18
19var treeSettings = {
20 data : {
21 type : 'json',
22 opts : { 'static' : [] }
23 },
24 ui : { theme_name : 'themeroller' },
25 rules : { multiple : false, valid_children: ['root'] },
26 types : {
27 root : { valid_children: ['t0', 't1', 't2'] },
28 t2 : { valid_children: ['t0', 't1', 't2'] },
29 t1 : { valid_children: 'none' },
30 t0 : { valid_children: 'none' }
31 },
32 callback : {
33 onselect : function(node) {
34 var _role = $(node).attr('role');
35 if (_role) {
36 var role = JSON.parse( _role );
37 onSelectNode(role.name);
38 $(node).children('a').addClass('ui-priority-primary');
39 } else {
40 roleDetailsHelp.removeClass('ui-helper-hidden');
41 roleDetailsTable.addClass('ui-helper-hidden');
42 }
43 },
44 onparse : function (s, t) {
45 return $(s)
46 .find('li[rel=t2] > a > ins').addClass('ui-icon ui-icon-contact').end()
47 .find('li[rel=t1] > a > ins').addClass('ui-icon ui-icon-person').end()
48 .find('li[rel=t0] > a > ins').addClass('ui-icon ui-icon-bullet').end();
49 },
50 ondeselect : function(node) { $(node).children('a').removeClass('ui-priority-primary') },
51 ondblclk : function(node, tree_obj) {
52 var n = $(node);
53 var pp = tree_obj.parent(node);
54 var r = roleObj(n);
55 var g = roleObj(pp);
56 console.log(r, g);
57 if (r && g) {
58 if( isInMemberArray(r, g.members, 1) ) {
59 $.post(pluginRoot, { action: 'removeMember', role: r.name, group: g.name });
60 $.post(pluginRoot, { action: 'addRequiredMember', role: r.name, group: g.name }, function(data) {
61 pp.attr('role', JSON.stringify(data));
62 }, 'json');
63 n.addClass('required');
64 } else if( isInMemberArray(r, g.rmembers, 1) ) {
65 $.post(pluginRoot, { action: 'removeMember', role: r.name, group: g.name });
66 $.post(pluginRoot, { action: 'addMember', role: r.name, group: g.name }, function(data) {
67 pp.attr('role', JSON.stringify(data));
68 }, 'json');
69 n.removeClass('required');
70 }
71 }
72 },
73 beforemove : function(node, ref_node, type, tree_obj, is_copy) {
74 var _ = dragObj(node, ref_node, type, tree_obj);
75 // --- check if the move is valid:
76 // don't move things around the same/root level
77 if (_.to == false && _.from == false) return false;
78 // no copy to the root folder
79 if (is_copy && _.to == false) return false;
80 // no rearrange withing the folder
81 if (_.to != false && _.from != false && _.to.name == _.from.name) return false;
82 // already contains such a member
83 if (_.to != false && isMember(_.node, _.to)) return false;
84
85 // do copy-move
86 // unassign from the old group, if it is move
87 if (!is_copy && _.from) $.post(pluginRoot, {'action': 'removeMember', 'role' : _.node.name, 'group' : _.from.name} , function(data) {}, 'json');
88 // assign to the new group
89 if (_.to) $.post(pluginRoot, {'action': 'addMember', 'role' : _.node.name, 'group' : _.to.name} , function(data) {}, 'json');
90
91 return true;
92 }
93 }
94}
95
96$(function() {
97 userTree = $('#userTree');
98 roleDetails = $('#roleDetails');
99 roleDetailsTable = roleDetails.find('table');
100 roleDetailsHelp = roleDetails.find('#roleDetailsHelp');
101 roleDetailsBody = roleDetailsTable.find('tbody');
102 roleDetailsTemplateP = roleDetailsBody.find('tr:eq(0)');
103 roleDetailsTemplateC = roleDetailsBody.find('tr:eq(1)');
104 roleDetailsTemplate = roleDetailsBody.find('tr:eq(2)').clone();
105 roleDetailsBody.find('tr').not('.header').remove();
106
107 // add new property/credential code
108 $('tr.header span.ui-icon-plus').click(function() {
109 $(this).parent().parent().parent().parent().after(newProp());
110 });
111
112 // new role dialog
113 var _buttons = {};
114 _buttons[i18n.close] = function() {
115 $(this).dialog('close');
116 }
117 _buttons[i18n.add] = function() {
118 var _ = newDialogRole;
119 var n = _.find('input');
120 if (!n.val()) {
121 n.addClass('ui-state-error');
122 return false;
123 } else n.removeClass('ui-state-error');
124 var t = _.find('select').val();
125 $.post(pluginRoot, {'action': 'set', 'data' : JSON.stringify({'name': n.val(), 'type': new Number(t)})} , function(data) {
126 _.dialog('close');
127 $('#reload').click();
128 }, 'json');
129 }
130 newDialogRole = $("#newDialogRole").dialog({
131 autoOpen : false,
132 modal : true,
133 open : function() { $(this).find('input').val('').removeClass('ui-state-error') },
134 closeText: i18n.abort,
135 buttons : _buttons
136 });
137
138 // role info buttons
139 $('#delRole').click( function() {
140 if (selectedRole) $.post(pluginRoot, {'action': 'del', 'role' : selectedRole}, function() {
141 $('#reload').click();
142 });
143 });
144 $('#savRole').click( doSaveRole );
145
146 // top-frame buttons
147 $('#newRole').click( function() {
148 newDialogRole.dialog('open');
149 return false;
150 });
151 $('#reload').click( function() {
152 $.post(pluginRoot, {'action': 'list'} , function(data) {
153 roleDetailsHelp.removeClass('ui-helper-hidden');
154 roleDetailsTable.addClass('ui-helper-hidden');
155
156 var sortedGroups = sortGroups(data);
157 var treeRoot = buildTree(sortedGroups);
158
159 treeSettings.data.opts['static'] = treeRoot;
160 userTree.empty().tree(treeSettings);
161 }, 'json');
162 return false;
163 }).click();
164});
165
166function newProp() {
167 var tr = roleDetailsTemplate.clone()
168 .find('li').click( function() {
169 tr.remove();
170 }).end()
171 .find('select').change( function(evt) {
172 tr.find('.v').replaceWith('<input class="v" '+ ($(this).val().indexOf('password') == 0 ? 'type="password"' : '') + '/>');
173 initStaticWidgets(tr);
174 }).end()
175 initStaticWidgets(tr);
176 return tr;
177}
178function hashToArray(s) {
179 var r = [];
180 while(s.length > 0) {
181 r.push(parseInt(s.substring(0, 2), 16));
182 s = s.substring(2);
183 }
184 return r;
185}
186function strToArray(s) {
187 var r = [];
188 var el = s.split(',');
189 for(var i=0;i<el.length;i++) r.push( parseInt(el[i], 10) );
190 return r;
191}
192function doSaveRole() {
193 if (!selectedRole) return;
194 var doProps = true;
195 var data = {
196 name : selectedRole,
197 properties : {},
198 credentials : {}
199 };
200 roleDetailsBody.find('tr').each( function() {
201 var _ = $(this);
202 if (_.hasClass('header-props')) doProps = true;
203 else if (_.hasClass('header-cred')) doProps = false;
204 else {
205 var k = _.find('.k').val();
206 var v = _.find('.v').val();
207 var t = _.find('select').val();
208
209 if (t.indexOf('password-') == 0) {
210 var hash = CryptoJS[t.substring(9)](v).toString(CryptoJS.enc.Hex);
211 v = hashToArray(hash);
212 } else if (t == 'byte[]') {
213 v = strToArray(v);
214 }
215
216 if (doProps) data.properties[k] = v;
217 else data.credentials[k] = v;
218 }
219 });
220 $.post(pluginRoot, {'action': 'set', 'data' : JSON.stringify(data)});
221}
222
223function isInMemberArray(role, g) {
224 if(g) for(var i in g) if (g[i].name == role.name) return true;
225 return false;
226}
227
228function isMember(role, group) {
229 if (!role) return false;
230 if (!group) return false;
231 if (isInMemberArray(role, group.members)) return true;
232 if (isInMemberArray(role, group.rmembers)) return true;
233}
234
235function buildTree(sortedGroups) {
236 var treeRoot = {
237 data : i18n.root,
238 state: 'open',
239 attributes : { 'rel' : 'root' },
240 children: []
241 };
242 var treeNode = function(name, role, parent, req) {
243 if (!role) return;
244 if (!parent) parent = treeRoot.children;
245 var node = {
246 data : role.name,
247 attributes : {
248 'rel' : 't' + role.type,
249 'role' : JSON.stringify(role)
250 }
251 }
252 if (req) node.attributes['class'] = 'required';
253 parent.push(node);
254 if (role.type == 2) {
255 node['children'] = [];
256 node = node['children'];
257 if (role.members) $.each(role.members, function(idx, role) {
258 treeNode(role.name, role, node, 0);
259 });
260 if (role.rmembers) $.each(role.rmembers, function(idx, role) {
261 treeNode(role.name, role, node, 1);
262 });
263 }
264 }
265
266 $.each(sortedGroups, treeNode);
267 return treeRoot;
268}
269
270function sortGroups(data) {
271 var rootGroups = {}; // only root groups - without parents
272 var unassigned = {}; // non-groups, not assigned to any group
273 var processed = {}; // all processed entries
274 var u = 0;
275 var g = 0;
276 var r = 0;
277
278 var _st = function(map, n, role) {
279 if (typeof map[n] == 'undefined') { // not added - add
280 map[n] = role;
281 } else if (map[n] != false) { // already added
282 map[n] = false; // mark for removal
283 }
284 }
285
286 var groupF = function(i1, role) {
287 var n = role.name;
288 var t = role.type;
289
290 if (t == 2) { // group
291 // don't process twice
292 if (processed[n]) {
293 rootGroups[n] = false;
294 return true;
295 }
296 processed[n]=role;
297
298 _st(rootGroups, n, role);
299
300 if (role.members) $.each(role.members, groupF);
301 if (role.rmembers) $.each(role.rmembers, groupF);
302 g++;
303 } else { // role or user
304 if (t == 1) u++; else r++;
305 _st(unassigned, n, role);
306 }
307 }
308
309 $.each(data, groupF);
310 $('.statline').text( i18n.status.msgFormat(g,u,r) );
311
312 return $.extend(rootGroups, unassigned);
313}
314
315function onSelectNode(role) {
316 $.post(pluginRoot, {'action': 'get', 'role' : role} , function(data) {
317 selectedRole = role;
318 roleDetailsHelp.addClass('ui-helper-hidden');
319 roleDetailsTable.removeClass('ui-helper-hidden');
320 roleDetailsBody.find('tr').not('.header').remove();
321
322 var target = false;
323 var _append = function(k,v) {
324 var t = $.isArray(v) ? 'byte[]' : 'string';
325 target.after(newProp()
326 .data('k', k)
327 .find('input.k').val(k).end()
328 .find('input.v').val(v).end()
329 .find('select').val(t).end()
330 );
331 }
332 var x = data.properties;
333 if (x) {
334 target = roleDetailsTemplateP;
335 $.each(x, _append);
336 }
337 x = data.credentials;
338 if (x) {
339 target = roleDetailsTemplateC;
340 $.each(x, _append);
341 }
342 // show/user credentials view if user/or not (respectively)
343 x = roleDetailsBody.find('.header-cred');
344 if (data.type != 1) x.addClass('ui-helper-hidden');
345 else x.removeClass('ui-helper-hidden');
346 }, 'json')
347 return false;
348}
349
350function dragObj(node, ref_node, type, tree_obj) {
351 // determine the destination folder
352 var _role = false;
353 if ('inside' == type) {
354 _role = $(ref_node).attr('role');
355 } else {
356 _role = tree_obj.parent(ref_node)
357 _role = _role.attr ? _role.attr('role') : false;
358 }
359 var to = _role ? JSON.parse(_role) : false;
360 // determine object to move
361 _role = $(node).attr('role');
362 var source = JSON.parse(_role);
363 // determine the previous location (in case it is move, not copy)
364 _role = tree_obj.parent(node);
365 var from = _role.attr && _role.attr('role') ? JSON.parse(_role.attr('role')) : false;
366
367 return {
368 'to' : to,
369 'from' : from,
370 'node' : source
371 }
372}