Implement permissions, part 1. Interface works and is populated with existing permiss...
authorJan Schneider <jan@horde.org>
Mon, 8 Mar 2010 16:16:35 +0000 (17:16 +0100)
committerJan Schneider <jan@horde.org>
Mon, 8 Mar 2010 16:16:35 +0000 (17:16 +0100)
framework/Ajax/lib/Horde/Ajax/Application/Base.php
kronolith/js/kronolith.js
kronolith/lib/Ajax/Application.php
kronolith/lib/Kronolith.php
kronolith/templates/chunks/calendar.php

index 5343348..d81aea7 100644 (file)
@@ -107,17 +107,39 @@ abstract class Horde_Ajax_Application_Base
     }
 
     /**
-     * AJAX action: Logout.
+     * Logs the user off the Horde session.
      *
      * This needs to be done here (server), rather than on the browser,
      * because the logout tokens might otherwise expire.
-     *
-     * @param Horde_Variables $vars  None used.
      */
-    public function logOut($vars)
+    public function logOut()
     {
         Horde::redirect(str_replace('&amp;', '&', Horde::getServiceLink('logout', $this->_app)));
         exit;
     }
 
+    /**
+     * Returns a hash of group IDs and group names that the user has access to.
+     *
+     * @return array  Groups hash.
+     */
+    public function listGroups()
+    {
+        $result = new stdClass;
+        $horde_groups = Group::singleton();
+        if (!empty($GLOBALS['conf']['share']['any_group'])) {
+            $groups = $horde_groups->listGroups();
+        } else {
+            $groups = $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true);
+        }
+        if ($groups) {
+            if ($groups instanceof PEAR_Error) {
+                $groups = array();
+            }
+            asort($groups);
+            $result->groups = $groups;
+        }
+        return $result;
+    }
+
 }
index 4849779..8a1e47c 100644 (file)
@@ -16,7 +16,7 @@ var frames = { horde_main: true },
 KronolithCore = {
     // Vars used and defaulting to null/false:
     //   DMenu, Growler, inAjaxCallback, is_logout,
-    //   daySizes, viewLoading, freeBusy, colorPicker
+    //   daySizes, viewLoading, groupLoading, freeBusy, colorPicker
 
     view: '',
     ecache: $H(),
@@ -2151,13 +2151,28 @@ KronolithCore = {
         var type = calendar[0];
         calendar = calendar.length == 1 ? null : calendar[1];
 
-        var firstTab = $('kronolithCalendarForm' + type).down('.tabset a.kronolithTabLink');
+        var form = $('kronolithCalendarForm' + type),
+            firstTab = form.down('.tabset a.kronolithTabLink'),
+            info;
+
+        this.updateGroupDropDown([['kronolithCalendarPermsGroupList', this.updateGroupPerms.bind(this)],
+                                  ['kronolithCalendarPermsGroupNew']]);
+        form.enable();
+        form.reset();
         if (firstTab) {
             this.openTab(firstTab);
         }
         $('kronolithCalendarDialog').select('.kronolithCalendarDiv').invoke('hide');
         $('kronolithCalendar' + type + '1').show();
-        $('kronolithCalendarForm' + type).select('.kronolithCalendarContinue').invoke('enable');
+        form.select('.kronolithCalendarContinue').invoke('enable');
+        $('kronolithCalendarPermsBasic').show();
+        $('kronolithCalendarPermsAdvanced').hide();
+        $('kronolithCalendarPermsAllShow').disable();
+        $('kronolithCalendarPermsGroupList').disable();
+        $('kronolithCalendarPermsGroupPerms').disable();
+        $('kronolithCalendarPermsAdvanced').select('tr').findAll(function(tr) {
+            return tr.retrieve('remove');
+        }).invoke('remove');
 
         var newCalendar = !calendar;
         if (calendar &&
@@ -2182,29 +2197,20 @@ KronolithCore = {
             }
         }
 
-        /* Reset form to defaults if this is for adding calendars. */
         if (newCalendar) {
-            var fields = [ 'Id', 'Name' ];
             switch (type) {
             case 'internal':
             case 'tasklists':
                 $('kronolithCalendar' + type + 'LinkImportExport').up('span').hide();
-                fields.push('Description');
-                break;
-            case 'remote':
-                fields.push('Description', 'Url', 'Username', 'Password');
                 break;
             }
-            fields.each(function(field) {
-                $('kronolithCalendar' + type + field).clear();
-            });
             $('kronolithCalendar' + type + 'Color').setValue('#dddddd').setStyle({ backgroundColor: '#dddddd', color: '#000' });
-            $('kronolithCalendarForm' + type).down('.kronolithCalendarDelete').hide();
+            form.down('.kronolithCalendarDelete').hide();
             if (calendar && type == 'remote') {
                 $('kronolithCalendarremoteUrl').setValue(calendar);
             }
         } else {
-            var info = Kronolith.conf.calendars[type][calendar];
+            info = Kronolith.conf.calendars[type][calendar];
 
             $('kronolithCalendar' + type + 'Id').setValue(calendar);
             $('kronolithCalendar' + type + 'Name').setValue(info.name);
@@ -2230,11 +2236,7 @@ KronolithCore = {
             }
         }
 
-        /* Currently we only show the calendar form for own calendars anyway,
-           but be prepared. */
-        var form = $('kronolithCalendarForm' + type);
         if (newCalendar || info.owner) {
-            form.enable();
             form.down('.kronolithColorPicker').show();
             if (type == 'internal') {
                 form.down('.kronolithCalendarSubscribe').hide();
@@ -2247,6 +2249,12 @@ KronolithCore = {
             }
             form.down('.kronolithCalendarSave').show();
             form.down('.kronolithFormActions .kronolithSeparator').show();
+            if (type == 'internal' || type == 'tasklists') {
+                $('kronolithCalendar' + type + 'LinkPerms').up('li').show();
+            }
+            if (!Object.isUndefined(info) && info.owner) {
+                this.setPermsFields(info.perms);
+            }
         } else {
             form.disable();
             form.down('.kronolithColorPicker').hide();
@@ -2264,10 +2272,309 @@ KronolithCore = {
             } else {
                 form.down('.kronolithFormActions .kronolithSeparator').hide();
             }
+            if (type == 'internal' || type == 'tasklists') {
+                $('kronolithCalendar' + type + 'LinkPerms').up('li').hide();
+            }
+        }
+    },
+
+    /**
+     * Handles clicks on the radio boxes of the basic permissions screen.
+     *
+     * @param string perm  The permission to activate, 'None', 'All', or
+     *                     'Group'.
+     */
+    permsClickHandler: function(perm)
+    {
+        $('kronolithCalendarPermsAdvanced')
+            .select('input[type=checkbox]')
+            .invoke('setValue', 0);
+        switch (perm) {
+        case 'None':
+            $('kronolithCalendarPermsAllShow').disable();
+            $('kronolithCalendarPermsGroupList').disable();
+            $('kronolithCalendarPermsGroupPerms').disable();
+            break;
+        case 'All':
+            $('kronolithCalendarPermsAllShow').enable();
+            $('kronolithCalendarPermsGroupList').disable();
+            $('kronolithCalendarPermsGroupPerms').disable();
+            var perms = {
+                default: Kronolith.conf.perms.read,
+                guest: Kronolith.conf.perms.read
+            };
+            if ($F('kronolithCalendarPermsAllShow')) {
+                perms.default |= Kronolith.conf.perms.show;
+                perms.guest |= Kronolith.conf.perms.show;
+            }
+            this.setPermsFields(perms);
+            break;
+        case 'Group':
+            $('kronolithCalendarPermsAllShow').disable();
+            $('kronolithCalendarPermsGroupList').enable();
+            $('kronolithCalendarPermsGroupPerms').enable();
+            var group = $F('kronolithCalendarPermsGroupSingle')
+                ? $F('kronolithCalendarPermsGroupSingle')
+                : $F('kronolithCalendarPermsGroupList');
+            this.insertGroupOrUser('group', group);
+            $('kronolithCalendarPermsGroupshow_' + group).setValue(1);
+            $('kronolithCalendarPermsGroupread_' + group).setValue(1);
+            if ($F('kronolithCalendarPermsGroupPerms') == 'edit') {
+                $('kronolithCalendarPermsGroupedit_' + group).setValue(1);
+            } else {
+                $('kronolithCalendarPermsGroupedit_' + group).setValue(0);
+            }
+            $('kronolithCalendarPermsGroupdelete_' + group).setValue(0);
+            $('kronolithCalendarPermsGroupdelegate_' + group).setValue(0);
+            break;
+        }
+    },
+
+    /**
+     * Populates the permissions field matrix.
+     *
+     * @param object perms  An object with the resource permissions.
+     */
+    setPermsFields: function(perms)
+    {
+        if (this.groupLoading) {
+            this.setPermsFields.bind(this, perms).defer();
+            return;
+        }
+
+        var allperms = $H(Kronolith.conf.perms),
+            advanced = false,
+            basic, same, groupPerms, groupId;
+        $H(perms).each(function(perm) {
+            switch (perm.key) {
+            case 'default':
+            case 'guest':
+                if (Object.isUndefined(same)) {
+                    same = perm.value;
+                } else if (Object.isUndefined(basic) &&
+                           same == perm.value &&
+                           (perm.value == Kronolith.conf.perms.read ||
+                            perm.value == Kronolith.conf.perms.read | Kronolith.conf.perms.show)) {
+                    basic = perm.value == Kronolith.conf.perms.read ? 'all_read' : 'all_show';
+                } else if (perm.value != 0) {
+                    advanced = true;
+                }
+                break;
+            case 'creator':
+                if (perm.value != 0) {
+                    advanced = true;
+                }
+                break;
+            case 'groups':
+                $H(perm.value).each(function(group) {
+                    this.insertGroupOrUser('group', group.key);
+                    groupPerms = group.value;
+                    groupId = group.key;
+                }, this);
+                if (Object.isUndefined(basic) &&
+                    $H(perm.value).size() == 1 &&
+                    (groupPerms == Kronolith.conf.perms.show | Kronolith.conf.perms.read ||
+                     groupPerms == Kronolith.conf.perms.show | Kronolith.conf.perms.read | Kronolith.conf.perms.edit)) {
+                    basic = groupPerms == Kronolith.conf.perms.show | Kronolith.conf.perms.read ? 'group_read' : 'group_edit';
+                } else {
+                    advanced = true;
+                }
+                break;
+            case 'users':
+                $H(perm.value).each(function(user) {
+                    if (user.key != Kronolith.conf.user) {
+                        this.insertGroupOrUser('user', user.key);
+                    }
+                }, this);
+                advanced = true;
+                break;
+            }
+
+            allperms.each(function(baseperm) {
+                if (baseperm.key == 'all') {
+                    return;
+                }
+                switch (perm.key) {
+                case 'default':
+                case 'guest':
+                case 'creator':
+                    if (baseperm.value & perm.value) {
+                        $('kronolithCalendarPerms' + perm.key + baseperm.key).setValue(1);
+                    }
+                    break;
+                case 'groups':
+                    $H(perm.value).each(function(group) {
+                        if (baseperm.value & group.value) {
+                            $('kronolithCalendarPermsGroup' + baseperm.key + '_' + group.key).setValue(1);
+                        }
+                    });
+                    break;
+                case 'users':
+                    $H(perm.value).each(function(user) {
+                        if (baseperm.value & user.value &&
+                            user.key != Kronolith.conf.user) {
+                            $('kronolithCalendarPermsUser' + baseperm.key + '_' + user.key).setValue(1);
+                        }
+                    });
+                    break;
+                }
+            });
+        }.bind(this));
+
+        if (advanced) {
+            this.activateAdvancedPerms();
+        } else {
+            switch (basic) {
+            case 'all_read':
+                $('kronolithCalendarPermsAll').setValue(1);
+                $('kronolithCalendarPermsAllShow').setValue(0);
+            case 'all_show':
+                $('kronolithCalendarPermsAll').setValue(1);
+                $('kronolithCalendarPermsAllShow').setValue(1);
+            case 'group_read':
+            case 'group_edit':
+                var setGroup = function(group) {
+                    if ($('kronolithCalendarPermsGroupList').visible()) {
+                        $('kronolithCalendarPermsGroupList').setValue(group);
+                        if ($('kronolithCalendarPermsGroupList').getValue() != group) {
+                            // Group no longer exists.
+                            this.permsClickHandler('None');
+                        }
+                    } else if ($('kronolithCalendarPermsGroupSingle').getValue() != group) {
+                        // Group no longer exists.
+                        this.permsClickHandler('None');
+                    }
+                }.bind(this, groupId);
+                if (this.groupLoading) {
+                    setGroup.defer();
+                } else {
+                    setGroup();
+                }
+                $('kronolithCalendarPermsGroup').setValue(1);
+                $('kronolithCalendarPermsGroupPerms').setValue(basic.substring(6));
+                $('kronolithCalendarPermsAdvanced').hide();
+                $('kronolithCalendarPermsBasic').show();
+            }
+        }
+   },
+
+    /**
+     * Propagates a SELECT drop down list with the groups.
+     *
+     * @param array params  A two-dimensional array with the following values
+     *                      in each element:
+     *                      - The id of the SELECT element.
+     *                      - A callback method that is invoked with the group
+     *                        list passes as an argument.
+     */
+    updateGroupDropDown: function(params)
+    {
+        this.groupLoading = true;
+        params.each(function(param) {
+            var options = $(param[0]).childElements();
+            options.shift();
+            options.invoke('remove');
+        });
+        this.doAction('listGroups', null, function(r) {
+            var groups;
+            if (r.response.groups) {
+                groups = $H(r.response.groups);
+                params.each(function(param) {
+                    groups.each(function(group) {
+                        $(param[0]).insert(new Element('option', { value: group.key })
+                                     .update(group.value.escapeHTML()));
+                    });
+                });
+            }
+            params.each(function(param) {
+                if (param[1]) {
+                    param[1](groups);
+                }
+            });
+            this.groupLoading = false;
+        }.bind(this));
+    },
+
+    /**
+     * Updates the basic group permission interface after the group list has
+     * been loaded.
+     *
+     * @param Hash groups  The list of groups.
+     */
+    updateGroupPerms: function(groups)
+    {
+        $('kronolithCalendarPermsGroupSingle').clear();
+        if (!groups) {
+            $('kronolithCalendarPermsGroup').up('span').hide();
+        } else if (groups.size() == 1) {
+            $('kronolithCalendarPermsGroupName')
+                .update('&quot;' + groups.values()[0].escapeHTML() + '&quot;')
+                .show();
+            $('kronolithCalendarPermsGroupSingle').setValue(groups.keys()[0]);
+            $('kronolithCalendarPermsGroupList').hide();
+        } else {
+            $('kronolithCalendarPermsGroupName').hide();
+            $('kronolithCalendarPermsGroupList').show();
         }
     },
 
     /**
+     * Inserts a group or user row into the advanced permissions interface.
+     *
+     * @param what string   Either 'group' or 'user'.
+     * @param group string  The group id or user name to insert. Defaults to
+     *                      the value of the drop down.
+     */
+    insertGroupOrUser: function(what, id)
+    {
+        var elm = $(what == 'user' ? 'kronolithCalendarPermsUserNew' : 'kronolithCalendarPermsGroupNew');
+        if (id) {
+            elm.setValue(id);
+        }
+        var value = elm.getValue();
+        if (!value) {
+            return;
+        }
+
+        var tr = elm.up('tr'),
+            row = tr.cloneNode(true).store('remove', true),
+            td = row.down('td');
+
+        td.down('label').remove();
+        // For some strange prototype/firefox box, an instance .remove()
+        // doesn't work here.
+        Element.remove(td.down(elm.tagName));
+        td.insert((elm.tagName == 'SELECT' ? elm.options[elm.selectedIndex].text: elm.getValue()).escapeHTML())
+            .insert(new Element('input', { type: 'hidden', name: (what == 'user' ? 'u' : 'g') + '_names[' + value + ']', value: value }));
+        row.select('input[type=checkbox]').each(function(input) {
+            input.writeAttribute('name', input.name.replace(/\[.*?$/, '[' + value + ']'))
+                .writeAttribute('id', input.id.replace(/new/, value))
+                .next()
+                .writeAttribute('for', input.id);
+        });
+        tr.insert({ before: row });
+
+        if (elm.tagName == 'SELECT') {
+            elm.options[elm.selectedIndex].writeAttribute('disabled', true);
+            elm.selectedIndex = 0;
+        } else {
+            elm.clear();
+        }
+
+        this.activateAdvancedPerms();
+    },
+
+    /**
+     * Activates the advanced permissions.
+     */
+    activateAdvancedPerms: function()
+    {
+        [$('kronolithCalendarPermsNone'), $('kronolithCalendarPermsAll'), $('kronolithCalendarPermsGroup')].invoke('writeAttribute', 'checked', false);
+        $('kronolithCalendarPermsBasic').hide();
+        $('kronolithCalendarPermsAdvanced').show();
+    },
+
+    /**
      * Opens the next screen of the calendar management wizard.
      *
      * @param string type  The calendar type.
@@ -2838,19 +3145,24 @@ KronolithCore = {
                 e.stop();
                 return;
 
+            case 'kronolithCalendarPermsNone':
             case 'kronolithCalendarPermsAll':
-                if ($F('kronolithCalendarPermsAll')) {
-                    $('kronolithCalendarPermsShow').enable();
-                } else {
-                    $('kronolithCalendarPermsShow').disable();
-                }
+            case 'kronolithCalendarPermsGroup':
+                this.permsClickHandler(id.substring(22));
                 return;
 
-            case 'kronolithCalendarPermsGroup':
-                if ($F('kronolithCalendarPermsGroup')) {
-                    $('kronolithCalendarPermsGroupPerms').enable();
-                } else {
-                    $('kronolithCalendarPermsGroupPerms').disable();
+            case 'kronolithCalendarPermsAllShow':
+                this.permsClickHandler('All');
+                e.stop();
+                return;
+
+            case 'kronolithCalendarPermsAdvanced':
+                if (orig.tagName != 'INPUT') {
+                    return;
+                }
+                this.activateAdvancedPerms();
+                if (orig.name.match(/u_.*||new/)) {
+                    this.insertGroupOrUser('user');
                 }
                 return;
 
index 4acc012..1d7700c 100644 (file)
@@ -647,6 +647,7 @@ class Kronolith_Ajax_Application extends Horde_Ajax_Application_Base
             'fg' => Kronolith::foregroundColor($calendar),
             'bg' => Kronolith::backgroundColor($calendar),
             'show' => false,
+            'perms' => $calendar->getPermission()->data,
             'edit' => $calendar->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT));
         return $result;
     }
index 413d4f9..1d6e4f0 100644 (file)
@@ -216,6 +216,12 @@ class Kronolith
                              Horde_Date_Recurrence::RECUR_YEARLY_DATE => 'Yearly',
                              Horde_Date_Recurrence::RECUR_YEARLY_DAY => 'Yearly',
                              Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY => 'Yearly'),
+            'perms' => array('all' => Horde_Perms::ALL,
+                             'show' => Horde_Perms::SHOW,
+                             'read' => Horde_Perms::READ,
+                             'edit' => Horde_Perms::EDIT,
+                             'delete' => Horde_Perms::DELETE,
+                             'delegate' => self::PERMS_DELEGATE),
             'snooze' => array('0' => _("select..."),
                               '5' => _("5 minutes"),
                               '15' => _("15 minutes"),
@@ -250,6 +256,7 @@ class Kronolith
                         'fg' => self::foregroundColor($calendar),
                         'bg' => self::backgroundColor($calendar),
                         'show' => in_array($id, $GLOBALS['display_calendars']),
+                        'perms' => $calendar->getPermission()->data,
                         'edit' => $calendar->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT));
                 }
             }
index e470925..afa9520 100644 (file)
@@ -1,4 +1,16 @@
-<?php $auth = Horde_Auth::singleton($GLOBALS['conf']['auth']['driver']); ?>
+<?php
+$auth = Horde_Auth::singleton($GLOBALS['conf']['auth']['driver']);
+$horde_groups = Group::singleton();
+if (!empty($GLOBALS['conf']['share']['any_group'])) {
+    $groups = $horde_groups->listGroups();
+} else {
+    $groups = $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true);
+}
+if ($groups instanceof PEAR_Error) {
+    $groups = array();
+}
+asort($groups);
+?>
 <div id="kronolithCalendarDialog" class="kronolithDialog">
 
 <form id="kronolithCalendarForminternal" action="">
   <div id="kronolithCalendarPermsBasic">
     <div class="kronolithDialogInfo"><?php printf(_("%s Standard sharing. %s You can also set %s advanced sharing %s options."), '<strong>', '</strong>', '<strong><a href="#" id="kronolithCalendarPermsMore">', '</a></strong>') ?></div>
     <div>
-      <input type="radio" id="kronolithCalendarPermsNone" name="share_with" value="none" checked="checked" />
+      <input type="radio" id="kronolithCalendarPermsNone" name="basic_perms" checked="checked" />
       <label for="kronolithCalendarPermsNone"><?php echo _("Don't share this calendar") ?></label><br />
       <?php echo _("or share with") ?>
-      <input type="checkbox" id="kronolithCalendarPermsAll" name="share_with_all" />
+      <input type="radio" id="kronolithCalendarPermsAll" name="basic_perms" />
       <label for="kronolithCalendarPermsAll"><?php echo _("everyone") ?></label>
       (<?php echo _("and") ?>
-      <input type="checkbox" id="kronolithCalendarPermsShow" name="share_show" disabled="disabled" />
-      <?php printf(_("%s make it searchable %s by everyone too"), '<label for="kronolithCalendarPermsShow">', '</label>') ?>)<br />
-      <span id="kronolithCalendarPermsGroups">
+      <input type="checkbox" id="kronolithCalendarPermsAllShow" />
+      <?php printf(_("%s make it searchable %s by everyone too"), '<label for="kronolithCalendarPermsAllShow">', '</label>') ?>)<br />
+      <span>
         <?php echo _("or share with") ?>
-        <input type="checkbox" id="kronolithCalendarPermsGroup" name="share_with_group" />
+        <input type="radio" id="kronolithCalendarPermsGroup" name="basic_perms" />
         <label for="kronolithCalendarPermsGroup">
           <?php echo _("the") ?>
-          <span id="kronolithCalendarPermsSingleGroup"></span>
+          <input type="hidden" id="kronolithCalendarPermsGroupSingle"<?php if (count($groups) == 1) echo ' value="' . key($groups) . '"' ?> />
+          <span id="kronolithCalendarPermsGroupName"><?php if (count($groups) == 1) echo '&quot;' . htmlspecialchars(reset($groups)) . '&quot;' ?></span>
         </label>
-          <span id="kronolithCalendarPermsGroupList">
-            <select name="share_groups">
-              <option>Group one</option>
-              <option>Soccer team</option>
-              <option>Family</option>
-            </select>
-          </span>
+        <select id="kronolithCalendarPermsGroupList">
+          <?php if (count($groups) > 1): ?>
+          <?php foreach ($groups as $id => $group): ?>
+          <option value="<?php echo $id ?>"><?php echo htmlspecialchars($group) ?></option>
+          <?php endforeach; ?>
+          <?php endif; ?>
+        </select>
         <label for="kronolithCalendarPermsGroup">
           <?php echo _("group") ?>
         </label>
         <?php printf(_("and %s allow them to %s"), '<label for="kronolithCalendarPermsGroupPerms">','</label>') ?>
-        <select id="kronolithCalendarPermsGroupPerms" name="share_group_perms" disabled="disabled">
+        <select id="kronolithCalendarPermsGroupPerms" onchange="KronolithCore.permsClickHandler('Group')">
           <option value="read"><?php echo _("read the events") ?></option>
           <option value="edit"><?php echo _("read and edit the events") ?></option>
         </select><br />
@@ -82,7 +95,7 @@
     </div>
   </div>
   <div id="kronolithCalendarPermsAdvanced" style="display:none">
-    <div class="kronolithDialogInfo"><?php printf(_("%s Advanced sharing. %s You can also return to the %s standard settings. %s"), '<strong>', '</strong>', '<strong><a href="#" id="kronolithCalendarPermsLess">', '</a></strong>') ?></div>
+    <div class="kronolithDialogInfo"><?php printf(_("%s Advanced sharing. %s You can also return to the %s standard settings %s."), '<strong>', '</strong>', '<strong><a href="#" id="kronolithCalendarPermsLess">', '</a></strong>') ?></div>
     <div>
     <table width="100%" cellspacing="0" cellpadding="0" border="0">
       <thead>
       <tbody>
         <tr>
          <td>
-      <?php if ($auth->hasCapability('list') && ($GLOBALS['conf']['auth']['list_users'] == 'list' || $GLOBALS['conf']['auth']['list_users'] == 'both')): ?>
-      <label for="owner_select"><?php echo Horde::img('user.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("User:") ?></label>
-      <select id="owner_select" name="owner_select">
-        <option value=""><?php echo _("Select a new owner:") ?></option>
-        <option value="" selected="selected"><?php echo htmlspecialchars(Horde_Auth::getAuth()) ?></option>
-        <?php foreach (array('User one', 'User two') as $user): ?>
-        <option value="<?php echo htmlspecialchars($user) ?>"><?php echo htmlspecialchars($user) ?></option>
-        <?php endforeach; ?>
-      </select>
-      <?php else: ?>
-      <label for="owner_input"><?php echo Horde::img('user.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("User:") ?></label>
-      <input type="text" id="owner_input" name="owner_input" size="50" value="<?php echo htmlspecialchars(Horde_Auth::getAuth()) ?>" />
-      <?php endif; ?>
+            <?php if ($auth->hasCapability('list') && ($GLOBALS['conf']['auth']['list_users'] == 'list' || $GLOBALS['conf']['auth']['list_users'] == 'both')): ?>
+            <select name="owner_select">
+              <option value=""><?php echo _("Select a new owner:") ?></option>
+              <?php foreach ($auth->listUsers() as $user): ?>
+              <option value="<?php echo htmlspecialchars($user) ?>"<?php if ($user == Horde_Auth::getAuth()) echo ' selected="selected"' ?>><?php echo htmlspecialchars($user) ?></option>
+              <?php endforeach; ?>
+            </select>
+            <?php else: ?>
+            <input type="text" name="owner_input" size="50" value="<?php echo htmlspecialchars(Horde_Auth::getAuth()) ?>" />
+            <?php endif; ?>
           </td>
         </tr>
       </tbody>
         </tr>
       </thead>
 
-      <?php if (Horde_Auth::isAdmin() || !empty($GLOBALS['conf']['shares']['world'])): ?>
+      <tbody>
+      <?php if (Horde_Auth::isAdmin() || !empty($GLOBALS['conf']['share']['world'])): ?>
       <!-- Default Permissions -->
       <tr>
-        <td><?php echo Horde::img('perms.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("All Authenticated Users") ?></td>
+        <td><?php echo _("All Authenticated Users") ?></td>
         <td>
-          <input type="checkbox" id="default_show" name="default_show" />
-          <label for="default_show"><?php echo _("Show") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsdefaultshow" name="default_show" />
+          <label for="kronolithCalendarPermsdefaultshow"><?php echo _("Show") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="default_read" name="default_read" />
-          <label for="default_read"><?php echo _("Read") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsdefaultread" name="default_read" />
+          <label for="kronolithCalendarPermsdefaultread"><?php echo _("Read") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="default_edit" name="default_edit" />
-          <label for="default_edit"><?php echo _("Edit") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsdefaultedit" name="default_edit" />
+          <label for="kronolithCalendarPermsdefaultedit"><?php echo _("Edit") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="default_delete" name="default_delete" />
-          <label for="default_delete"><?php echo _("Delete") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsdefaultdelete" name="default_delete" />
+          <label for="kronolithCalendarPermsdefaultdelete"><?php echo _("Delete") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="default_delegate" name="default_delegate" />
-          <label for="default_delegate"><?php echo _("Delegate") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsdefaultdelegate" name="default_delegate" />
+          <label for="kronolithCalendarPermsdefaultdelegate"><?php echo _("Delegate") ?></label>
         </td>
       </tr>
 
       <tr>
         <td><?php echo _("Guest Permissions") ?></td>
         <td>
-          <input type="checkbox" id="guest_show" name="guest_show" />
-          <label for="guest_show"><?php echo _("Show") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsguestshow" name="guest_show" />
+          <label for="kronolithCalendarPermsguestshow"><?php echo _("Show") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="guest_read" name="guest_read" />
-          <label for="guest_read"><?php echo _("Read") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsguestread" name="guest_read" />
+          <label for="kronolithCalendarPermsguestread"><?php echo _("Read") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="guest_edit" name="guest_edit" />
-          <label for="guest_edit"><?php echo _("Edit") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsguestedit" name="guest_edit" />
+          <label for="kronolithCalendarPermsguestedit"><?php echo _("Edit") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="guest_delete" name="guest_delete" />
-          <label for="guest_delete"><?php echo _("Delete") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsguestdelete" name="guest_delete" />
+          <label for="kronolithCalendarPermsguestdelete"><?php echo _("Delete") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="guest_delegate" name="guest_delegate" />
-          <label for="guest_delegate"><?php echo _("Delegate") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsguestdelegate" name="guest_delegate" />
+          <label for="kronolithCalendarPermsguestdelegate"><?php echo _("Delegate") ?></label>
         </td>
       </tr>
       <?php endif; ?>
 
       <!-- Creator Permissions -->
       <tr>
-        <td><?php echo Horde::img('user.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("Object Creator") ?></td>
+        <td><?php echo _("Object Creator") ?></td>
         <td>
-          <input type="checkbox" id="creator_show"  name="creator_show" />
-          <label for="creator_show"><?php echo _("Show") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermscreatorshow"  name="creator_show" />
+          <label for="kronolithCalendarPermscreatorshow"><?php echo _("Show") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="creator_read" name="creator_read" />
-          <label for="creator_read"><?php echo _("Read") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermscreatorread" name="creator_read" />
+          <label for="kronolithCalendarPermscreatorread"><?php echo _("Read") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="creator_edit" name="creator_edit" />
-          <label for="creator_edit"><?php echo _("Edit") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermscreatoredit" name="creator_edit" />
+          <label for="kronolithCalendarPermscreatoredit"><?php echo _("Edit") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="creator_delete" name="creator_delete" />
-          <label for="creator_delete"><?php echo _("Delete") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermscreatordelete" name="creator_delete" />
+          <label for="kronolithCalendarPermscreatordelete"><?php echo _("Delete") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="creator_delegate" name="creator_delegate" />
-          <label for="creator_delegate"><?php echo _("Delegate") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermscreatordelegate" name="creator_delegate" />
+          <label for="kronolithCalendarPermscreatordelegate"><?php echo _("Delegate") ?></label>
         </td>
       </tr>
 
       <!-- User Permissions -->
       <tr>
         <td>
-          <?php echo Horde::img('user.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("User:") ?>
-          <label for="u_names_new_input" class="hidden"><?php echo _("User to add:") ?></label>
-          <input type="text" id="u_names_new_input" name="u_names[||new_input]" />
+          <?php echo _("User:") ?>
+          <label for="kronolithCalendarPermsUserNew" class="hidden"><?php echo _("User to add:") ?></label>
+          <?php if ($auth->hasCapability('list') && ($GLOBALS['conf']['auth']['list_users'] == 'list' || $GLOBALS['conf']['auth']['list_users'] == 'both')): ?>
+          <select id="kronolithCalendarPermsUserNew" name="u_names[||new]" onchange="KronolithCore.insertGroupOrUser('user')">
+            <option value=""><?php echo _("Select a user") ?></option>
+            <?php foreach ($auth->listUsers() as $user): ?>
+            <?php if ($user != Horde_Auth::getAuth()): ?>
+            <option value="<?php echo htmlspecialchars($user) ?>"><?php echo htmlspecialchars($user) ?></option>
+            <?php endif; ?>
+            <?php endforeach; ?>
+          </select>
+          <?php else: ?>
+          <input type="text" id="kronolithCalendarPermsUserNew" name="u_names[||new]" onchange="KronolithCore.insertGroupOrUser('user')" />
+          <?php endif; ?>
         </td>
         <td>
-          <input type="checkbox" id="u_show_new_input" name="u_show[||new_input]" />
-          <label for="u_show_new_input"><?php echo _("Show") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsUsershow_new" name="u_show[||new]" />
+          <label for="kronolithCalendarPermsUsershow_new"><?php echo _("Show") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="u_read_new_input" name="u_read[||new_input]" />
-          <label for="u_read_new_input"><?php echo _("Read") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsUserread_new" name="u_read[||new]" />
+          <label for="kronolithCalendarPermsUserread_new"><?php echo _("Read") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="u_edit_new_input" name="u_edit[||new_input]" />
-          <label for="u_edit_new_input"><?php echo _("Edit") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsUseredit_new" name="u_edit[||new]" />
+          <label for="kronolithCalendarPermsUseredit_new"><?php echo _("Edit") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="u_delete_new_input" name="u_delete[||new_input]" />
-          <label for="u_delete_new_input"><?php echo _("Delete") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsUserdelete_new" name="u_delete[||new]" />
+          <label for="kronolithCalendarPermsUserdelete_new"><?php echo _("Delete") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="u_delegate_new_input" name="u_delegate[||new_input]" />
-          <label for="u_delegate_new_input"><?php echo _("Delegate") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsUserdelegate_new" name="u_delegate[||new]" />
+          <label for="kronolithCalendarPermsUserdelegate_new"><?php echo _("Delegate") ?></label>
         </td>
       </tr>
 
       <!-- Group Permissions -->
       <tr>
         <td>
-          <?php echo Horde::img('group.png', '', '', $GLOBALS['registry']->getImageDir('horde')) . '&nbsp;' . _("Group:") ?>
-          <label for="g_names_new" class="hidden"><?php echo _("Select a group to add:") ?></label>
-          <select id="g_names_new" name="g_names[||new]">
-            <option value=""><?php echo _("Select a group to add") ?></option>
-            <?php foreach (array('Group one', 'Family') as $gid => $group): ?>
-            <option value="<?php echo htmlspecialchars($gid) ?>"><?php echo htmlspecialchars($group) ?></option>
+          <?php echo _("Group:") ?>
+          <label for="kronolithCalendarPermsGroupNew" class="hidden"><?php echo _("Select a group to add:") ?></label>
+          <select id="kronolithCalendarPermsGroupNew" name="g_names[||new]" onchange="KronolithCore.insertGroupOrUser('group')">
+            <option value=""><?php echo _("Select a group") ?></option>
+            <?php foreach ($groups as $id => $group): ?>
+            <option value="<?php echo $id ?>"><?php echo htmlspecialchars($group) ?></option>
             <?php endforeach; ?>
           </select>
         </td>
         <td>
-          <input type="checkbox" id="g_show_new" name="g_show[||new]" />
-          <label for="g_show_new"><?php echo _("Show") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsGroupshow_new" name="g_show[||new]" />
+          <label for="kronolithCalendarPermsGroupshow_new"><?php echo _("Show") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="g_read_new" name="g_read[||new]" />
-          <label for="g_read_new"><?php echo _("Read") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsGroupread_new" name="g_read[||new]" />
+          <label for="kronolithCalendarPermsGroupread_new"><?php echo _("Read") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="g_edit_new" name="g_edit[||new]" />
-          <label for="g_edit_new"><?php echo _("Edit") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsGroupedit_new" name="g_edit[||new]" />
+          <label for="kronolithCalendarPermsGroupedit_new"><?php echo _("Edit") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="g_delete_new" name="g_delete[||new]" />
-          <label for="g_delete_new"><?php echo _("Delete") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsGroupdelete_new" name="g_delete[||new]" />
+          <label for="kronolithCalendarPermsGroupdelete_new"><?php echo _("Delete") ?></label>
         </td>
         <td>
-          <input type="checkbox" id="g_delegate_new" name="g_delegate[||new]" />
-          <label for="g_delegate_new"><?php echo _("Delegate") ?></label>
+          <input type="checkbox" id="kronolithCalendarPermsGroupdelegate_new" name="g_delegate[||new]" />
+          <label for="kronolithCalendarPermsGroupdelegate_new"><?php echo _("Delegate") ?></label>
         </td>
       </tr>
+      </tbody>
     </table>
   </div>
 </div>
 <div>
   <label><?php echo _("Color") ?>:<br />
     <input type="text" name="color" id="kronolithCalendartasklistsColor" size="7" />
-    <?php echo Horde::url('#')->link(array('title' => _("Color Picker"), 'onclick' => 'new ColorPicker({ color: $F(\'kronolithCalendartasklistsColor\'), offsetParent: Event.element(event), update: [[\'kronolithCalendartasklistsColor\', \'value\'], [\'kronolithCalendartasklistsColor\', \'background\']] }); return false;')) . Horde::img('colorpicker.png', _("Color Picker"), '', $GLOBALS['registry']->getImageDir('horde')) . '</a>' ?>
+    <?php echo Horde::url('#')->link(array('title' => _("Color Picker"), 'class' => 'kronolithColorPicker')) . Horde::img('colorpicker.png', _("Color Picker"), '', $GLOBALS['registry']->getImageDir('horde')) . '</a>' ?>
   </label>
 </div>