Add permission management
authorDuck (Jakob Munih) <duck@obala.net>
Mon, 16 Feb 2009 19:50:06 +0000 (20:50 +0100)
committerDuck (Jakob Munih) <duck@obala.net>
Mon, 16 Feb 2009 19:50:06 +0000 (20:50 +0100)
folks/config/conf.xml
folks/lib/Friends.php
folks/lib/Friends/shared.php
folks/lib/Friends/sql.php
folks/perms.php [new file with mode: 0644]

index a5932ae..7434300 100644 (file)
@@ -9,8 +9,6 @@
      <configsql switchname="driverconfig">
       <configstring name="table" desc="Database
       table">folks_users</configstring>
-      <configstring name="friends" desc="Database
-        friends table">folks_friends</configstring>
       <configstring name="online" desc="Database
         online table">folks_online</configstring>
       <configstring name="search" desc="Database
 
 <configtab name="general" desc="General">
    <configstring name="support" desc="Email from which support messages will be sent">support@example.com</configstring>
-   <configswitch name="friends" desc="Driver for friends storage">sql
+
+   <configsection name="friends">
+   <configswitch name="driver" desc="Driver for friends storage">sql
        <case name="prefs" desc="Prefs - friends and blacklist only sored"></case>
-       <case name="sql" desc="SQL - friends and blacklist only"></case>
-       <case name="shared" desc="Shared - custom shared groups lists"></case>
-       <case name="application" desc="Application">
+       <case name="sql" desc="SQL - friends and blacklist only">
         <configsection name="params">
-        <configenum name="app" desc="The application which is providing friends">letter
-        <values>
-            <configspecial name="list-horde-apps"/>
-        </values>
-        </configenum>
+            <configstring name="friends" desc="Friends table"></configstring>
+            <configstring name="blacklist" desc="Blacklist table"></configstring>
+        </configsection>
+       </case>
+       <case name="shared" desc="Shared - custom shared groups lists">
+       <configsection name="params">
+            <configstring name="friends" desc="Friends table"></configstring>
+            <configstring name="blacklist" desc="Blacklist table"></configstring>
         </configsection>
        </case>
+       <case name="application" desc="Application">
+            <configsection name="params">
+                <configenum name="app" desc="The application which is providing friends">letter
+                <values>
+                    <configspecial name="list-horde-apps"/>
+                </values>
+                </configenum>
+            </configsection>
+       </case>
    </configswitch>
+   </configsection>
 
  <configsection name="images">
    <configheader>Images</configheader>
index 8ad7d8f..0cd7224 100644 (file)
@@ -59,7 +59,11 @@ class Folks_Friends {
     private static function factory($driver = null, $params = null)
     {
         if ($driver === null) {
-            $driver = $GLOBALS['conf']['friends'];
+            $driver = $GLOBALS['conf']['friends']['driver'];
+        }
+
+        if ($params === null && isset($GLOBALS['conf']['friends']['params'])) {
+            $params = $GLOBALS['conf']['friends']['params'];
         }
 
         $driver = basename($driver);
@@ -250,7 +254,7 @@ class Folks_Friends {
      * Add user to a friend list
      *
      * @param string $friend   Friend's usersame
-     * @param string $group   Group to add friend to
+     * @param string $group    Group to add friend to
      */
     public function addFriend($friend, $group = null)
     {
index 0979833..02174be 100644 (file)
@@ -18,7 +18,12 @@ require_once dirname(__FILE__) . '/sql.php';
  */
 class Folks_Friends_shared extends  Folks_Friends_sql {
 
-    const CUSTOM = 3;
+    /**
+     * Share holder
+     *
+     * @var int
+     */
+    private $_shares;
 
     /**
      * friends list ID
@@ -67,11 +72,9 @@ class Folks_Friends_shared extends  Folks_Friends_sql {
         if ($groups instanceof PEAR_Error) {
             return $groups;
         }
-var_dump($groups);
+
         foreach ($groups as $id => $group) {
-            if ($group->get('type') == self::BLACKLIST) {
-                $this->_blacklist = $group->getId();
-            } elseif ($group->get('type') == self::WHITELIST) {
+            if ($group->get('name') == '__FRIENDS__') {
                 $this->_whitelist = $group->getId();
             }
         }
@@ -198,17 +201,15 @@ var_dump($groups);
             return $groups;
         }
 
+        /** TODO: USE TRANSLATEDN NAMES ??? */
+
         $list = array();
-        foreach ($groups as $id => $group) {
-            // set friends ids
-            if ($group->get('type') == self::BLACKLIST) {
-                $this->_blacklist = $id;
-                $list[$id] = _("Blacklist");
-            } elseif ($group->get('type') == self::WHITELIST) {
+        foreach ($groups as $group) {
+            if ($group->get('name') == '__FRIENDS__') {
                 $this->_whitelist = $id;
-                $list[$id] = _("Friends");
+                $list[$group->getId()] = _("Friends");
             } else {
-                $list[$id] = $group->get('name');
+                $list[$group->getId()] = $group->get('name');
             }
         }
 
@@ -216,9 +217,44 @@ var_dump($groups);
     }
 
     /**
+     * Rename user group
+     *
+     * @param integer $group   Group ID to delete
+     */
+    public function renameGroup($group, $name)
+    {
+        if (empty($name)) {
+            return PEAR::raiseError(_("A group names cannot be empty"));
+        }
+
+        $GLOBALS['folks_shares'] = Horde_Share::singleton('folks');
+
+        $share = $GLOBALS['folks_shares']->getShareById($group);
+        if ($share instanceof PEAR_Error) {
+            return $share;
+        }
+
+        // Only owners of a group can delete them
+        if (Auth::getAuth() != $share->get('owner') &&
+            !Auth::isAdmin('folks:admin')) {
+            return PEAR::raiseError("You can rename only your own groups.");
+        }
+
+        $share->set('name', $name);
+        $result = $share->save();
+        if ($result instanceof PEAR_Error) {
+            return $result;
+        }
+
+        $this->_cache->expire('folksGroups' . $this->_user);
+
+        return true;
+    }
+
+    /**
      * Delete user group
      *
-     * @param string $group   Group to delete
+     * @param integer $group   Group ID to delete
      */
     public function removeGroup($group)
     {
@@ -229,22 +265,47 @@ var_dump($groups);
             return $share;
         }
 
-        $query = 'DELETE FROM ' . $this->_params['friends'] . ' WHERE user_uid = ? AND group_id = ?';
-        $result = $this->_write_db->query($query, array($this->_user, $share->getId()));
+        // Only owners of a group can delete them
+        if (Auth::getAuth() != $share->get('owner') &&
+            !Auth::isAdmin('folks:admin')) {
+            return PEAR::raiseError("You can delete only your own groups.");
+        }
+
+        $query = 'DELETE FROM ' . $this->_params['friends']
+                    . ' WHERE user_uid = ' . $share->_shareOb->_write_db->quote($this->_user)
+                    . ' AND group_id = ' . $share->_shareOb->_write_db->quote($share->getId());
+        $result = $share->_shareOb->_write_db->exec($query);
+        if ($result instanceof PEAR_Error) {
+            return $result;
+        }
+
+        $result = $GLOBALS['folks_shares']->removeShare($share);
         if ($result instanceof PEAR_Error) {
             return $result;
         }
 
-        return $GLOBALS['folks_shares']->_removeShare($share);
+        $this->_cache->expire('folksGroups' . $this->_user);
+        $this->_cache->expire('folksFriends' . $this->_user . $group);
+
+        return true;
     }
 
     /**
-     * Delete user group
+     * Add group
      *
-     * @param string $group   Group to delete
+     * @param string $group   Group name
      */
-    public function addGroup($group, $type = null)
+    public function addGroup($name)
     {
+        if (empty($name)) {
+            return PEAR::raiseError(_("A group names cannot be empty"));
+        }
+
+        $groups = $this->getGroups();
+        if (in_array($name, $groups)) {
+            return PEAR::raiseError(sprintf(_("You already have a group named \"%s\"."), $name));
+        }
+
         $GLOBALS['folks_shares'] = Horde_Share::singleton('folks');
 
         $share = $GLOBALS['folks_shares']->newShare(hash('md5', microtime()));
@@ -252,14 +313,12 @@ var_dump($groups);
             return $share;
         }
 
-        $share->set('name', $group);
-
-        if ($type !== null) {
-            $share->set('type', $type);
-        } else {
-            $share->set('type', self::CUSTOM);
+        $share->set('name', $name);
+        $result = $GLOBALS['folks_shares']->addShare($share);
+        if ($result instanceof PEAR_Error) {
+            return $result;
         }
 
-        return $GLOBALS['folks_shares']->addShare($share);
+        return $share->getId();
     }
 }
\ No newline at end of file
index 8241f79..65d85d5 100644 (file)
@@ -15,9 +15,6 @@
  */
 class Folks_Friends_sql extends Folks_Friends {
 
-    const WHITELIST = 0;
-    const BLACKLIST = 1;
-
     /**
      * Handle for the current database connection.
      *
@@ -192,8 +189,7 @@ class Folks_Friends_sql extends Folks_Friends {
      */
     public function getGroups()
     {
-        return array(self::WHITELIST => _("Whitelist"),
-                        self::BLACKLIST  => _("Blacklist"));
+        return array(_("Whitelist"));
     }
 
     /**
diff --git a/folks/perms.php b/folks/perms.php
new file mode 100644 (file)
index 0000000..f81040a
--- /dev/null
@@ -0,0 +1,249 @@
+<?php
+/**
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ */
+
+require_once dirname(__FILE__) . '/lib/base.php';
+require_once 'Horde/Group.php';
+
+$shares = &Horde_Share::singleton('folks');
+$groups = &Group::singleton();
+$auth = &Auth::singleton($conf['auth']['driver']);
+
+$reload = false;
+$actionID = Util::getFormData('actionID', 'edit');
+switch ($actionID) {
+case 'edit':
+    $share = &$shares->getShareById(Util::getFormData('cid'));
+    if (!is_a($share, 'PEAR_Error')) {
+        $perm = &$share->getPermission();
+    } elseif (($category = Util::getFormData('share')) !== null) {
+        $share = &$shares->getShare($category);
+        if (!is_a($share, 'PEAR_Error')) {
+            $perm = &$share->getPermission();
+        }
+    }
+    if (is_a($share, 'PEAR_Error')) {
+        $notification->push($share, 'horde.error');
+    } elseif (isset($share) && Auth::getAuth() != $share->get('owner')) {
+        exit('permission denied');
+    }
+    break;
+
+case 'editform':
+    $share = &$shares->getShareById(Util::getFormData('cid'));
+    if (is_a($share, 'PEAR_Error')) {
+        $notification->push(_("Attempt to edit a non-existent share."), 'horde.error');
+    } else {
+        if (Auth::getAuth() != $share->get('owner')) {
+            exit('permission denied');
+        }
+        $perm = &$share->getPermission();
+
+        // Process owner and owner permissions.
+        $old_owner = $share->get('owner');
+        $new_owner = Auth::addHook(Util::getFormData('owner', $old_owner));
+        if ($old_owner !== $new_owner && !empty($new_owner)) {
+            if ($old_owner != Auth::getAuth() && !Auth::isAdmin()) {
+                $notification->push(_("Only the owner or system administrator may change ownership or owner permissions for a share"), 'horde.error');
+            } else {
+                $share->set('owner', $new_owner);
+                $share->save();
+            }
+        }
+
+        // Process default permissions.
+        if (Util::getFormData('default_show')) {
+            $perm->addDefaultPermission(PERMS_SHOW, false);
+        } else {
+            $perm->removeDefaultPermission(PERMS_SHOW, false);
+        }
+        if (Util::getFormData('default_read')) {
+            $perm->addDefaultPermission(PERMS_READ, false);
+        } else {
+            $perm->removeDefaultPermission(PERMS_READ, false);
+        }
+        if (Util::getFormData('default_edit')) {
+            $perm->addDefaultPermission(PERMS_EDIT, false);
+        } else {
+            $perm->removeDefaultPermission(PERMS_EDIT, false);
+        }
+        if (Util::getFormData('default_delete')) {
+            $perm->addDefaultPermission(PERMS_DELETE, false);
+        } else {
+            $perm->removeDefaultPermission(PERMS_DELETE, false);
+        }
+
+        // Process guest permissions.
+        if (Util::getFormData('guest_show')) {
+            $perm->addGuestPermission(PERMS_SHOW, false);
+        } else {
+            $perm->removeGuestPermission(PERMS_SHOW, false);
+        }
+        if (Util::getFormData('guest_read')) {
+            $perm->addGuestPermission(PERMS_READ, false);
+        } else {
+            $perm->removeGuestPermission(PERMS_READ, false);
+        }
+        if (Util::getFormData('guest_edit')) {
+            $perm->addGuestPermission(PERMS_EDIT, false);
+        } else {
+            $perm->removeGuestPermission(PERMS_EDIT, false);
+        }
+        if (Util::getFormData('guest_delete')) {
+            $perm->addGuestPermission(PERMS_DELETE, false);
+        } else {
+            $perm->removeGuestPermission(PERMS_DELETE, false);
+        }
+
+        // Process creator permissions.
+        if (Util::getFormData('creator_show')) {
+            $perm->addCreatorPermission(PERMS_SHOW, false);
+        } else {
+            $perm->removeCreatorPermission(PERMS_SHOW, false);
+        }
+        if (Util::getFormData('creator_read')) {
+            $perm->addCreatorPermission(PERMS_READ, false);
+        } else {
+            $perm->removeCreatorPermission(PERMS_READ, false);
+        }
+        if (Util::getFormData('creator_edit')) {
+            $perm->addCreatorPermission(PERMS_EDIT, false);
+        } else {
+            $perm->removeCreatorPermission(PERMS_EDIT, false);
+        }
+        if (Util::getFormData('creator_delete')) {
+            $perm->addCreatorPermission(PERMS_DELETE, false);
+        } else {
+            $perm->removeCreatorPermission(PERMS_DELETE, false);
+        }
+
+        // Process user permissions.
+        $u_names = Util::getFormData('u_names');
+        $u_show = Util::getFormData('u_show');
+        $u_read = Util::getFormData('u_read');
+        $u_edit = Util::getFormData('u_edit');
+        $u_delete = Util::getFormData('u_delete');
+
+        foreach ($u_names as $key => $user) {
+            // Apply backend hooks
+            $user = Auth::addHook($user);
+            // If the user is empty, or we've already set permissions
+            // via the owner_ options, don't do anything here.
+            if (empty($user) || $user == $new_owner) {
+                continue;
+            }
+
+            if (!empty($u_show[$key])) {
+                $perm->addUserPermission($user, PERMS_SHOW, false);
+            } else {
+                $perm->removeUserPermission($user, PERMS_SHOW, false);
+            }
+            if (!empty($u_read[$key])) {
+                $perm->addUserPermission($user, PERMS_READ, false);
+            } else {
+                $perm->removeUserPermission($user, PERMS_READ, false);
+            }
+            if (!empty($u_edit[$key])) {
+                $perm->addUserPermission($user, PERMS_EDIT, false);
+            } else {
+                $perm->removeUserPermission($user, PERMS_EDIT, false);
+            }
+            if (!empty($u_delete[$key])) {
+                $perm->addUserPermission($user, PERMS_DELETE, false);
+            } else {
+                $perm->removeUserPermission($user, PERMS_DELETE, false);
+            }
+        }
+
+        // Process group permissions.
+        $g_names = Util::getFormData('g_names');
+        $g_show = Util::getFormData('g_show');
+        $g_read = Util::getFormData('g_read');
+        $g_edit = Util::getFormData('g_edit');
+        $g_delete = Util::getFormData('g_delete');
+
+        foreach ($g_names as $key => $group) {
+            if (empty($group)) {
+                continue;
+            }
+
+            if (!empty($g_show[$key])) {
+                $perm->addGroupPermission($group, PERMS_SHOW, false);
+            } else {
+                $perm->removeGroupPermission($group, PERMS_SHOW, false);
+            }
+            if (!empty($g_read[$key])) {
+                $perm->addGroupPermission($group, PERMS_READ, false);
+            } else {
+                $perm->removeGroupPermission($group, PERMS_READ, false);
+            }
+            if (!empty($g_edit[$key])) {
+                $perm->addGroupPermission($group, PERMS_EDIT, false);
+            } else {
+                $perm->removeGroupPermission($group, PERMS_EDIT, false);
+            }
+            if (!empty($g_delete[$key])) {
+                $perm->addGroupPermission($group, PERMS_DELETE, false);
+            } else {
+                $perm->removeGroupPermission($group, PERMS_DELETE, false);
+            }
+        }
+
+        $result = $share->setPermission($perm, false);
+        if (is_a($result, 'PEAR_Error')) {
+            $notification->push($result, 'horde.error');
+        } else {
+            $result = $share->save();
+            if (is_a($result, 'PEAR_Error')) {
+                $notification->push($result, 'horde.error');
+            } else {
+                if (Util::getFormData('save_and_finish')) {
+                    Util::closeWindowJS();
+                    exit;
+                }
+                $notification->push(sprintf(_("Updated \"%s\"."), $share->get('name')), 'horde.success');
+            }
+        }
+    }
+    break;
+}
+
+if (is_a($share, 'PEAR_Error')) {
+    $title = _("Edit Permissions");
+} else {
+    $title = sprintf(_("Edit Permissions for %s"), $share->get('name'));
+}
+
+if ($auth->hasCapability('list')) {
+    $userList = $auth->listUsers();
+    if (is_a($userList, 'PEAR_Error')) {
+        Horde::logMessage($userList, __FILE__, __LINE__, PEAR_LOG_ERR);
+        $userList = array();
+    }
+    sort($userList);
+} else {
+    $userList = array();
+}
+
+if (!empty($conf['share']['any_group'])) {
+    $groupList = $groups->listGroups();
+} else {
+    $groupList = $groups->getGroupMemberships(Auth::getAuth(), true);
+}
+if (is_a($groupList, 'PEAR_Error')) {
+    Horde::logMessage($groupList, __FILE__, __LINE__, PEAR_LOG_NOTICE);
+    $groupList = array();
+}
+asort($groupList);
+
+require FOLKS_TEMPLATES . '/common-header.inc';
+$notification->notify(array('listeners' => 'status'));
+require $registry->get('templates', 'horde') . '/shares/edit.inc';
+require $registry->get('templates', 'horde') . '/common-footer.inc';