]> git.donarmstrong.com Git - roundcube.git/blob - plugins/acl/acl.js
Imported Upstream version 0.7
[roundcube.git] / plugins / acl / acl.js
1 /**
2  * ACL plugin script
3  *
4  * @version 0.6.3
5  * @author Aleksander Machniak <alec@alec.pl>
6  */
7
8 if (window.rcmail) {
9     rcmail.addEventListener('init', function() {
10         if (rcmail.gui_objects.acltable) {
11             rcmail.acl_list_init();
12             // enable autocomplete on user input
13             if (rcmail.env.acl_users_source) {
14                 rcmail.init_address_input_events($('#acluser'), {action:'settings/plugin.acl-autocomplete'});
15                 // fix inserted value
16                 rcmail.addEventListener('autocomplete_insert', function(e) {
17                     if (e.field.id != 'acluser')
18                         return;
19
20                     var value = e.insert;
21                     // get UID from the entry value
22                     if (value.match(/\s*\(([^)]+)\)[, ]*$/))
23                         value = RegExp.$1;
24                     e.field.value = value;
25                 });
26             }
27         }
28
29         rcmail.enable_command('acl-create', 'acl-save', 'acl-cancel', 'acl-mode-switch', true);
30         rcmail.enable_command('acl-delete', 'acl-edit', false);
31     });
32 }
33
34 // Display new-entry form
35 rcube_webmail.prototype.acl_create = function()
36 {
37     this.acl_init_form();
38 }
39
40 // Display ACL edit form
41 rcube_webmail.prototype.acl_edit = function()
42 {
43     // @TODO: multi-row edition
44     var id = this.acl_list.get_single_selection();
45     if (id)
46         this.acl_init_form(id);
47 }
48
49 // ACL entry delete
50 rcube_webmail.prototype.acl_delete = function()
51 {
52     var users = this.acl_get_usernames();
53
54     if (users && users.length && confirm(this.get_label('acl.deleteconfirm'))) {
55         this.http_request('settings/plugin.acl', '_act=delete&_user='+urlencode(users.join(','))
56             + '&_mbox='+urlencode(this.env.mailbox),
57             this.set_busy(true, 'acl.deleting'));
58     }
59 }
60
61 // Save ACL data
62 rcube_webmail.prototype.acl_save = function()
63 {
64     var user = $('#acluser').val(), rights = '', type;
65
66     $(':checkbox', this.env.acl_advanced ? $('#advancedrights') : sim_ul = $('#simplerights')).map(function() {
67         if (this.checked)
68             rights += this.value;
69     });
70
71     if (type = $('input:checked[name=usertype]').val()) {
72         if (type != 'user')
73             user = type;
74     }
75
76     if (!user) {
77         alert(this.get_label('acl.nouser'));
78         return;
79     }
80     if (!rights) {
81         alert(this.get_label('acl.norights'));
82         return;
83     }
84
85     this.http_request('settings/plugin.acl', '_act=save'
86         + '&_user='+urlencode(user)
87         + '&_acl=' +rights
88         + '&_mbox='+urlencode(this.env.mailbox)
89         + (this.acl_id ? '&_old='+this.acl_id : ''),
90         this.set_busy(true, 'acl.saving'));
91 }
92
93 // Cancel/Hide form
94 rcube_webmail.prototype.acl_cancel = function()
95 {
96     this.ksearch_blur();
97     this.acl_form.hide();
98 }
99
100 // Update data after save (and hide form)
101 rcube_webmail.prototype.acl_update = function(o)
102 {
103     // delete old row
104     if (o.old)
105         this.acl_remove_row(o.old);
106     // make sure the same ID doesn't exist
107     else if (this.env.acl[o.id])
108         this.acl_remove_row(o.id);
109
110     // add new row
111     this.acl_add_row(o, true);
112     // hide autocomplete popup
113     this.ksearch_blur();
114     // hide form
115     this.acl_form.hide();
116 }
117
118 // Switch table display mode
119 rcube_webmail.prototype.acl_mode_switch = function(elem)
120 {
121     this.env.acl_advanced = !this.env.acl_advanced;
122     this.enable_command('acl-delete', 'acl-edit', false);
123     this.http_request('settings/plugin.acl', '_act=list'
124         + '&_mode='+(this.env.acl_advanced ? 'advanced' : 'simple')
125         + '&_mbox='+urlencode(this.env.mailbox),
126         this.set_busy(true, 'loading'));
127 }
128
129 // ACL table initialization
130 rcube_webmail.prototype.acl_list_init = function()
131 {
132     this.acl_list = new rcube_list_widget(this.gui_objects.acltable,
133         {multiselect:true, draggable:false, keyboard:true, toggleselect:true});
134     this.acl_list.addEventListener('select', function(o) { rcmail.acl_list_select(o); });
135     this.acl_list.addEventListener('dblclick', function(o) { rcmail.acl_list_dblclick(o); });
136     this.acl_list.addEventListener('keypress', function(o) { rcmail.acl_list_keypress(o); });
137     this.acl_list.init();
138 }
139
140 // ACL table row selection handler
141 rcube_webmail.prototype.acl_list_select = function(list)
142 {
143     rcmail.enable_command('acl-delete', list.selection.length > 0);
144     rcmail.enable_command('acl-edit', list.selection.length == 1);
145     list.focus();
146 }
147
148 // ACL table double-click handler
149 rcube_webmail.prototype.acl_list_dblclick = function(list)
150 {
151     this.acl_edit();
152 }
153
154 // ACL table keypress handler
155 rcube_webmail.prototype.acl_list_keypress = function(list)
156 {
157     if (list.key_pressed == list.ENTER_KEY)
158         this.command('acl-edit');
159     else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY)
160         if (!this.acl_form || !this.acl_form.is(':visible'))
161             this.command('acl-delete');
162 }
163
164 // Reloads ACL table
165 rcube_webmail.prototype.acl_list_update = function(html)
166 {
167     $(this.gui_objects.acltable).html(html);
168     this.acl_list_init();
169 }
170
171 // Returns names of users in selected rows
172 rcube_webmail.prototype.acl_get_usernames = function()
173 {
174     var users = [], n, len, cell, row,
175         list = this.acl_list,
176         selection = list.get_selection();
177
178     for (n=0, len=selection.length; n<len; n++) {
179         if (this.env.acl_specials.length && $.inArray(selection[n], this.env.acl_specials) >= 0) {
180             users.push(selection[n]);
181         }
182         else {
183             row = list.rows[selection[n]].obj;
184             cell = $('td.user', row);
185             if (cell.length == 1)
186                 users.push(cell.text());
187         }
188     }
189
190     return users;
191 }
192
193 // Removes ACL table row
194 rcube_webmail.prototype.acl_remove_row = function(id)
195 {
196     this.acl_list.remove_row(id);
197     // we don't need it anymore (remove id conflict)
198     $('#rcmrow'+id).remove();
199     this.env.acl[id] = null;
200 }
201
202 // Adds ACL table row
203 rcube_webmail.prototype.acl_add_row = function(o, sel)
204 {
205     var n, len, ids = [], spec = [], id = o.id, list = this.acl_list,
206         items = this.env.acl_advanced ? [] : this.env.acl_items,
207         table = this.gui_objects.acltable,
208         row = $('thead > tr', table).clone();
209
210     // Update new row
211     $('td', row).map(function() {
212         var r, cl = this.className.replace(/^acl/, '');
213
214         if (items && items[cl])
215             cl = items[cl];
216
217         if (cl == 'user')
218             $(this).text(o.username);
219         else
220             $(this).addClass(rcmail.acl_class(o.acl, cl)).text('');
221     });
222
223     row.attr('id', 'rcmrow'+id);
224     row = row.get(0);
225
226     this.env.acl[id] = o.acl;
227
228     // sorting... (create an array of user identifiers, then sort it)
229     for (n in this.env.acl) {
230         if (this.env.acl[n]) {
231             if (this.env.acl_specials.length && $.inArray(n, this.env.acl_specials) >= 0)
232                 spec.push(n);
233             else
234                 ids.push(n);
235         }
236     }
237     ids.sort();
238     // specials on the top
239     ids = spec.concat(ids);
240
241     // find current id
242     for (n=0, len=ids.length; n<len; n++)
243         if (ids[n] == id)
244             break;
245
246     // add row
247     if (n && n < len) {
248         $('#rcmrow'+ids[n-1]).after(row);
249         list.init_row(row);
250         list.rowcount++;
251     }
252     else
253         list.insert_row(row);
254
255     if (sel)
256         list.select_row(o.id);
257 }
258
259 // Initializes and shows ACL create/edit form
260 rcube_webmail.prototype.acl_init_form = function(id)
261 {
262     var ul, row, val = '', type = 'user', li_elements, body = $('body'),
263         adv_ul = $('#advancedrights'), sim_ul = $('#simplerights'),
264         name_input = $('#acluser');
265
266     if (!this.acl_form) {
267         var fn = function () { $('input[value=user]').prop('checked', true); };
268         name_input.click(fn).keypress(fn);
269     }
270
271     this.acl_form = $('#aclform');
272
273     // Hide unused items
274     if (this.env.acl_advanced) {
275         adv_ul.show();
276         sim_ul.hide();
277         ul = adv_ul;
278     }
279     else {
280         sim_ul.show();
281         adv_ul.hide();
282         ul = sim_ul;
283     }
284
285     // initialize form fields
286     li_elements = $(':checkbox', ul);
287     li_elements.attr('checked', false);
288
289     if (id) {
290         row = this.acl_list.rows[id].obj;
291         li_elements.map(function() {
292             var val = this.value, td = $('td.'+this.id, row);
293             if (td && td.hasClass('enabled'))
294                 this.checked = true;
295         });
296
297         if (!this.env.acl_specials.length || $.inArray(id, this.env.acl_specials) < 0)
298             val = $('td.user', row).text();
299         else
300             type = id;
301     }
302
303     name_input.val(val);
304     $('input[value='+type+']').prop('checked', true);
305
306     this.acl_id = id;
307
308     // position the form horizontally
309     var bw = body.width(), mw = this.acl_form.width();
310
311     if (bw >= mw)
312         this.acl_form.css({left: parseInt((bw - mw)/2)+'px'});
313
314     // display it
315     this.acl_form.show();
316     if (type == 'user')
317         name_input.focus();
318
319     // unfocus the list, make backspace key in name input field working
320     this.acl_list.blur();
321 }
322
323 // Returns class name according to ACL comparision result
324 rcube_webmail.prototype.acl_class = function(acl1, acl2)
325 {
326     var i, len, found = 0;
327
328     acl1 = String(acl1);
329     acl2 = String(acl2);
330
331     for (i=0, len=acl2.length; i<len; i++)
332         if (acl1.indexOf(acl2[i]) > -1)
333             found++;
334
335     if (found == len)
336         return 'enabled';
337     else if (found)
338         return 'partial';
339
340     return 'disabled';
341 }