Mercurial > hg > rc1
comparison plugins/acl/acl.js @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
| author | Charlie Root |
|---|---|
| date | Thu, 04 Jan 2018 15:50:29 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1e000243b222 |
|---|---|
| 1 /** | |
| 2 * ACL plugin script | |
| 3 */ | |
| 4 | |
| 5 if (window.rcmail) { | |
| 6 rcmail.addEventListener('init', function() { | |
| 7 if (rcmail.gui_objects.acltable) { | |
| 8 rcmail.acl_list_init(); | |
| 9 // enable autocomplete on user input | |
| 10 if (rcmail.env.acl_users_source) { | |
| 11 var inst = rcmail.is_framed() ? parent.rcmail : rcmail; | |
| 12 inst.init_address_input_events($('#acluser'), {action:'settings/plugin.acl-autocomplete'}); | |
| 13 | |
| 14 // pass config settings and localized texts to autocomplete context | |
| 15 inst.set_env({ autocomplete_max:rcmail.env.autocomplete_max, autocomplete_min_length:rcmail.env.autocomplete_min_length }); | |
| 16 inst.add_label('autocompletechars', rcmail.labels.autocompletechars); | |
| 17 inst.add_label('autocompletemore', rcmail.labels.autocompletemore); | |
| 18 | |
| 19 // fix inserted value | |
| 20 inst.addEventListener('autocomplete_insert', function(e) { | |
| 21 if (e.field.id != 'acluser') | |
| 22 return; | |
| 23 | |
| 24 e.field.value = e.insert.replace(/[ ,;]+$/, ''); | |
| 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 if (rcmail.env.acl_advanced) | |
| 33 $('#acl-switch').addClass('selected'); | |
| 34 }); | |
| 35 } | |
| 36 | |
| 37 // Display new-entry form | |
| 38 rcube_webmail.prototype.acl_create = function() | |
| 39 { | |
| 40 this.acl_init_form(); | |
| 41 } | |
| 42 | |
| 43 // Display ACL edit form | |
| 44 rcube_webmail.prototype.acl_edit = function() | |
| 45 { | |
| 46 // @TODO: multi-row edition | |
| 47 var id = this.acl_list.get_single_selection(); | |
| 48 if (id) | |
| 49 this.acl_init_form(id); | |
| 50 } | |
| 51 | |
| 52 // ACL entry delete | |
| 53 rcube_webmail.prototype.acl_delete = function() | |
| 54 { | |
| 55 var users = this.acl_get_usernames(); | |
| 56 | |
| 57 if (users && users.length && confirm(this.get_label('acl.deleteconfirm'))) { | |
| 58 this.http_post('settings/plugin.acl', { | |
| 59 _act: 'delete', | |
| 60 _user: users.join(','), | |
| 61 _mbox: this.env.mailbox | |
| 62 }, | |
| 63 this.set_busy(true, 'acl.deleting')); | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 // Save ACL data | |
| 68 rcube_webmail.prototype.acl_save = function() | |
| 69 { | |
| 70 var data, type, rights = '', user = $('#acluser', this.acl_form).val(); | |
| 71 | |
| 72 $((this.env.acl_advanced ? '#advancedrights :checkbox' : '#simplerights :checkbox'), this.acl_form).map(function() { | |
| 73 if (this.checked) | |
| 74 rights += this.value; | |
| 75 }); | |
| 76 | |
| 77 if (type = $('input:checked[name=usertype]', this.acl_form).val()) { | |
| 78 if (type != 'user') | |
| 79 user = type; | |
| 80 } | |
| 81 | |
| 82 if (!user) { | |
| 83 alert(this.get_label('acl.nouser')); | |
| 84 return; | |
| 85 } | |
| 86 if (!rights) { | |
| 87 alert(this.get_label('acl.norights')); | |
| 88 return; | |
| 89 } | |
| 90 | |
| 91 data = { | |
| 92 _act: 'save', | |
| 93 _user: user, | |
| 94 _acl: rights, | |
| 95 _mbox: this.env.mailbox | |
| 96 } | |
| 97 | |
| 98 if (this.acl_id) { | |
| 99 data._old = this.acl_id; | |
| 100 } | |
| 101 | |
| 102 this.http_post('settings/plugin.acl', data, this.set_busy(true, 'acl.saving')); | |
| 103 } | |
| 104 | |
| 105 // Cancel/Hide form | |
| 106 rcube_webmail.prototype.acl_cancel = function() | |
| 107 { | |
| 108 this.ksearch_blur(); | |
| 109 this.acl_popup.dialog('close'); | |
| 110 } | |
| 111 | |
| 112 // Update data after save (and hide form) | |
| 113 rcube_webmail.prototype.acl_update = function(o) | |
| 114 { | |
| 115 // delete old row | |
| 116 if (o.old) | |
| 117 this.acl_remove_row(o.old); | |
| 118 // make sure the same ID doesn't exist | |
| 119 else if (this.env.acl[o.id]) | |
| 120 this.acl_remove_row(o.id); | |
| 121 | |
| 122 // add new row | |
| 123 this.acl_add_row(o, true); | |
| 124 // hide autocomplete popup | |
| 125 this.ksearch_blur(); | |
| 126 // hide form | |
| 127 this.acl_popup.dialog('close'); | |
| 128 } | |
| 129 | |
| 130 // Switch table display mode | |
| 131 rcube_webmail.prototype.acl_mode_switch = function(elem) | |
| 132 { | |
| 133 this.env.acl_advanced = !this.env.acl_advanced; | |
| 134 this.enable_command('acl-delete', 'acl-edit', false); | |
| 135 this.http_request('settings/plugin.acl', '_act=list' | |
| 136 + '&_mode='+(this.env.acl_advanced ? 'advanced' : 'simple') | |
| 137 + '&_mbox='+urlencode(this.env.mailbox), | |
| 138 this.set_busy(true, 'loading')); | |
| 139 } | |
| 140 | |
| 141 // ACL table initialization | |
| 142 rcube_webmail.prototype.acl_list_init = function() | |
| 143 { | |
| 144 var method = this.env.acl_advanced ? 'addClass' : 'removeClass'; | |
| 145 | |
| 146 $('#acl-switch')[method]('selected'); | |
| 147 $(this.gui_objects.acltable)[method]('advanced'); | |
| 148 | |
| 149 this.acl_list = new rcube_list_widget(this.gui_objects.acltable, | |
| 150 {multiselect: true, draggable: false, keyboard: true}); | |
| 151 this.acl_list.addEventListener('select', function(o) { rcmail.acl_list_select(o); }) | |
| 152 .addEventListener('dblclick', function(o) { rcmail.acl_list_dblclick(o); }) | |
| 153 .addEventListener('keypress', function(o) { rcmail.acl_list_keypress(o); }) | |
| 154 .init(); | |
| 155 } | |
| 156 | |
| 157 // ACL table row selection handler | |
| 158 rcube_webmail.prototype.acl_list_select = function(list) | |
| 159 { | |
| 160 rcmail.enable_command('acl-delete', list.selection.length > 0); | |
| 161 rcmail.enable_command('acl-edit', list.selection.length == 1); | |
| 162 list.focus(); | |
| 163 } | |
| 164 | |
| 165 // ACL table double-click handler | |
| 166 rcube_webmail.prototype.acl_list_dblclick = function(list) | |
| 167 { | |
| 168 this.acl_edit(); | |
| 169 } | |
| 170 | |
| 171 // ACL table keypress handler | |
| 172 rcube_webmail.prototype.acl_list_keypress = function(list) | |
| 173 { | |
| 174 if (list.key_pressed == list.ENTER_KEY) | |
| 175 this.command('acl-edit'); | |
| 176 else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY) | |
| 177 if (!this.acl_form || !this.acl_form.is(':visible')) | |
| 178 this.command('acl-delete'); | |
| 179 } | |
| 180 | |
| 181 // Reloads ACL table | |
| 182 rcube_webmail.prototype.acl_list_update = function(html) | |
| 183 { | |
| 184 $(this.gui_objects.acltable).html(html); | |
| 185 this.acl_list_init(); | |
| 186 } | |
| 187 | |
| 188 // Returns names of users in selected rows | |
| 189 rcube_webmail.prototype.acl_get_usernames = function() | |
| 190 { | |
| 191 var users = [], n, len, cell, row, | |
| 192 list = this.acl_list, | |
| 193 selection = list.get_selection(); | |
| 194 | |
| 195 for (n=0, len=selection.length; n<len; n++) { | |
| 196 if (this.env.acl_specials.length && $.inArray(selection[n], this.env.acl_specials) >= 0) { | |
| 197 users.push(selection[n]); | |
| 198 } | |
| 199 else if (row = list.rows[selection[n]]) { | |
| 200 cell = $('td.user', row.obj); | |
| 201 if (cell.length == 1) | |
| 202 users.push(cell.text()); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 return users; | |
| 207 } | |
| 208 | |
| 209 // Removes ACL table row | |
| 210 rcube_webmail.prototype.acl_remove_row = function(id) | |
| 211 { | |
| 212 var list = this.acl_list; | |
| 213 | |
| 214 list.remove_row(id); | |
| 215 list.clear_selection(); | |
| 216 | |
| 217 // we don't need it anymore (remove id conflict) | |
| 218 $('#rcmrow'+id).remove(); | |
| 219 this.env.acl[id] = null; | |
| 220 | |
| 221 this.enable_command('acl-delete', list.selection.length > 0); | |
| 222 this.enable_command('acl-edit', list.selection.length == 1); | |
| 223 } | |
| 224 | |
| 225 // Adds ACL table row | |
| 226 rcube_webmail.prototype.acl_add_row = function(o, sel) | |
| 227 { | |
| 228 var n, len, ids = [], spec = [], id = o.id, list = this.acl_list, | |
| 229 items = this.env.acl_advanced ? [] : this.env.acl_items, | |
| 230 table = this.gui_objects.acltable, | |
| 231 row = $('thead > tr', table).clone(); | |
| 232 | |
| 233 // Update new row | |
| 234 $('th', row).map(function() { | |
| 235 var td = $('<td>'), | |
| 236 title = $(this).attr('title'), | |
| 237 cl = this.className.replace(/^acl/, ''); | |
| 238 | |
| 239 if (title) | |
| 240 td.attr('title', title); | |
| 241 | |
| 242 if (items && items[cl]) | |
| 243 cl = items[cl]; | |
| 244 | |
| 245 if (cl == 'user') | |
| 246 td.addClass(cl).append($('<a>').text(o.username)); | |
| 247 else | |
| 248 td.addClass(this.className + ' ' + rcmail.acl_class(o.acl, cl)).text(''); | |
| 249 | |
| 250 $(this).replaceWith(td); | |
| 251 }); | |
| 252 | |
| 253 row.attr('id', 'rcmrow'+id); | |
| 254 row = row.get(0); | |
| 255 | |
| 256 this.env.acl[id] = o.acl; | |
| 257 | |
| 258 // sorting... (create an array of user identifiers, then sort it) | |
| 259 for (n in this.env.acl) { | |
| 260 if (this.env.acl[n]) { | |
| 261 if (this.env.acl_specials.length && $.inArray(n, this.env.acl_specials) >= 0) | |
| 262 spec.push(n); | |
| 263 else | |
| 264 ids.push(n); | |
| 265 } | |
| 266 } | |
| 267 ids.sort(); | |
| 268 // specials on the top | |
| 269 ids = spec.concat(ids); | |
| 270 | |
| 271 // find current id | |
| 272 for (n=0, len=ids.length; n<len; n++) | |
| 273 if (ids[n] == id) | |
| 274 break; | |
| 275 | |
| 276 // add row | |
| 277 if (n && n < len) { | |
| 278 $('#rcmrow'+ids[n-1]).after(row); | |
| 279 list.init_row(row); | |
| 280 list.rowcount++; | |
| 281 } | |
| 282 else | |
| 283 list.insert_row(row); | |
| 284 | |
| 285 if (sel) | |
| 286 list.select_row(o.id); | |
| 287 } | |
| 288 | |
| 289 // Initializes and shows ACL create/edit form | |
| 290 rcube_webmail.prototype.acl_init_form = function(id) | |
| 291 { | |
| 292 var ul, row, td, val = '', type = 'user', li_elements, body = $('body'), | |
| 293 adv_ul = $('#advancedrights'), sim_ul = $('#simplerights'), | |
| 294 name_input = $('#acluser'), type_list = $('#usertype'); | |
| 295 | |
| 296 if (!this.acl_form) { | |
| 297 var fn = function () { $('input[value="user"]').prop('checked', true); }; | |
| 298 name_input.click(fn).keypress(fn); | |
| 299 } | |
| 300 | |
| 301 this.acl_form = $('#aclform'); | |
| 302 | |
| 303 // Hide unused items | |
| 304 if (this.env.acl_advanced) { | |
| 305 adv_ul.show(); | |
| 306 sim_ul.hide(); | |
| 307 ul = adv_ul; | |
| 308 } | |
| 309 else { | |
| 310 sim_ul.show(); | |
| 311 adv_ul.hide(); | |
| 312 ul = sim_ul; | |
| 313 } | |
| 314 | |
| 315 // initialize form fields | |
| 316 li_elements = $(':checkbox', ul); | |
| 317 li_elements.attr('checked', false); | |
| 318 | |
| 319 if (id && (row = this.acl_list.rows[id])) { | |
| 320 row = row.obj; | |
| 321 li_elements.map(function() { | |
| 322 td = $('td.'+this.id, row); | |
| 323 if (td.length && td.hasClass('enabled')) | |
| 324 this.checked = true; | |
| 325 }); | |
| 326 | |
| 327 if (!this.env.acl_specials.length || $.inArray(id, this.env.acl_specials) < 0) | |
| 328 val = $('td.user', row).text(); | |
| 329 else | |
| 330 type = id; | |
| 331 } | |
| 332 // mark read (lrs) rights by default | |
| 333 else { | |
| 334 li_elements.filter(function() { return this.id.match(/^acl([lrs]|read)$/); }).prop('checked', true); | |
| 335 } | |
| 336 | |
| 337 name_input.val(val); | |
| 338 $('input[value='+type+']').prop('checked', true); | |
| 339 | |
| 340 this.acl_id = id; | |
| 341 | |
| 342 var buttons = {}, me = this, body = document.body; | |
| 343 | |
| 344 buttons[this.get_label('save')] = function(e) { me.command('acl-save'); }; | |
| 345 buttons[this.get_label('cancel')] = function(e) { me.command('acl-cancel'); }; | |
| 346 | |
| 347 // display it as popup | |
| 348 this.acl_popup = this.show_popup_dialog( | |
| 349 this.acl_form.show(), | |
| 350 id ? this.get_label('acl.editperms') : this.get_label('acl.newuser'), | |
| 351 buttons, | |
| 352 { | |
| 353 button_classes: ['mainaction'], | |
| 354 modal: true, | |
| 355 closeOnEscape: true, | |
| 356 close: function(e, ui) { | |
| 357 (me.is_framed() ? parent.rcmail : me).ksearch_hide(); | |
| 358 me.acl_form.appendTo(body).hide(); | |
| 359 $(this).remove(); | |
| 360 window.focus(); // focus iframe | |
| 361 } | |
| 362 } | |
| 363 ); | |
| 364 | |
| 365 if (type == 'user') | |
| 366 name_input.focus(); | |
| 367 else | |
| 368 $('input:checked', type_list).focus(); | |
| 369 } | |
| 370 | |
| 371 // Returns class name according to ACL comparison result | |
| 372 rcube_webmail.prototype.acl_class = function(acl1, acl2) | |
| 373 { | |
| 374 var i, len, found = 0; | |
| 375 | |
| 376 acl1 = String(acl1); | |
| 377 acl2 = String(acl2); | |
| 378 | |
| 379 for (i=0, len=acl2.length; i<len; i++) | |
| 380 if (acl1.indexOf(acl2[i]) > -1) | |
| 381 found++; | |
| 382 | |
| 383 if (found == len) | |
| 384 return 'enabled'; | |
| 385 else if (found) | |
| 386 return 'partial'; | |
| 387 | |
| 388 return 'disabled'; | |
| 389 } |
