*
* @param string $permission Allow users with this permission admin access
* in the current context.
- * @param integer $permlevel The level of permissions to check for
- * (PERMS_EDIT, PERMS_DELETE, etc). Defaults
- * to PERMS_EDIT.
+ * @param integer $permlevel The level of permissions to check for.
+ * Defaults to Horde_Perms::EDIT.
* @param string $user The user to check. Defaults to
* self::getAuth().
*
if (!is_null($permission)) {
if (is_null($permlevel)) {
- $permlevel = PERMS_EDIT;
+ $permlevel = Horde_Perms::EDIT;
}
return $GLOBALS['perms']->hasPermission($permission, $user, $permlevel);
}
if (isset($conf['menu']['apps']) && is_array($conf['menu']['apps'])) {
foreach ($conf['menu']['apps'] as $app) {
- if ($registry->get('status', $app) != 'inactive' && $registry->hasPermission($app, PERMS_SHOW)) {
+ if ($registry->get('status', $app) != 'inactive' && $registry->hasPermission($app, Horde_Perms::SHOW)) {
try {
$this->add(Horde::url($registry->getInitialPage($app)), $registry->get('name', $app), $registry->get('icon', $app), '');
} catch (Horde_Exception $e) {}
throw new Horde_Exception(_("This system is currently deactivated."));
}
- /* Create the global Perms object. */
+ /* Create the global permissions object. */
// TODO: Remove(?)
- $GLOBALS['perms'] = Perms::singleton();
+ $GLOBALS['perms'] = Horde_Perms::singleton();
}
/**
* applications are defined returns an empty array.
*/
public function listApps($filter = null, $assoc = false,
- $perms = PERMS_SHOW)
+ $perms = Horde_Perms::SHOW)
{
$apps = array();
if (is_null($filter)) {
* - To all admins.
* - To all authenticated users if no permission is set on $app.
* - To anyone who is allowed by an explicit ACL on $app. */
- if ($checkPerms && !$this->hasPermission($app, PERMS_READ)) {
+ if ($checkPerms && !$this->hasPermission($app, Horde_Perms::READ)) {
if (!Horde_Auth::isAuthenticated(array('app' => $app))) {
throw new Horde_Exception('User is not authorized', self::AUTH_FAILURE);
}
*
* @return boolean Whether access is allowed.
*/
- public function hasPermission($app, $perms = PERMS_READ)
+ public function hasPermission($app, $perms = Horde_Perms::READ)
{
/* Always do isAuthenticated() check first. You can be an admin, but
* application auth != Horde admin auth. And there can *never* be
* non-SHOW access to an application that requires authentication. */
if (!Horde_Auth::isAuthenticated(array('app' => $app)) &&
Horde_Auth::requireAuth($app) &&
- ($perms != PERMS_SHOW)) {
+ ($perms != Horde_Perms::SHOW)) {
return false;
}
* Checks to see if a user has a given permission.
*
* @param string $userid The userid of the user.
- * @param integer $permission A PERMS_* constant to test for.
+ * @param integer $permission A Horde_Perms::* constant to test for.
* @param string $creator The creator of the shared object.
*
* @return boolean|PEAR_Error Whether or not $userid has $permission.
} else {
$perms = array(
'users' => array(
- Horde_Auth::getAuth() => PERMS_SHOW | PERMS_READ |
- PERMS_EDIT | PERMS_DELETE));
+ Horde_Auth::getAuth() => Horde_Perms::ALL
+ )
+ );
}
$this->_perms = new Horde_Kolab_Storage_Permission($this, $perms);
}
/**
* Packages that aren't autoloadable yet
*/
-require_once 'Horde/Perms.php';
require_once 'Horde/Group.php';
/**
for ($i = 0, $j = strlen($rights); $i < $j; $i++) {
switch ($rights[$i]) {
case 'l':
- $result |= PERMS_SHOW;
+ $result |= Horde_Perms::SHOW;
break;
case 'r':
- $result |= PERMS_READ;
+ $result |= Horde_Perms::READ;
break;
case 'i':
- $result |= PERMS_EDIT;
+ $result |= Horde_Perms::EDIT;
break;
case 'd':
- $result |= PERMS_DELETE;
+ $result |= Horde_Perms::DELETE;
break;
}
}
{
// Convert the horde permission style to IMAP permissions
$result = $user == $this->_folder->getOwner() ? 'a' : '';
- if ($perms & PERMS_SHOW) {
+ if ($perms & Horde_Perms::SHOW) {
$result .= 'l';
}
- if ($perms & PERMS_READ) {
+ if ($perms & Horde_Perms::READ) {
$result .= 'r';
}
- if ($perms & PERMS_EDIT) {
+ if ($perms & Horde_Perms::EDIT) {
$result .= 'iswc';
}
- if ($perms & PERMS_DELETE) {
+ if ($perms & Horde_Perms::DELETE) {
$result .= 'd';
}
<?php
/**
* @package Kolab_Storage
- *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.3 2009/01/06 17:49:27 jan Exp $
*/
/**
* Packages that aren't autoloadable yet
*/
-require_once 'Horde/Perms.php';
require_once 'Horde/Group.php';
/**
* Permission handling and the IMAP permission system used on the
* Kolab server.
*
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.3 2009/01/06 17:49:27 jan Exp $
- *
* Copyright 2006-2009 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
for ($i = 0, $j = strlen($rights); $i < $j; $i++) {
switch ($rights[$i]) {
case 'l':
- $result |= PERMS_SHOW;
+ $result |= Horde_Perms::SHOW;
break;
case 'r':
- $result |= PERMS_READ;
+ $result |= Horde_Perms::READ;
break;
case 'i':
- $result |= PERMS_EDIT;
+ $result |= Horde_Perms::EDIT;
break;
case 'd':
- $result |= PERMS_DELETE;
+ $result |= Horde_Perms::DELETE;
break;
}
}
{
// Convert the horde permission style to IMAP permissions
$result = $user == $this->_folder->getOwner() ? 'a' : '';
- if ($perms & PERMS_SHOW) {
+ if ($perms & Horde_Perms::SHOW) {
$result .= 'l';
}
- if ($perms & PERMS_READ) {
+ if ($perms & Horde_Perms::READ) {
$result .= 'r';
}
- if ($perms & PERMS_EDIT) {
+ if ($perms & Horde_Perms::EDIT) {
$result .= 'iswc';
}
- if ($perms & PERMS_DELETE) {
+ if ($perms & Horde_Perms::DELETE) {
$result .= 'd';
}
$this->assertEquals(array(), $perms->get('perm'));
$permissions = array('users' =>
array(
- 'wrobel' =>
- PERMS_SHOW |
- PERMS_READ |
- PERMS_EDIT |
- PERMS_DELETE
+ 'wrobel' => Horde_Perms::ALL
));
$perms = new Horde_Kolab_Storage_Permission($folder, $permissions);
$this->assertTrue(is_array($perms->get('perm')));
unset($data['guest']);
unset($data['default']);
unset($data['users']['viewer']);
- $data['users']['editor'] = PERMS_SHOW | PERMS_READ | PERMS_EDIT | PERMS_DELETE;
- $data['users']['test'] = PERMS_SHOW | PERMS_READ;
- $data['groups']['group'] = PERMS_SHOW | PERMS_READ;
+ $data['users']['editor'] = Horde_Perms::ALL;
+ $data['users']['test'] = Horde_Perms::SHOW | Horde_Perms::READ;
+ $data['groups']['group'] = Horde_Perms::SHOW | Horde_Perms::READ;
$perms->setData($data);
$perms->save();
$this->assertNotContains('anyone', array_keys($folder->acl));
$folder = new DummyFolder(array(), 'wrobel');
$hperms = new Horde_Permission('test');
- $hperms->addUserPermission('wrobel', PERMS_SHOW, false);
+ $hperms->addUserPermission('wrobel', Horde_Perms::SHOW, false);
$perms = new Horde_Kolab_Storage_Permission($folder, $hperms->data);
$perms->save();
$this->assertEquals('al', $folder->acl['wrobel']);
/**
* Base for PHPUnit scenarios.
*
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Test/Storage.php,v 1.9 2009/06/24 23:39:23 slusarz Exp $
- *
* PHP version 5
*
* @category Kolab
/**
* Base for PHPUnit scenarios.
*
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Test/Storage.php,v 1.9 2009/06/24 23:39:23 slusarz Exp $
- *
* Copyright 2008-2009 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
$this->prepareNotification();
if (!isset($GLOBALS['perms'])) {
- include_once 'Horde/Perms.php';
- $GLOBALS['perms'] = Perms::singleton();
+ $GLOBALS['perms'] = Horde_Perms::singleton();
}
/** Provide the horde registry */
$folder = $this->prepareNewFolder($storage1, 'Contacts', 'contact', true);
$perms = $folder->getPermission();
- $perms->addUserPermission('test@example.org', PERMS_SHOW);
+ $perms->addUserPermission('test@example.org', Horde_Perms::SHOW);
$perms->save();
$folder = $this->prepareNewFolder($storage1, 'Calendar', 'event', true);
$perms = $folder->getPermission();
- $perms->addUserPermission('test@example.org', PERMS_SHOW);
+ $perms->addUserPermission('test@example.org', Horde_Perms::SHOW);
$perms->save();
/** Prepare a Kolab test storage */
$this->markTestSkipped('The Horde_Mobile package is not installed!');
}
- /** Loading Horde/Registry.php requires the PERMS_* constants */
- require_once 'Horde/Perms.php';
/**
* The listener pulls the registry from global scope to get the image
* directory.
$this->markTestSkipped('The Horde_Perms package is not installed!');
}
- /** Loading Horde/Registry.php requires the PERMS_* constants */
- require_once 'Horde/Perms.php';
/**
* The listener pulls the registry from global scope to get the image
* directory.
--- /dev/null
+<?php
+/**
+ * The Horde_Perms:: class provides the Horde permissions system.
+ *
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms
+{
+ /* Existence of object is known - object is shown to user. */
+ const SHOW = 2;
+ /* Contents of the object can be read. */
+ const READ = 4;
+ /* Contents of the object can be edited. */
+ const EDIT = 8;
+ /* The object can be deleted. */
+ const DELETE = 16;
+
+ /* A bitmask of all possible permission values. Useful for
+ * removeXxxPermission(), unsetPerm(), etc.
+ * 30 = SHOW | READ | EDIT | DELETE */
+ const ALL = 30;
+
+ /* The root permission. */
+ const ROOT = -1;
+
+ /**
+ * Caches information about application permissions.
+ *
+ * @var array
+ */
+ protected $_appPerms;
+
+ /**
+ * Singleton instance.
+ *
+ * @var array
+ */
+ static protected $_instance = null;
+
+ /**
+ * Cache for integerToArray().
+ *
+ * @var array
+ */
+ static protected $_itaCache = array();
+
+ /**
+ * Attempts to return a concrete instance based on $driver.
+ *
+ * @param string $driver The type of the concrete subclass to return.
+ * The class name is based on the perms driver
+ * ($driver). The code is dynamically included.
+ * @param array $params A hash containing any additional configuration
+ * or connection parameters a subclass might need.
+ *
+ * @return Horde_Perms The newly created concrete instance.
+ * @throws Horde_Perms_Exception
+ */
+ static public function factory($driver = null, $params = null)
+ {
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('perms', $driver);
+ }
+
+ if (is_null($driver)) {
+ $perms = new Perms($params);
+ } else {
+ $class = 'Horde_Perms_' . ucfirst(basename($driver));
+ if (!class_exists($class)) {
+ throw new Horde_Perms_Exception('Bad permissions class name: ' . $class);
+ }
+
+ $perms = new $class($params);
+ }
+
+ return $perms;
+ }
+
+ /**
+ * Attempts to return a reference to a concrete instance.
+ * It will only create a new instance if no instance currently exists.
+ *
+ * This method must be invoked as: $var = Horde_Perms::singleton()
+ *
+ * @return Horde_Perms The concrete reference.
+ * @throws Horde_Perms_Exception
+ */
+ static public function singleton()
+ {
+ if (is_null(self::$_instance)) {
+ $perm_driver = $perm_params = null;
+ if (empty($GLOBALS['conf']['perms']['driver'])) {
+ $perm_driver = empty($GLOBALS['conf']['datatree']['driver'])
+ ? null
+ : 'datatree';
+ } else {
+ $perm_driver = $GLOBALS['conf']['perms']['driver'];
+ $perm_params = Horde::getDriverConfig('perms', $perm_driver);
+ }
+
+ self::$_instance = self::factory($perm_driver, $perm_params);
+ }
+
+ return self::$_instance;
+ }
+
+ /**
+ * Returns the available permissions for a given level.
+ *
+ * @param string $name The permission's name.
+ *
+ * @return array An array of available permissions and their titles or
+ * false if not sub permissions exist for this level.
+ * @throws Horde_Perms_Exception
+ */
+ public function getAvailable($name)
+ {
+ if ($name == self::ROOT) {
+ $name = '';
+ }
+
+ if (empty($name)) {
+ /* No name passed, so top level permissions are requested. These
+ * can only be applications. */
+ $apps = $GLOBALS['registry']->listApps(array('notoolbar', 'active', 'hidden'), true);
+ foreach (array_keys($apps) as $app) {
+ $apps[$app] = $GLOBALS['registry']->get('name', $app) . ' (' . $app . ')';
+ }
+ asort($apps);
+
+ return $apps;
+ }
+
+ /* Name has been passed, explode the name to get all the levels in
+ * permission being requisted, with the app as the first level. */
+ $levels = explode(':', $name);
+
+ /* First level is always app. */
+ $app = $levels[0];
+
+ /* Return empty if no app defined API method for providing
+ * permission information. */
+ if (!$GLOBALS['registry']->hasAppMethod($app, 'perms')) {
+ return false;
+ }
+
+ /* Call the app's permission function to return the permissions
+ * specific to this app. */
+ $perms = $this->getApplicationPermissions($app);
+
+ /* Get the part of the app's permissions based on the permission
+ * name requested. */
+ $children = Horde_Array::getElement($perms['tree'], $levels);
+ if (($children === false) ||
+ !is_array($children) ||
+ !count($children)) {
+ /* No array of children available for this permission name. */
+ return false;
+ }
+
+ $perms_list = array();
+ foreach ($children as $perm_key => $perm_val) {
+ $perms_list[$perm_key] = $perms['title'][$name . ':' . $perm_key];
+ }
+
+ return $perms_list;
+ }
+
+ /**
+ * Returns the short name of an object, the last portion of the full name.
+ *
+ * @param string $name The name of the object.
+ *
+ * @return string The object's short name.
+ */
+ static public function getShortName($name)
+ {
+ /* If there are several components to the name, explode and
+ * get the last one, otherwise just return the name. */
+ if (strpos($name, ':') !== false) {
+ $tmp = explode(':', $name);
+ return array_pop($tmp);
+ }
+
+ return $name;
+ }
+
+ /**
+ * Given a permission name, returns the title for that permission by
+ * looking it up in the applications's permission api.
+ *
+ * @param string $name The permissions's name.
+ *
+ * @return string The title for the permission.
+ */
+ public function getTitle($name)
+ {
+ if ($name === self::ROOT) {
+ return _("All Permissions");
+ }
+
+ $levels = explode(':', $name);
+ if (count($levels) == 1) {
+ return $GLOBALS['registry']->get('name', $name) . ' (' . $name . ')';
+ }
+ $perm = array_pop($levels);
+
+ /* First level is always app. */
+ $app = $levels[0];
+
+ /* Return empty if no app defined API method for providing permission
+ * information. */
+ if (!$GLOBALS['registry']->hasAppMethod($app, 'perms')) {
+ return $this->getShortName($name);
+ }
+
+ $app_perms = $this->getApplicationPermissions($app);
+
+ return isset($app_perms['title'][$name])
+ ? $app_perms['title'][$name] . ' (' . $this->getShortName($name) . ')'
+ : $this->getShortName($name);
+ }
+
+ /**
+ * Returns information about permissions implemented by an application.
+ *
+ * @param string $app An application name.
+ *
+ * @return array Hash with permissions information.
+ */
+ public function getApplicationPermissions($app)
+ {
+ if (!isset($this->_appPerms[$app])) {
+ try {
+ $this->_appPerms[$app] = $GLOBALS['registry']->callAppMethod($app, 'perms');
+ } catch (Horde_Exception $e) {
+ $this->_appPerms[$app] = array();
+ }
+ }
+
+ return $this->_appPerms[$app];
+ }
+
+ /**
+ * Returns a new permissions object.
+ *
+ * @param string $name The permission's name.
+ *
+ * @return Horde_Perms_Permission A new permissions object.
+ * @throws Horde_Perms_Exception
+ */
+ public function newPermission($name)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Returns an object corresponding to the named permission, with the users
+ * and other data retrieved appropriately.
+ *
+ * @param string $name The name of the permission to retrieve.
+ *
+ * @return Horde_Perms_Permission A permissions object.
+ * @throws Horde_Perms_Exception
+ */
+ public function getPermission($name)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Returns an object corresponding to the given unique ID, with the users
+ * and other data retrieved appropriately.
+ *
+ * @param integer $cid The unique ID of the permission to retrieve.
+ *
+ * @return Horde_Perms_Permission A permissions object.
+ * @throws Horde_Perms_Exception
+ */
+ public function getPermissionById($cid)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Adds a permission to the permissions system. The permission must first
+ * be created with newPermission(), and have any initial users added to
+ * it, before this function is called.
+ *
+ * @param Horde_Perms_Permission $perm The permissions object.
+ *
+ * @throws Horde_Perms_Exception
+ */
+ public function addPermission($perm)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Removes a permission from the permissions system permanently.
+ *
+ * @param Horde_Perms_Permission $perm The permission to remove.
+ * @param boolean $force Force to remove every child.
+ *
+ * @throws Horde_Perms_Exception
+ */
+ public function removePermission($perm, $force = false)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Finds out what rights the given user has to this object.
+ *
+ * @param mixed $permission The full permission name of the object to
+ * check the permissions of, or the
+ * Horde_Permissions object.
+ * @param string $user The user to check for. Defaults to the current
+ * user.
+ * @param string $creator The user who created the event.
+ *
+ * @return mixed A bitmask of permissions the user has, false if there
+ * are none.
+ */
+ public function getPermissions($permission, $user = null, $creator = null)
+ {
+ if (is_string($permission)) {
+ try {
+ $permission = $this->getPermission($permission);
+ } catch (Horde_Perms_Exception $e) {
+ Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return false;
+ }
+ }
+
+ if (is_null($user)) {
+ $user = Horde_Auth::getAuth();
+ }
+
+ // If this is a guest user, only check guest permissions.
+ if (empty($user)) {
+ return $permission->getGuestPermissions();
+ }
+
+ // If $creator was specified, check creator permissions.
+ // If the user is the creator of the event see if there are creator
+ // permissions.
+ if (!is_null($creator) &&
+ strlen($user) &&
+ ($user === $creator) &&
+ (($perms = $permission->getCreatorPermissions()) !== null)) {
+ return $perms;
+ }
+
+ // Check user-level permissions.
+ $userperms = $permission->getUserPermissions();
+ if (isset($userperms[$user])) {
+ return $userperms[$user];
+ }
+
+ // If no user permissions are found, try group permissions.
+ if (isset($permission->data['groups']) &&
+ is_array($permission->data['groups']) &&
+ count($permission->data['groups'])) {
+ require_once 'Horde/Group.php';
+ $groups = Group::singleton();
+
+ $composite_perm = null;
+ $type = $permission->get('type');
+ foreach ($permission->data['groups'] as $group => $perm) {
+ if ($groups->userIsInGroup($user, $group)) {
+ if (is_null($composite_perm)) {
+ $composite_perm = ($type == 'matrix') ? 0 : array();
+ }
+
+ if ($type == 'matrix') {
+ $composite_perm |= $perm;
+ } else {
+ $composite_perm[] = $perm;
+ }
+ }
+ }
+
+ if (!is_null($composite_perm)) {
+ return $composite_perm;
+ }
+ }
+
+ // If there are default permissions, return them.
+ if (($perms = $permission->getDefaultPermissions()) !== null) {
+ return $perms;
+ }
+
+ // Otherwise, deny all permissions to the object.
+ return false;
+ }
+
+ /**
+ * Returns the unique identifier of this permission.
+ *
+ * @param Horde_Perms_Permission $permission The permission object to get
+ * the ID of.
+ *
+ * @return integer The unique id.
+ * @throws Horde_Perms_Exception
+ */
+ public function getPermissionId($permission)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Finds out if the user has the specified rights to the given object.
+ *
+ * @param string $permission The permission to check.
+ * @param string $user The user to check for.
+ * @param integer $perm The permission level that needs to be checked
+ * for.
+ * @param string $creator The creator of the event
+ *
+ * @return boolean Whether the user has the specified permissions.
+ */
+ public function hasPermission($permission, $user, $perm, $creator = null)
+ {
+ return ($this->getPermissions($permission, $user, $creator) & $perm);
+ }
+
+ /**
+ * Checks if a permission exists in the system.
+ *
+ * @param string $permission The permission to check.
+ *
+ * @return boolean True if the permission exists.
+ */
+ public function exists($permission)
+ {
+ return false;
+ }
+
+ /**
+ * Returns a list of parent permissions.
+ *
+ * @param string $child The name of the child to retrieve parents for.
+ *
+ * @return array A hash with all parents in a tree format.
+ * @throws Horde_Perms_Exception
+ */
+ public function getParents($child)
+ {
+ throw new Horde_Perms_Exception('The administrator needs to configure a permanent permissions backend.');
+ }
+
+ /**
+ * Returns all permissions of the system in a tree format.
+ *
+ * @return array A hash with all permissions in a tree format.
+ */
+ public function getTree()
+ {
+ return array();
+ }
+
+ /**
+ * Returns an hash of the available permissions.
+ *
+ * @return array The available permissions as a hash.
+ */
+ static public function getPermsArray()
+ {
+ return array(
+ self::SHOW => _("Show"),
+ self::READ => _("Read"),
+ self::EDIT => _("Edit"),
+ self::DELETE => _("Delete")
+ );
+ }
+
+ /**
+ * Given an integer value of permissions returns an array representation
+ * of the integer.
+ *
+ * @param integer $int The integer representation of permissions.
+ *
+ * @return TODO
+ */
+ static public function integerToArray($int)
+ {
+ if (isset(self::$_itaCache[$int])) {
+ return self::$_itaCache[$int];
+ }
+
+ self::$_itaCache[$int] = array();
+
+ /* Get the available perms array. */
+ $perms = self::getPermsArray();
+
+ /* Loop through each perm and check if its value is included in the
+ * integer representation. */
+ foreach ($perms as $val => $label) {
+ if ($int & $val) {
+ self::$_itaCache[$int][$val] = true;
+ }
+ }
+
+ return self::$_itaCache[$int];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Perms_Datatree:: class provides a DataTree driver for the Horde
+ * permissions system.
+ *
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Datatree extends Horde_Perms
+{
+ /**
+ * Pointer to a DataTree instance to manage the different permissions.
+ *
+ * @var DataTree
+ */
+ protected $_datatree;
+
+ /**
+ * Pointer to a Horde_Cache instance.
+ *
+ * @var Horde_Cache
+ */
+ protected $_cache;
+
+ /**
+ * Cache for getPermission().
+ *
+ * @var array
+ */
+ protected $_permsCache = array();
+
+ /**
+ * Constructor.
+ *
+ * @throws Horde_Exception
+ */
+ public function __construct()
+ {
+ global $conf;
+
+ if (empty($conf['datatree']['driver'])) {
+ throw new Horde_Exception('You must configure a DataTree backend.');
+ }
+
+ $driver = $conf['datatree']['driver'];
+ $this->_datatree = DataTree::singleton($driver,
+ array_merge(Horde::getDriverConfig('datatree', $driver),
+ array('group' => 'horde.perms')));
+
+ $this->_cache = Horde_Cache::singleton($GLOBALS['conf']['cache']['driver'],
+ Horde::getDriverConfig('cache', $GLOBALS['conf']['cache']['driver']));
+
+ parent::__construct();
+ }
+
+ /**
+ * Returns a new permissions object.
+ *
+ * @param string $name The permission's name.
+ *
+ * @return DataTreeObject_Permissions A new permissions object.
+ */
+ public function newPermission($name)
+ {
+ $type = 'matrix';
+ $params = null;
+
+ if ($pos = strpos($name, ':')) {
+ try {
+ $info = $this->getApplicationPermissions(substr($name, 0, $pos));
+ if (isset($info['type']) && isset($info['type'][$name])) {
+ $type = $info['type'][$name];
+ }
+
+ if (isset($info['params']) && isset($info['params'][$name])) {
+ $params = $info['params'][$name];
+ }
+ } catch (Horde_Perms_Exception $e) {}
+ }
+
+ $perm = new Horde_Perms_Permission_DataTreeObject($name, $type, $params);
+ $perm->setDataTree($this->_datatree);
+
+ return $perm;
+ }
+
+ /**
+ * Returns a permission object corresponding to the named permission,
+ * with the users and other data retrieved appropriately.
+ *
+ * @param string $name The name of the permission to retrieve.
+ *
+ * @return TODO
+ */
+ public function getPermission($name)
+ {
+ if (isset($this->_permsCache[$name])) {
+ return $this->_permsCache[$name];
+ }
+
+ $perm = $this->_cache->get('perm_' . $name, $GLOBALS['conf']['cache']['default_lifetime']);
+ if ($perm === false) {
+ $perm = $this->_datatree->getObject($name, 'Horde_Perms_Permission_DataTreeObject');
+ $this->_cache->set('perm_' . $name, serialize($perm), $GLOBALS['conf']['cache']['default_lifetime']);
+ $this->_permsCache[$name] = $perm;
+ } else {
+ $this->_permsCache[$name] = unserialize($perm);
+ }
+
+ return $this->_permsCache[$name];
+ }
+
+ /**
+ * Returns a permission object corresponding to the given unique ID,
+ * with the users and other data retrieved appropriately.
+ *
+ * @param integer $cid The unique ID of the permission to retrieve.
+ */
+ public function getPermissionById($cid)
+ {
+ return ($cid == Horde_Perms::ROOT)
+ ? $this->newPermission(Horde_Perms::ROOT)
+ : $this->_datatree->getObjectById($cid, 'Horde_Perms_Permission_DataTreeObject');
+ }
+
+ /**
+ * Adds a permission to the permissions system. The permission must first
+ * be created with newPermission(), and have any initial users added to
+ * it, before this function is called.
+ *
+ * @param Horde_Perms_Permission_DataTreeObject $perm The new perm
+ * object.
+ * @throws Horde_Perms_Exception
+ */
+ public function addPermission($perm)
+ {
+ if (!($perm instanceof Horde_Perms_Permission_DataTreeObject)) {
+ throw Horde_Perms_Exception('Permissions must be Horde_Perms_Permission_DataTreeObject objects.');
+ }
+
+ $name = $perm->getName();
+ if (empty($name)) {
+ throw Horde_Perms_Exception('Permission names must be non-empty.');
+ }
+ $this->_cache->expire('perm_' . $name);
+ $this->_cache->expire('perm_exists_' . $name);
+
+ return $this->_datatree->add($perm);
+ }
+
+ /**
+ * Removes a permission from the permissions system permanently.
+ *
+ * @param Horde_Perms_Permission_DataTreeObject $perm The permission to
+ * remove.
+ * @param boolean $force Force to remove
+ * every child.
+ */
+ public function removePermission($perm, $force = false)
+ {
+ if (!($perm instanceof Horde_Perms_Permission_DataTreeObject)) {
+ throw Horde_Perms_Exception('Permissions must be Horde_Perms_Permission_DataTreeObject objects.');
+ }
+
+ $keys = $this->_datatree->get(DATATREE_FORMAT_FLAT, $perm->name, true);
+ foreach ($keys as $key) {
+ $this->_cache->expire('perm_' . $key);
+ $this->_cache->expire('perm_exists_' . $key);
+ }
+
+ return $this->_datatree->remove($perm->name, $force);
+ }
+
+ /**
+ * Returns the unique identifier of this permission.
+ *
+ * @param Horde_Perms_Permission_DataTreeObject $perm The permission
+ * object to get the
+ * ID of.
+ *
+ * @return integer The unique id.
+ */
+ public function getPermissionId($permission)
+ {
+ return $this->_datatree->getId($permission->getName());
+ }
+
+ /**
+ * Checks if a permission exists in the system.
+ *
+ * @param string $permission The permission to check.
+ *
+ * @return boolean True if the permission exists.
+ */
+ public function exists($permission)
+ {
+ $key = 'perm_exists_' . $permission;
+ $exists = $this->_cache->get($key, $GLOBALS['conf']['cache']['default_lifetime']);
+ if ($exists === false) {
+ $exists = $this->_datatree->exists($permission);
+ $this->_cache->set($key, (string)$exists);
+ }
+
+ return (bool)$exists;
+ }
+
+ /**
+ * Returns a list of parent permissions.
+ *
+ * @param string $child The name of the child to retrieve parents for.
+ *
+ * @return array A hash with all parents in a tree format.
+ */
+ public function getParents($child)
+ {
+ return $this->_datatree->getParents($child);
+ }
+
+ /**
+ * Returns a child's direct parent ID.
+ *
+ * @param mixed $child Either the object, an array containing the
+ * path elements, or the object name for which
+ * to look up the parent's ID.
+ *
+ * @return mixed The unique ID of the parent or PEAR_Error on error.
+ */
+ public function getParent($child)
+ {
+ return $this->_datatree->getParent($child);
+ }
+
+ /**
+ * Returns all permissions of the system in a tree format.
+ *
+ * @return array A hash with all permissions in a tree format.
+ */
+ public function getTree()
+ {
+ return $this->_datatree->get(DATATREE_FORMAT_FLAT, Horde_Perms::ROOT, true);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Exception handler for the Horde_Perms package.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Exception extends Horde_Exception
+{
+}
--- /dev/null
+<?php
+/**
+ * Instance of a single permissioning object.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Permission
+{
+ // TODO
+ public $data;
+
+ // TODO
+ public $name;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the perm.
+ * @param string $type The permission type.
+ * @param array $params A hash with any parameters that the permission
+ * type needs.
+ */
+ public function __construct($name, $type = 'matrix', $params = null)
+ {
+ $this->setName($name);
+ $this->data['type'] = $type;
+ if (is_array($params)) {
+ $this->data['params'] = $params;
+ }
+ }
+
+ /**
+ * Gets one of the attributes of the object, or null if it isn't defined.
+ *
+ * @param string $attribute The attribute to get.
+ *
+ * @return mixed The value of the attribute, or null.
+ */
+ public function get($attribute)
+ {
+ if (isset($this->data[$attribute])) {
+ return $this->data[$attribute];
+ }
+
+ return ($attribute == 'type') ? 'matrix' : null;
+ }
+
+ /**
+ * Get permission name.
+ *
+ * @return string Permission name.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Set permission name
+ *
+ * @param string $name Permission name.
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Get permission details.
+ *
+ * @return array Permission details.
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Set permission details.
+ *
+ * @param string $data Permission details.
+ */
+ public function setData($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Updates the permissions based on data passed in the array.
+ *
+ * @param array $perms An array containing the permissions which are to
+ * be updated.
+ */
+ public function updatePermissions($perms)
+ {
+ $type = $this->get('type');
+
+ if ($type == 'matrix') {
+ /* Array of permission types to iterate through. */
+ $perm_types = Horde_Perms::getPermsArray();
+ }
+
+ foreach ($perms as $perm_class => $perm_values) {
+ switch ($perm_class) {
+ case 'default':
+ case 'guest':
+ case 'creator':
+ if ($type == 'matrix') {
+ foreach ($perm_types as $val => $label) {
+ if (!empty($perm_values[$val])) {
+ $this->setPerm($perm_class, $val, false);
+ } else {
+ $this->unsetPerm($perm_class, $val, false);
+ }
+ }
+ } elseif (!empty($perm_values)) {
+ $this->setPerm($perm_class, $perm_values, false);
+ } else {
+ $this->unsetPerm($perm_class, null, false);
+ }
+ break;
+
+ case 'u':
+ case 'g':
+ $permId = array('class' => $perm_class == 'u' ? 'users' : 'groups');
+ /* Figure out what names that are stored in this permission
+ * class have not been submitted for an update, ie. have been
+ * removed entirely. */
+ $current_names = isset($this->data[$permId['class']])
+ ? array_keys($this->data[$permId['class']])
+ : array();
+ $updated_names = array_keys($perm_values);
+ $removed_names = array_diff($current_names, $updated_names);
+
+ /* Remove any names that have been completely unset. */
+ foreach ($removed_names as $name) {
+ unset($this->data[$permId['class']][$name]);
+ }
+
+ /* If nothing to actually update finish with this case. */
+ if (is_null($perm_values)) {
+ continue;
+ }
+
+ /* Loop through the names and update permissions for each. */
+ foreach ($perm_values as $name => $name_values) {
+ $permId['name'] = $name;
+
+ if ($type == 'matrix') {
+ foreach ($perm_types as $val => $label) {
+ if (!empty($name_values[$val])) {
+ $this->setPerm($permId, $val, false);
+ } else {
+ $this->unsetPerm($permId, $val, false);
+ }
+ }
+ } elseif (!empty($name_values)) {
+ $this->setPerm($permId, $name_values, false);
+ } else {
+ $this->unsetPerm($permId, null, false);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function setPerm($permId, $permission, $update = true)
+ {
+ if (is_array($permId)) {
+ if (empty($permId['name'])) {
+ return;
+ }
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data[$permId['class']][$permId['name']])) {
+ $this->data[$permId['class']][$permId['name']] |= $permission;
+ } else {
+ $this->data[$permId['class']][$permId['name']] = $permission;
+ }
+ } else {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data[$permId])) {
+ $this->data[$permId] |= $permission;
+ } else {
+ $this->data[$permId] = $permission;
+ }
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function unsetPerm($permId, $permission, $update = true)
+ {
+ if (is_array($permId)) {
+ if (empty($permId['name'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ if (isset($this->data[$permId['class']][$permId['name']])) {
+ $this->data[$permId['class']][$permId['name']] &= ~$permission;
+ if (empty($this->data[$permId['class']][$permId['name']])) {
+ unset($this->data[$permId['class']][$permId['name']]);
+ }
+ } else {
+ $update = false;
+ }
+ } else {
+ unset($this->data[$permId['class']][$permId['name']]);
+ }
+ } else {
+ if ($this->get('type') == 'matrix') {
+ if (isset($this->data[$permId])) {
+ $this->data[$permId] &= ~$permission;
+ } else {
+ $update = false;
+ }
+ } else {
+ unset($this->data[$permId]);
+ }
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants a user additional permissions to this object.
+ *
+ * @param string $uer The user to grant additional permissions
+ * to.
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addUserPermission($user, $permission, $update = true)
+ {
+ if (empty($user)) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['users'][$user])) {
+ $this->data['users'][$user] |= $permission;
+ } else {
+ $this->data['users'][$user] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants guests additional permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addGuestPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['guest'])) {
+ $this->data['guest'] |= $permission;
+ } else {
+ $this->data['guest'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants creators additional permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addCreatorPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['creator'])) {
+ $this->data['creator'] |= $permission;
+ } else {
+ $this->data['creator'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants additional default permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addDefaultPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['default'])) {
+ $this->data['default'] |= $permission;
+ } else {
+ $this->data['default'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants a group additional permissions to this object.
+ *
+ * @param integer $groupId The id of the group to grant additional
+ * permissions to.
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addGroupPermission($groupId, $permission, $update = true)
+ {
+ if (empty($groupId)) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['groups'][$groupId])) {
+ $this->data['groups'][$groupId] |= $permission;
+ } else {
+ $this->data['groups'][$groupId] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that a user currently has on this object.
+ *
+ * @param string $user The user to remove the permission from.
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeUserPermission($user, $permission, $update = true)
+ {
+ if (empty($user) || !isset($this->data['users'][$user])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['users'][$user] &= ~$permission;
+ if (empty($this->data['users'][$user])) {
+ unset($this->data['users'][$user]);
+ }
+ } else {
+ unset($this->data['users'][$user]);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that guests currently have on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeGuestPermission($permission, $update = true)
+ {
+ if (!isset($this->data['guest'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['guest'] &= ~$permission;
+ } else {
+ unset($this->data['guest']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that creators currently have on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeCreatorPermission($permission, $update = true)
+ {
+ if (!isset($this->data['creator'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['creator'] &= ~$permission;
+ } else {
+ unset($this->data['creator']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a default permission on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeDefaultPermission($permission, $update = true)
+ {
+ if (!isset($this->data['default'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['default'] &= ~$permission;
+ } else {
+ unset($this->data['default']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that a group currently has on this object.
+ *
+ * @param integer $groupId The id of the group to remove the
+ * permission from.
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeGroupPermission($groupId, $permission,
+ $update = true)
+ {
+ if (empty($groupId) || !isset($this->data['groups'][$groupId])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['groups'][$groupId] &= ~$permission;
+ if (empty($this->data['groups'][$groupId])) {
+ unset($this->data['groups'][$groupId]);
+ }
+ } else {
+ unset($this->data['groups'][$groupId]);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Returns an array of all user permissions on this object.
+ *
+ * @param integer $perm List only users with this permission level.
+ * Defaults to all users.
+ *
+ * @return array All user permissions for this object, indexed by user.
+ */
+ public function getUserPermissions($perm = null)
+ {
+ if (!isset($this->data['users']) || !is_array($this->data['users'])) {
+ return array();
+ } elseif (!$perm) {
+ return $this->data['users'];
+ }
+
+ $users = array();
+ foreach ($this->data['users'] as $user => $uperm) {
+ if ($uperm & $perm) {
+ $users[$user] = $uperm;
+ }
+ }
+
+ return $users;
+ }
+
+ /**
+ * Returns the guest permissions on this object.
+ *
+ * @return integer The guest permissions on this object.
+ */
+ public function getGuestPermissions()
+ {
+ return empty($this->data['guest'])
+ ? null
+ : $this->data['guest'];
+ }
+
+ /**
+ * Returns the creator permissions on this object.
+ *
+ * @return integer The creator permissions on this object.
+ */
+ public function getCreatorPermissions()
+ {
+ return empty($this->data['creator'])
+ ? null
+ : $this->data['creator'];
+ }
+
+ /**
+ * Returns the default permissions on this object.
+ *
+ * @return integer The default permissions on this object.
+ */
+ public function getDefaultPermissions()
+ {
+ return empty($this->data['default'])
+ ? null
+ : $this->data['default'];
+ }
+
+ /**
+ * Returns an array of all group permissions on this object.
+ *
+ * @param integer $perm List only users with this permission level.
+ * Defaults to all users.
+ *
+ * @return array All group permissions for this object, indexed by group.
+ */
+ public function getGroupPermissions($perm = null)
+ {
+ if (!isset($this->data['groups']) ||
+ !is_array($this->data['groups'])) {
+ return array();
+ } elseif (!$perm) {
+ return $this->data['groups'];
+ }
+
+ $groups = array();
+ foreach ($this->data['groups'] as $group => $gperm) {
+ if ($gperm & $perm) {
+ $groups[$group] = $gperm;
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * TODO
+ */
+ public function save()
+ {
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Extension of the DataTreeObject class for storing Permission information in
+ * the DataTree driver. If you want to store specialized Permission
+ * information, you should extend this class instead of extending
+ * DataTreeObject directly.
+ *
+ * @TODO This class duplicates most of the functionality of the
+ * Horde_Permission class. However, because for BC/DataTree reasons it
+ * must extend DataTreeObject, we can't remove these methods yet.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Permission_DataTreeObject extends DataTreeObject
+{
+ /**
+ * Constructor. Just makes sure to call the parent constructor so that
+ * the perm's name is set properly.
+ *
+ * @param string $name The name of the perm.
+ * @param string $type The permission type.
+ * @param array $params A hash with any parameters that the permission
+ * type needs.
+ */
+ public function __construct($name, $type = 'matrix', $params = null)
+ {
+ parent::DataTreeObject($name);
+
+ $this->data['type'] = $type;
+ if (is_array($params)) {
+ $this->data['params'] = $params;
+ }
+ }
+
+ /**
+ * Gets one of the attributes of the object, or null if it isn't defined.
+ *
+ * @param string $attribute The attribute to get.
+ *
+ * @return mixed The value of the attribute, or null.
+ */
+ public function get($attribute)
+ {
+ $value = parent::get($attribute);
+
+ return (is_null($value) && $attribute == 'type')
+ ? 'matrix'
+ : $value;
+ }
+
+ /**
+ * Updates the permissions based on data passed in the array.
+ *
+ * @param array $perms An array containing the permissions which are to
+ * be updated.
+ */
+ public function updatePermissions($perms)
+ {
+ $type = $this->get('type');
+
+ if ($type == 'matrix') {
+ /* Array of permission types to iterate through. */
+ $perm_types = Horde_Perms::getPermsArray();
+ }
+
+ foreach ($perms as $perm_class => $perm_values) {
+ switch ($perm_class) {
+ case 'default':
+ case 'guest':
+ case 'creator':
+ if ($type == 'matrix') {
+ foreach ($perm_types as $val => $label) {
+ if (!empty($perm_values[$val])) {
+ $this->setPerm($perm_class, $val, false);
+ } else {
+ $this->unsetPerm($perm_class, $val, false);
+ }
+ }
+ } elseif (!empty($perm_values)) {
+ $this->setPerm($perm_class, $perm_values, false);
+ } else {
+ $this->unsetPerm($perm_class, null, false);
+ }
+ break;
+
+ case 'u':
+ case 'g':
+ $permId = array('class' => $perm_class == 'u' ? 'users' : 'groups');
+ /* Figure out what names that are stored in this permission
+ * class have not been submitted for an update, ie. have been
+ * removed entirely. */
+ $current_names = isset($this->data[$permId['class']])
+ ? array_keys($this->data[$permId['class']])
+ : array();
+ $updated_names = array_keys($perm_values);
+ $removed_names = array_diff($current_names, $updated_names);
+
+ /* Remove any names that have been completely unset. */
+ foreach ($removed_names as $name) {
+ unset($this->data[$permId['class']][$name]);
+ }
+
+ /* If nothing to actually update finish with this case. */
+ if (is_null($perm_values)) {
+ continue;
+ }
+
+ /* Loop through the names and update permissions for each. */
+ foreach ($perm_values as $name => $name_values) {
+ $permId['name'] = $name;
+
+ if ($type == 'matrix') {
+ foreach ($perm_types as $val => $label) {
+ if (!empty($name_values[$val])) {
+ $this->setPerm($permId, $val, false);
+ } else {
+ $this->unsetPerm($permId, $val, false);
+ }
+ }
+ } elseif (!empty($name_values)) {
+ $this->setPerm($permId, $name_values, false);
+ } else {
+ $this->unsetPerm($permId, null, false);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function setPerm($permId, $permission, $update = true)
+ {
+ if (is_array($permId)) {
+ if (empty($permId['name'])) {
+ return;
+ }
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data[$permId['class']][$permId['name']])) {
+ $this->data[$permId['class']][$permId['name']] |= $permission;
+ } else {
+ $this->data[$permId['class']][$permId['name']] = $permission;
+ }
+ } else {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data[$permId])) {
+ $this->data[$permId] |= $permission;
+ } else {
+ $this->data[$permId] = $permission;
+ }
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function unsetPerm($permId, $permission, $update = true)
+ {
+ if (is_array($permId)) {
+ if (empty($permId['name'])) {
+ return;
+ }
+ if ($this->get('type') == 'matrix') {
+ if (isset($this->data[$permId['class']][$permId['name']])) {
+ $this->data[$permId['class']][$permId['name']] &= ~$permission;
+ if (empty($this->data[$permId['class']][$permId['name']])) {
+ unset($this->data[$permId['class']][$permId['name']]);
+ }
+ if ($update) {
+ $this->save();
+ }
+ }
+ } else {
+ unset($this->data[$permId['class']][$permId['name']]);
+ if ($update) {
+ $this->save();
+ }
+ }
+ } else {
+ if ($this->get('type') == 'matrix') {
+ if (isset($this->data[$permId])) {
+ $this->data[$permId] &= ~$permission;
+ if ($update) {
+ $this->save();
+ }
+ }
+ } else {
+ unset($this->data[$permId]);
+ if ($update) {
+ $this->save();
+ }
+ }
+ }
+ }
+
+ /**
+ * Grants a user additional permissions to this object.
+ *
+ * @param string $user The user to grant additional permissions
+ * to.
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addUserPermission($user, $permission, $update = true)
+ {
+ if (empty($user)) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['users'][$user])) {
+ $this->data['users'][$user] |= $permission;
+ } else {
+ $this->data['users'][$user] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants guests additional permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addGuestPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['guest'])) {
+ $this->data['guest'] |= $permission;
+ } else {
+ $this->data['guest'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants creators additional permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addCreatorPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['creator'])) {
+ $this->data['creator'] |= $permission;
+ } else {
+ $this->data['creator'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants additional default permissions to this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addDefaultPermission($permission, $update = true)
+ {
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['default'])) {
+ $this->data['default'] |= $permission;
+ } else {
+ $this->data['default'] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Grants a group additional permissions to this object.
+ *
+ * @param integer $groupId The id of the group to grant additional
+ * permissions to.
+ * @param integer $permission The permission (DELETE, etc.) to add.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function addGroupPermission($groupId, $permission, $update = true)
+ {
+ if (empty($groupId)) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix' &&
+ isset($this->data['groups'][$groupId])) {
+ $this->data['groups'][$groupId] |= $permission;
+ } else {
+ $this->data['groups'][$groupId] = $permission;
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that a user currently has on this object.
+ *
+ * @param string $user The user to remove the permission from.
+ * @param integer $permission The permission (DELETE, etc.) to
+ * remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeUserPermission($user, $permission, $update = true)
+ {
+ if (empty($user) || !isset($this->data['users'][$user])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['users'][$user] &= ~$permission;
+ if (empty($this->data['users'][$user])) {
+ unset($this->data['users'][$user]);
+ }
+ } else {
+ unset($this->data['users'][$user]);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that guests currently have on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeGuestPermission($permission, $update = true)
+ {
+ if (!isset($this->data['guest'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['guest'] &= ~$permission;
+ } else {
+ unset($this->data['guest']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that creators currently have on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeCreatorPermission($permission, $update = true)
+ {
+ if (!isset($this->data['creator'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['creator'] &= ~$permission;
+ } else {
+ unset($this->data['creator']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a default permission on this object.
+ *
+ * @param integer $permission The permission (DELETE, etc.) to remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeDefaultPermission($permission, $update = true)
+ {
+ if (!isset($this->data['default'])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['default'] &= ~$permission;
+ } else {
+ unset($this->data['default']);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Removes a permission that a group currently has on this object.
+ *
+ * @param integer $groupId The id of the group to remove the
+ * permission from.
+ * @param integer $permission The permission (DELETE, etc.) to remove.
+ * @param boolean $update Whether to automatically update the
+ * backend.
+ */
+ public function removeGroupPermission($groupId, $permission,
+ $update = true)
+ {
+ if (empty($groupId) || !isset($this->data['groups'][$groupId])) {
+ return;
+ }
+
+ if ($this->get('type') == 'matrix') {
+ $this->data['groups'][$groupId] &= ~$permission;
+ if (empty($this->data['groups'][$groupId])) {
+ unset($this->data['groups'][$groupId]);
+ }
+ } else {
+ unset($this->data['groups'][$groupId]);
+ }
+
+ if ($update) {
+ $this->save();
+ }
+ }
+
+ /**
+ * Returns an array of all user permissions on this object.
+ *
+ * @param integer $perm List only users with this permission level.
+ * Defaults to all users.
+ *
+ * @return array All user permissions for this object, indexed by user.
+ */
+ public function getUserPermissions($perm = null)
+ {
+ if (!isset($this->data['users']) || !is_array($this->data['users'])) {
+ return array();
+ } elseif (!$perm) {
+ return $this->data['users'];
+ }
+
+ $users = array();
+ foreach ($this->data['users'] as $user => $uperm) {
+ if ($uperm & $perm) {
+ $users[$user] = $uperm;
+ }
+ }
+
+ return $users;
+ }
+
+ /**
+ * Returns the guest permissions on this object.
+ *
+ * @return integer The guest permissions on this object.
+ */
+ public function getGuestPermissions()
+ {
+ return empty($this->data['guest'])
+ ? null
+ : $this->data['guest'];
+ }
+
+ /**
+ * Returns the creator permissions on this object.
+ *
+ * @return integer The creator permissions on this object.
+ */
+ public function getCreatorPermissions()
+ {
+ return empty($this->data['creator'])
+ ? null
+ : $this->data['creator'];
+ }
+
+ /**
+ * Returns the default permissions on this object.
+ *
+ * @return integer The default permissions on this object.
+ */
+ public function getDefaultPermissions()
+ {
+ return empty($this->data['default'])
+ ? null
+ : $this->data['default'];
+ }
+
+ /**
+ * Returns an array of all group permissions on this object.
+ *
+ * @param integer $perm List only users with this permission level.
+ * Defaults to all users.
+ *
+ * @return array All group permissions for this object, indexed by group.
+ */
+ public function getGroupPermissions($perm = null)
+ {
+ if (!isset($this->data['groups']) ||
+ !is_array($this->data['groups'])) {
+ return array();
+ } elseif (!$perm) {
+ return $this->data['groups'];
+ }
+
+ $groups = array();
+ foreach ($this->data['groups'] as $group => $gperm) {
+ if ($gperm & $perm) {
+ $groups[$group] = $gperm;
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Saves any changes to this object to the backend permanently. New
+ * objects are added instead.
+ *
+ * @throws Horde_Perms_Exception
+ */
+ public function save()
+ {
+ $name = $this->getName();
+ if (empty($name)) {
+ throw new Horde_Perms_Exception('Permission names must be non-empty');
+ }
+
+ parent::save();
+
+ $cache = Horde_Cache::singleton($GLOBALS['conf']['cache']['driver'], Horde::getDriverConfig('cache', $GLOBALS['conf']['cache']['driver']));
+ $cache->expire('perm_' . $name);
+ $cache->expire('perm_exists_' . $name);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Extension of the Horde_Permission class for storing permission
+ * information in the SQL driver.
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Duck <duck@obala.net>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Permission_SqlObject extends Horde_Permission
+{
+ /**
+ * The string permission id.
+ *
+ * @var string
+ */
+ protected $_id;
+
+ /**
+ * Database handle for saving changes.
+ *
+ * @var DB
+ */
+ protected $_write_db;
+
+ /**
+ * Associates a DB object with this share.
+ *
+ * @param DB $write_db The DB object.
+ */
+ public function setSqlOb($write_db)
+ {
+ $this->_write_db = $write_db;
+ }
+
+ /**
+ * Get permission ID.
+ *
+ * @return TODO
+ */
+ public function getId()
+ {
+ return $this->_id;
+ }
+
+ /**
+ * Set permission id.
+ *
+ * @param string $id Permission ID.
+ */
+ public function setId($id)
+ {
+ $this->_id = $id;
+ }
+
+ /**
+ * Saves any changes to this object to the backend permanently. New
+ * objects are added instead.
+ *
+ * @throws Horde_Perms_Exception
+ */
+ public function save()
+ {
+ $name = $this->getName();
+ if (empty($name)) {
+ throw new Horde_Perms_Exception('Permission names must be non-empty');
+ }
+ $query = 'UPDATE horde_perms SET perm_data = ? WHERE perm_id = ?';
+ $params = array(serialize($this->data), $this->getId());
+ $result = $this->_write_db->query($query, $params);
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ }
+
+ $cache = Horde_Cache::singleton($GLOBALS['conf']['cache']['driver'], Horde::getDriverConfig('cache', $GLOBALS['conf']['cache']['driver']));
+ $cache->expire('perm_sql_' . $name);
+ $cache->expire('perm_sql_exists_' . $name);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Perms_Sql:: class provides a SQL driver for the Horde
+ * permissions system.
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Duck <duck@obala.net>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Sql extends Horde_Perms
+{
+ /**
+ * Boolean indicating whether or not we're connected to the SQL server.
+ *
+ * @var boolean
+ */
+ protected $_connected = false;
+
+ /**
+ * Handle for the current database connection.
+ *
+ * @var DB
+ */
+ protected $_db;
+
+ /**
+ * Handle for the current database connection, used for writing. Defaults
+ * to the same handle as $db if a separate write database is not required.
+ *
+ * @var DB
+ */
+ protected $_write_db;
+
+ /**
+ * Pointer to a Horde_Cache instance
+ *
+ * @var Horde_Cache
+ */
+ protected $_cache;
+
+ /**
+ * Cache of previously retrieved permissions.
+ *
+ * @var array
+ */
+ protected $_permsCache = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->_cache = Horde_Cache::singleton($GLOBALS['conf']['cache']['driver'], Horde::getDriverConfig('cache', $GLOBALS['conf']['cache']['driver']));
+ }
+
+ /**
+ * Returns a new permissions object.
+ *
+ * @param string $name The permission's name.
+ *
+ * @return Horde_Perms_Permission_SqlObject A new permissions object.
+ */
+ public function newPermission($name)
+ {
+ $type = 'matrix';
+ $params = null;
+
+ if ($pos = strpos($name, ':')) {
+ try {
+ $info = $this->getApplicationPermissions(substr($name, 0, $pos));
+ if (isset($info['type']) && isset($info['type'][$name])) {
+ $type = $info['type'][$name];
+ }
+
+ if (isset($info['params']) && isset($info['params'][$name])) {
+ $params = $info['params'][$name];
+ }
+ } catch (Horde_Perms_Exception $e) {}
+ }
+
+ return new Horde_Perms_Permission_SqlObject($name, $type, $params);
+ }
+
+ /**
+ * Returns an object corresponding to the named permission, with the
+ * users and other data retrieved appropriately.
+ *
+ * @param string $name The name of the permission to retrieve.
+ *
+ * @return Horde_Perms_Permission_SqlObject TODO
+ * @throw Horde_Perms_Exception
+ */
+ public function getPermission($name)
+ {
+ if (isset($this->_permsCache[$name])) {
+ return $this->_permsCache[$name];
+ }
+
+ $this->_connect();
+
+ $perm = $this->_cache->get('perm_sql' . $name, $GLOBALS['conf']['cache']['default_lifetime']);
+ if (empty($perm)) {
+ $query = 'SELECT perm_id, perm_data FROM horde_perms WHERE perm_name = ?';
+ $result = $this->_db->getRow($query, array($name), DB_FETCHMODE_ASSOC);
+
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ } elseif (empty($result)) {
+ throw new Horde_Perms_Exception('Does not exist');
+ }
+
+ $object = new Horde_Perms_Permission_SqlObject($name);
+ $object->setId($result['perm_id']);
+ $object->setData(unserialize($result['perm_data']));
+
+ $this->_cache->set('perm_sql' . $name, serialize($object));
+
+ $this->_permsCache[$name] = $object;
+ } else {
+ $this->_permsCache[$name] = unserialize($perm);
+ }
+
+ $this->_permsCache[$name]->setSQLOb($this->_write_db);
+
+ return $this->_permsCache[$name];
+ }
+
+ /**
+ * Returns a permission object corresponding to the given unique ID,
+ * with the users and other data retrieved appropriately.
+ *
+ * @param integer $id The unique ID of the permission to retrieve.
+ *
+ * @return Horde_Perms_Permission_SqlObject TODO
+ * @throws Horde_Perms_Exception
+ */
+ public function getPermissionById($id)
+ {
+ $this->_connect();
+
+ if ($id == Horde_Perms::ROOT || empty($id)) {
+ $object = $this->newPermission(Horde_Perms::ROOT);
+ } else {
+ $query = 'SELECT perm_name, perm_data FROM horde_perms WHERE perm_id = ?';
+ $result = $this->_db->getRow($query, array($id), DB_FETCHMODE_ASSOC);
+
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ } elseif (empty($result)) {
+ throw new Horde_Perms_Exception('Does not exist');
+ }
+
+ $object = new Horde_Perms_Permission_SqlObject($result['perm_name']);
+ $object->setId($id);
+ $object->setData(unserialize($result['perm_data']));
+ $object->setSQLOb($this->_write_db);
+ }
+
+ return $object;
+ }
+
+ /**
+ * Adds a permission to the permissions system. The permission must first
+ * be created with newPermission(), and have any initial users added to
+ * it, before this function is called.
+ *
+ * @param Horde_Perms_Permission_SqlObject $perm The perm object.
+ *
+ * @return TODO
+ * @throws Horde_Perms_Exception
+ */
+ public function addPermission($perm)
+ {
+ if (!($perm instanceof Horde_Perms_Permission_SqlObject)) {
+ throw new Horde_Perms_Exception('Permissions must be a Horde_Perms_Permission_SqlObject object.');
+ }
+
+ $name = $perm->getName();
+ if (empty($name)) {
+ throw new Horde_Perms_Exception('Permission name must be non-empty.');
+ }
+
+ $this->_cache->expire('perm_sql' . $name);
+ $this->_cache->expire('perm_sql_exists_' . $name);
+
+ $this->_connect();
+ $id = $this->_write_db->nextId('horde_perms');
+
+ // remove root from the name
+ if (substr($name, 0, 3) == (Horde_Perms::ROOT . ':')) {
+ $name = substr($name, 3);
+ }
+
+ // build parents
+ $parents = '';
+ if (($pos = strrpos($name, ':')) !== false) {
+ $parent_name = substr($name, 0, $pos);
+ $query = 'SELECT perm_id, perm_parents FROM horde_perms WHERE perm_name = ?';
+ $result = $this->_db->getRow($query, array($parent_name), DB_FETCHMODE_ASSOC);
+ if (!empty($result)) {
+ $parents = $result['perm_parents'] . ':' . $result['perm_id'];
+ }
+ }
+
+ $query = 'INSERT INTO horde_perms (perm_id, perm_name, perm_parents) VALUES (?, ?, ?)';
+ $perm->setId($id);
+
+ $result = $this->_write_db->query($query, array($id, $name, $parents));
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ }
+
+ $perm->setSQLOb($this->_write_db);
+ $perm->save();
+
+ return $id;
+ }
+
+ /**
+ * Removes a permission from the permissions system permanently.
+ *
+ * @param Horde_Perms_Permission_SqlObject $perm The permission to
+ * remove.
+ * @param boolean $force Force to remove ever
+ * child.
+ *
+ * @return TODO
+ * @throws Horde_Perms_Exception
+ */
+ public function removePermission($perm, $force = false)
+ {
+ if (!($perm instanceof Horde_Perms_Permissions_SqlObject)) {
+ throw new Horde_Perms_Exception('Permissions must be Horde_Perms_Permission_SqlObject objects.');
+ }
+
+ $name = $perm->getName();
+ $this->_cache->expire('perm_sql' . $name);
+ $this->_cache->expire('perm_sql_exists_' . $name);
+
+ $this->_connect();
+ $query = 'DELETE FROM horde_perms WHERE perm_name = ?';
+ $result = $this->_write_db->query($query, array($name));
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ } elseif ($force) {
+ return $result;
+ }
+
+ $query = 'DELETE FROM horde_perms WHERE perm_name LIKE ?';
+ return $this->_write_db->query($query, array($name . ':%'));
+ }
+
+ /**
+ * Returns the unique identifier of this permission.
+ *
+ * @param Horde_Perms_Permission_SqlObject $perm The permission object to
+ * get the ID of.
+ *
+ * @return integer The unique id.
+ */
+ public function getPermissionId($permission)
+ {
+ if ($permission->getName() == Horde_Perms::ROOT) {
+ return Horde_Perms::ROOT;
+ }
+
+ $this->_connect();
+ $query = 'SELECT perm_id FROM horde_perms WHERE perm_name = ?';
+ return $this->_db->getOne($query, array($permission->getName()));
+ }
+
+ /**
+ * Checks if a permission exists in the system.
+ *
+ * @param string $permission The permission to check.
+ *
+ * @return boolean True if the permission exists.
+ * @throws Horde_Perms_Exception
+ */
+ public function exists($permission)
+ {
+ $key = 'perm_sql_exists_' . $permission;
+ $exists = $this->_cache->get($key, $GLOBALS['conf']['cache']['default_lifetime']);
+ if ($exists === false) {
+ $this->_connect();
+ $query = 'SELECT COUNT(*) FROM horde_perms WHERE perm_name = ?';
+ $exists = $this->_db->getOne($query, array($permission));
+ if ($exists instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($exists);
+ }
+
+ $this->_cache->set($key, (string)$exists);
+ }
+
+ return (bool)$exists;
+ }
+
+ /**
+ * Returns a child's direct parent ID.
+ *
+ * @param mixed $child The object name for which to look up the parent's
+ * ID.
+ *
+ * @return integer The unique ID of the parent.
+ * @throws Horde_Perms_Exception
+ */
+ public function getParent($child)
+ {
+ $this->_connect();
+ $query = 'SELECT perm_parents FROM horde_perms WHERE perm_name = ?';
+ $parents = $this->_db->getOne($query, array($child));
+
+ if ($parents instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($parents);
+ }
+
+ if (empty($parents)) {
+ return Horde_Perms::ROOT;
+ }
+
+ $parents = explode(':', $parents);
+ return array_pop($parents);
+ }
+
+ /**
+ * Returns a list of parent permissions.
+ *
+ * @param string $child The name of the child to retrieve parents for.
+ *
+ * @return array A hash with all parents in a tree format.
+ * @throws Horde_Perms_Exception
+ */
+ public function getParents($child)
+ {
+ $this->_connect();
+ $query = 'SELECT perm_parents FROM horde_perms WHERE perm_name = ?';
+ $result = $this->_db->getOne($query, array($child));
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($result);
+ } elseif (empty($result)) {
+ throw new Horde_Perms_Exception('Does not exist');
+ }
+
+ return $this->_getParents($result);
+ }
+
+ /**
+ * TODO
+ */
+ protected function _getParents($parents)
+ {
+ if (empty($parents)) {
+ return array(Horde_Perms::ROOT => true);
+ }
+
+ $pname = $parents;
+ $parents = substr($parents, 0, strrpos($parents, ':'));
+
+ return array($pname => $this->_getParents($parents));
+ }
+
+ /**
+ * Returns all permissions of the system in a tree format.
+ *
+ * @return array A hash with all permissions in a tree format.
+ * @throws Horde_Perms_Exception
+ */
+ public function getTree()
+ {
+ $this->_connect();
+ $query = 'SELECT perm_id, perm_name FROM horde_perms ORDER BY perm_name ASC';
+ $tree = $this->_db->getAssoc($query);
+ if ($tree instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($tree);
+ }
+
+ $tree[Horde_Perms::ROOT] = Horde_Perms::ROOT;
+ return $tree;
+ }
+
+ /**
+ * Attempts to open a connection to the sql server.
+ *
+ * @throws Horde_Perms_Exception
+ */
+ protected function _connect()
+ {
+ if ($this->_connected) {
+ return;
+ }
+
+ $_params = $GLOBALS['conf']['sql'];
+ if (!isset($_params['database'])) {
+ $_params['database'] = '';
+ }
+ if (!isset($_params['username'])) {
+ $_params['username'] = '';
+ }
+ if (!isset($_params['hostspec'])) {
+ $_params['hostspec'] = '';
+ }
+
+ /* Connect to the sql server using the supplied parameters. */
+ $this->_write_db = DB::connect($_params,
+ array('persistent' => !empty($_params['persistent']),
+ 'ssl' => !empty($this->_params['ssl'])));
+ if ($this->_write_db instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($this->_write_db);
+ }
+
+ /* Set DB portability options. */
+ switch ($this->_write_db->phptype) {
+ case 'mssql':
+ $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ break;
+ }
+
+ /* Check if we need to set up the read DB connection seperately. */
+ if (!empty($_params['splitread'])) {
+ $params = array_merge($_params, $_params['read']);
+ $this->_db = DB::connect($params,
+ array('persistent' => !empty($params['persistent']),
+ 'ssl' => !empty($params['ssl'])));
+ if ($this->_db instanceof PEAR_Error) {
+ throw new Horde_Perms_Exception($this->_db);
+ }
+
+ /* Set DB portability options. */
+ switch ($this->_db->phptype) {
+ case 'mssql':
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ break;
+ }
+ } else {
+ /* Default to the same DB handle for the writer too. */
+ $this->_db = $this->_write_db;
+ }
+
+ $this->_connected = true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Perms_Ui:: class provides UI methods for the Horde permissions
+ * system.
+ *
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Horde_Perms
+ */
+class Horde_Perms_Ui
+{
+ /**
+ * The Horde_Perms object we're displaying UI stuff for.
+ *
+ * @var Horde_Perms
+ */
+ protected $_perms;
+
+ /**
+ * The Horde_Form object that will be used for displaying the edit form.
+ *
+ * @var Horde_Form
+ */
+ protected $_form = null;
+
+ /**
+ * The Horde_Variables object used in Horde_Form.
+ *
+ * @var Horde_Variables
+ */
+ protected $_vars = null;
+
+ /**
+ * The permission type.
+ *
+ * @var string
+ */
+ protected $_type = 'matrix';
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_Perms $perms The object to display UI stuff for.
+ */
+ public function __construct($perms)
+ {
+ $this->_perms = $perms;
+ }
+
+ /**
+ * Return a Horde_Tree representation of the permissions tree.
+ *
+ * @return string The html showing the permissions as a Horde_Tree.
+ * @throws Horde_Perms_Exception
+ */
+ public function renderTree($current = Horde_Perms::ROOT)
+ {
+ global $registry;
+
+ /* Get the perms tree. */
+ $nodes = $this->_perms->getTree();
+
+ $icondir = array('icondir' => $GLOBALS['registry']->getImageDir());
+ $perms_node = $icondir + array('icon' => 'perms.png');
+ $add = Horde::applicationUrl('admin/perms/addchild.php');
+ $add_img = Horde::img('add_perm.png', _("Add Permission"));
+ $edit = Horde::applicationUrl('admin/perms/edit.php');
+ $delete = Horde::applicationUrl('admin/perms/delete.php');
+ $edit_img = Horde::img('edit.png', _("Edit Permission"));
+ $delete_img = Horde::img('delete.png', _("Delete Permission"));
+ $blank_img = Horde::img('blank.gif', '', array('width' => 16, 'height' => 16));
+
+ /* Set up the tree. */
+ $tree = Horde_Tree::singleton('perms_ui', 'javascript');
+ $tree->setOption(array('alternate' => true, 'hideHeaders' => true));
+ $tree->setHeader(array(array('width' => '50%')));
+
+ foreach ($nodes as $perm_id => $node) {
+ $node_class = ($current == $perm_id)
+ ? array('class' => 'selected')
+ : array();
+ if ($perm_id == Horde_Perms::ROOT) {
+ $add_link = Horde::link(
+ Horde_Util::addParameter($add, 'perm_id', $perm_id),
+ _("Add New Permission"))
+ . $add_img . '</a>';
+ $base_node_params = $icondir +
+ array('icon' => 'administration.png');
+
+ $tree->addNode($perm_id, null, _("All Permissions"), 0, true,
+ $base_node_params + $node_class,
+ array($add_link));
+ } else {
+ $parent_id = $this->_perms->getParent($node);
+
+ $perms_extra = array();
+ $parents = explode(':', $node);
+
+ if (!in_array($parents[0], $GLOBALS['registry']->listApps())) {
+ // This backend has permissions for an application that is
+ // not installed. Perhaps the application has been removed
+ // or the backend is shared with other Horde installations.
+ // Skip this app and do not include it in the tree.
+ continue;
+ }
+
+ try {
+ $app_perms = $this->_perms->getApplicationPermissions($parents[0]);
+ } catch (Horde_Perms_Exception $e) {
+ $GLOBALS['notification']->push($e);
+ continue;
+ }
+
+ if (isset($app_perms['tree']) &&
+ is_array(Horde_Array::getElement($app_perms['tree'], $parents))) {
+ $add_link = Horde::link(
+ Horde_Util::addParameter($add, 'perm_id', $perm_id),
+ _("Add Child Permission"))
+ . $add_img . '</a>';
+ $perms_extra[] = $add_link;
+ } else {
+ $perms_extra[] = $blank_img;
+ }
+
+ $edit_link = Horde::link(
+ Horde_Util::addParameter($edit, 'perm_id', $perm_id),
+ _("Edit Permission"))
+ . $edit_img . '</a>';
+ $perms_extra[] = $edit_link;
+ $delete_link = Horde::link(
+ Horde_Util::addParameter($delete, 'perm_id', $perm_id),
+ _("Delete Permission"))
+ . $delete_img . '</a>';
+ $perms_extra[] = $delete_link;
+ $name = $this->_perms->getTitle($node);
+
+ $expanded = isset($nodes[$current]) &&
+ strpos($nodes[$current], $node) === 0 &&
+ $nodes[$current] != $node;
+ $tree->addNode($perm_id, $parent_id, $name,
+ substr_count($node, ':') + 1, $expanded,
+ $perms_node + $node_class, $perms_extra);
+ }
+ }
+
+ $tree->sort('label');
+
+ return $tree->renderTree();
+ }
+
+ /**
+ * Set an existing form object to use for the edit form.
+ *
+ * @param Horde_Form $form An existing Horde_Form object to use.
+ */
+ public function setForm(&$form)
+ {
+ $this->_form = $form;
+ }
+
+ /**
+ * Set an existing vars object to use for the edit form.
+ *
+ * @param Horde_Variables $vars An existing Horde_Variables object to
+ * use.
+ */
+ public function setVars($vars)
+ {
+ $this->_vars = $vars;
+ }
+
+ /**
+ * Create a form to add a permission.
+ *
+ * @param Horde_Perms_Permission $permission Permission
+ * @param string $force_choice If the permission to be
+ * added can be one of many,
+ * setting this will force the
+ * choice to one particular.
+ */
+ public function setupAddForm($permission, $force_choice = null)
+ {
+ /* Initialise form if required. */
+ $this->_formInit();
+
+ $this->_form->setTitle(sprintf(_("Add a child permission to \"%s\""), $this->_perms->getTitle($permission->getName())));
+ $this->_form->setButtons(_("Add"));
+ $this->_vars->set('perm_id', $this->_perms->getPermissionId($permission));
+ $this->_form->addHidden('', 'perm_id', 'text', false);
+
+ /* Set up the actual child adding field. */
+ $child_perms = $this->_perms->getAvailable($permission->getName());
+ if ($child_perms === false) {
+ /* False, so no childs are to be added below this level. */
+ $this->_form->addVariable(_("Permission"), 'child', 'invalid', true, false, null, array(_("No children can be added to this permission.")));
+ } elseif (is_array($child_perms)) {
+ if (!empty($force_choice)) {
+ /* Choice array available, but choice being forced. */
+ $this->_vars->set('child', $force_choice);
+ $this->_form->addVariable(_("Permissions"), 'child', 'enum', true, true, null, array($child_perms));
+ } else {
+ /* Choice array available, so set up enum field. */
+ $this->_form->addVariable(_("Permissions"), 'child', 'enum', true, false, null, array($child_perms));
+ }
+ }
+ }
+
+ /**
+ * Function to validate any add form input.
+ *
+ * @param TODO $info TODO
+ *
+ * @return mixed Either false if the form does not validate correctly or
+ * an array with all the form values.
+ */
+ public function validateAddForm($info)
+ {
+ if (!$this->_form->validate($this->_vars)) {
+ return false;
+ }
+
+ $this->_form->getInfo($this->_vars, $info);
+ return true;
+ }
+
+ /**
+ * Create a permission editing form.
+ *
+ * @param Horde_Perms_Permission $permission TODO
+ */
+ public function setupEditForm($permission)
+ {
+ global $registry;
+
+ /* Initialise form if required. */
+ $this->_formInit();
+
+ $this->_form->setButtons(_("Update"), true);
+ $perm_id = $this->_perms->getPermissionId($permission);
+ $this->_form->addHidden('', 'perm_id', 'text', false);
+
+ /* Get permission configuration. */
+ $this->_type = $permission->get('type');
+ $params = $permission->get('params');
+
+ /* Default permissions. */
+ $perm_val = $permission->getDefaultPermissions();
+ $this->_form->setSection('default', _("All Authenticated Users"), Horde::img('perms.png', '', '', $registry->getImageDir('horde')), false);
+
+ /* We MUST use 'deflt' for the variable name because 'default' is a
+ * reserved word in JavaScript. */
+ if ($this->_type == 'matrix') {
+ /* Set up the columns for the permissions matrix. */
+ $cols = Horde_Perms::getPermsArray();
+
+ /* Define a single matrix row for default perms. */
+ $matrix = array(Horde_Perms::integerToArray($perm_val));
+ $this->_form->addVariable('', 'deflt', 'matrix', false, false, null, array($cols, array(0 => ''), $matrix));
+ } else {
+ $var = $this->_form->addVariable('', 'deflt', $this->_type, false, false, null, $params);
+ $var->setDefault($perm_val);
+ }
+
+ /* Guest permissions. */
+ $perm_val = $permission->getGuestPermissions();
+ $this->_form->setSection('guest', _("Guest Permissions"), '', false);
+
+ if ($this->_type == 'matrix') {
+ /* Define a single matrix row for guest perms. */
+ $matrix = array(Horde_Perms::integerToArray($perm_val));
+ $this->_form->addVariable('', 'guest', 'matrix', false, false, null, array($cols, array(0 => ''), $matrix));
+ } else {
+ $var = $this->_form->addVariable('', 'guest', $this->_type, false, false, null, $params);
+ $var->setDefault($perm_val);
+ }
+
+ /* Object creator permissions. */
+ $perm_val = $permission->getCreatorPermissions();
+ $this->_form->setSection('creator', _("Creator Permissions"), Horde::img('user.png', '', '', $registry->getImageDir('horde')), false);
+
+ if ($this->_type == 'matrix') {
+ /* Define a single matrix row for creator perms. */
+ $matrix = array(Horde_Perms::integerToArray($perm_val));
+ $this->_form->addVariable('', 'creator', 'matrix', false, false, null, array($cols, array(0 => ''), $matrix));
+ } else {
+ $var = $this->_form->addVariable('', 'creator', $this->_type, false, false, null, $params);
+ $var->setDefault($perm_val);
+ }
+
+ /* Users permissions. */
+ $perm_val = $permission->getUserPermissions();
+ $this->_form->setSection('users', _("Individual Users"), Horde::img('user.png', '', '', $registry->getImageDir('horde')), false);
+ $auth = Horde_Auth::singleton($GLOBALS['conf']['auth']['driver']);
+ if ($auth->hasCapability('list')) {
+ /* The auth driver has list capabilities so set up an array which
+ * the matrix field type will recognise to set up an enum box for
+ * adding new users to the permissions matrix. */
+ $new_users = array();
+
+ try {
+ $user_list = $auth->listUsers();
+ sort($user_list);
+ foreach ($user_list as $user) {
+ if (!isset($perm_val[$user])) {
+ $new_users[$user] = $user;
+ }
+ }
+ } catch (Horde_Auth_Exception $e) {
+ $new_users = true;
+ }
+ } else {
+ /* No list capabilities, setting to true so that the matrix field
+ * type will offer a text input box for adding new users. */
+ $new_users = true;
+ }
+
+ if ($this->_type == 'matrix') {
+ /* Set up the matrix array, breaking up each permission integer
+ * into an array. The keys of this array will be the row
+ * headers. */
+ $rows = array();
+ $matrix = array();
+ foreach ($perm_val as $u_id => $u_perms) {
+ $rows[$u_id] = $u_id;
+ $matrix[$u_id] = Horde_Perms::integerToArray($u_perms);
+ }
+ $this->_form->addVariable('', 'u', 'matrix', false, false, null, array($cols, $rows, $matrix, $new_users));
+ } else {
+ if ($new_users) {
+ if (is_array($new_users)) {
+ $u_n = Horde_Util::getFormData('u_n');
+ $u_n = empty($u_n['u']) ? null : $u_n['u'];
+ $user_html = '<select name="u_n[u]"><option value="">' . _("-- select --") . '</option>';
+ foreach ($new_users as $new_user) {
+ $user_html .= '<option value="' . $new_user . '"';
+ $user_html .= $u_n == $new_user ? ' selected="selected"' : '';
+ $user_html .= '>' . htmlspecialchars($new_user) . '</option>';
+ }
+ $user_html .= '</select>';
+ } else {
+ $user_html = '<input type="text" name="u_n[u]" />';
+ }
+ $this->_form->addVariable($user_html, 'u_n[v]', $this->_type, false, false, null, $params);
+ }
+ foreach ($perm_val as $u_id => $u_perms) {
+ $var = $this->_form->addVariable($u_id, 'u_v[' . $u_id . ']', $this->_type, false, false, null, $params);
+ $var->setDefault($u_perms);
+ }
+ }
+
+ /* Groups permissions. */
+ $perm_val = $permission->getGroupPermissions();
+ $this->_form->setSection('groups', _("Groups"), Horde::img('group.png', '', '', $registry->getImageDir('horde')), false);
+ require_once 'Horde/Group.php';
+ $groups = Group::singleton();
+ $group_list = $groups->listGroups();
+ if ($group_list instanceof PEAR_Error) {
+ $GLOBALS['notification']->push($group_list);
+ $group_list = array();
+ }
+
+ if (!empty($group_list)) {
+ /* There is an available list of groups so set up an array which
+ * the matrix field type will recognise to set up an enum box for
+ * adding new groups to the permissions matrix. */
+ $new_groups = array();
+ foreach ($group_list as $groupId => $group) {
+ if (!isset($perm_val[$groupId])) {
+ $new_groups[$groupId] = $group;
+ }
+ }
+ } else {
+ /* Do not offer a text box to add new groups. */
+ $new_groups = false;
+ }
+
+ if ($this->_type == 'matrix') {
+ /* Set up the matrix array, break up each permission integer into
+ * an array. The keys of this array will be the row headers. */
+ $rows = array();
+ $matrix = array();
+ foreach ($perm_val as $g_id => $g_perms) {
+ $rows[$g_id] = isset($group_list[$g_id]) ? $group_list[$g_id] : $g_id;
+ $matrix[$g_id] = Horde_Perms::integerToArray($g_perms);
+ }
+ $this->_form->addVariable('', 'g', 'matrix', false, false, null, array($cols, $rows, $matrix, $new_groups));
+ } else {
+ if ($new_groups) {
+ if (is_array($new_groups)) {
+ $g_n = Horde_Util::getFormData('g_n');
+ $g_n = empty($g_n['g']) ? null : $g_n['g'];
+ $group_html = '<select name="g_n[g]"><option value="">' . _("-- select --") . '</option>';
+ foreach ($new_groups as $groupId => $group) {
+ $group_html .= '<option value="' . $groupId . '"';
+ $group_html .= $g_n == $groupId ? ' selected="selected"' : '';
+ $group_html .= '>' . htmlspecialchars($group) . '</option>';
+ }
+ $group_html .= '</select>';
+ } else {
+ $group_html = '<input type="text" name="g_n[g]" />';
+ }
+ $this->_form->addVariable($group_html, 'g_n[v]', $this->_type, false, false, null, $params);
+ }
+ foreach ($perm_val as $g_id => $g_perms) {
+ $var = &$this->_form->addVariable(isset($group_list[$g_id]) ? $group_list[$g_id] : $g_id, 'g_v[' . $g_id . ']', $this->_type, false, false, null, $params);
+ $var->setDefault($g_perms);
+ }
+ }
+
+ /* Set form title. */
+ $this->_form->setTitle(sprintf(_("Edit permissions for \"%s\""), $this->_perms->getTitle($permission->getName())));
+ }
+
+ /**
+ * Function to validate any edit form input.
+ *
+ * @return mixed Either false if the form does not validate correctly or
+ * an array with all the form values.
+ */
+ public function validateEditForm(&$info)
+ {
+ if (!$this->_form->validate($this->_vars)) {
+ return false;
+ }
+
+ $this->_form->getInfo($this->_vars, $info);
+
+ if ($this->_type == 'matrix') {
+ /* Collapse the array for default/guest/creator. */
+ $info['deflt'] = isset($info['deflt'][0])
+ ? $info['deflt'][0]
+ : null;
+ $info['guest'] = isset($info['guest'][0])
+ ? $info['guest'][0]
+ : null;
+ $info['creator'] = isset($info['creator'][0])
+ ? $info['creator'][0]
+ : null;
+ } else {
+ $u_n = $this->_vars->get('u_n');
+ $info['u'] = array();
+ if (!empty($u_n['u'])) {
+ $info['u'][$u_n['u']] = $info['u_n']['v'];
+ }
+ unset($info['u_n']);
+ if (isset($info['u_v'])) {
+ $info['u'] += $info['u_v'];
+ unset($info['u_v']);
+ }
+ $g_n = $this->_vars->get('g_n');
+ $info['g'] = array();
+ if (!empty($g_n['g'])) {
+ $info['g'][$g_n['g']] = $info['g_n']['v'];
+ }
+ unset($info['g_n']);
+ if (isset($info['g_v'])) {
+ $info['g'] += $info['g_v'];
+ unset($info['g_v']);
+ }
+ }
+ $info['default'] = $info['deflt'];
+ unset($info['deflt']);
+
+ return true;
+ }
+
+ /**
+ * Create a permission deleting form.
+ *
+ * @param Horde_Perms_Permission $permission A permissions object.
+ */
+ public function setupDeleteForm($permission)
+ {
+ /* Initialise form if required. */
+ $this->_formInit();
+
+ $this->_form->setTitle(sprintf(_("Delete permissions for \"%s\""), $this->_perms->getTitle($permission->getName())));
+ $this->_form->setButtons(array(_("Delete"), _("Do not delete")));
+ $this->_form->addHidden('', 'perm_id', 'text', false);
+ $this->_form->addVariable(sprintf(_("Delete permissions for \"%s\" and any sub-permissions?"), $this->_perms->getTitle($permission->getName())), 'prompt', 'description', false);
+ }
+
+ /**
+ * Function to validate any delete form input.
+ *
+ * @param TODO $info TODO
+ *
+ * @return mixed If the delete button confirmation has been pressed return
+ * true, if any other submit button has been pressed return
+ * false. If form did not validate return null.
+ */
+ public function validateDeleteForm($info)
+ {
+ $form_submit = $this->_vars->get('submitbutton');
+
+ if ($form_submit == _("Delete")) {
+ if ($this->_form->validate($this->_vars)) {
+ $this->_form->getInfo($this->_vars, $info);
+ return true;
+ }
+ } elseif (!empty($form_submit)) {
+ return false;
+ }
+
+ return null;
+ }
+
+ /**
+ * Renders the edit form.
+ */
+ public function renderForm($form_script = 'edit.php')
+ {
+ $renderer = new Horde_Form_Renderer();
+ $this->_form->renderActive($renderer, $this->_vars, $form_script, 'post');
+ }
+
+ /**
+ * Creates any form objects if they have not been initialised yet.
+ */
+ protected function _formInit()
+ {
+ if (is_null($this->_vars)) {
+ /* No existing vars set, get them now. */
+ $this->_vars = Horde_Variables::getDefaultVariables();
+ }
+
+ if (!($this->_form instanceof Horde_Form)) {
+ /* No existing valid form object set so set up a new one. */
+ $this->_form = new Horde_Form($this->_vars);
+ }
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Perms</name>
+ <channel>pear.horde.org</channel>
+ <extends>Horde_Perms</extends>
+ <summary>Horde Permissions System</summary>
+ <description>The Perms package provides an interface to the Horde permissions system.</description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Jan Schneider</name>
+ <user>jan</user>
+ <email>jan@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2009-11-20</date>
+ <version>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Initial Horde 4 package.
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Perms">
+ <dir name="Permission">
+ <file name="DataTreeObject.php" role="php" />
+ <file name="SqlObject.php" role="php" />
+ </dir> <!-- /lib/Horde/Perms/Permission -->
+ <file name="Datatree.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Permission.php" role="php" />
+ <file name="Sql.php" role="php" />
+ <file name="Ui.php" role="php" />
+ </dir> <!-- /lib/Horde/Perms -->
+ <file name="Perms.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ <package>
+ <name>Group</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Util</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <extension>
+ <name>gettext</name>
+ </extension>
+ </required>
+ <optional>
+ <package>
+ <name>Horde_DataTree</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Horde_Tree</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </optional>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Perms/Datatree.php" as="Horde/Perms/Datatree.php" />
+ <install name="lib/Horde/Perms/Exception.php" as="Horde/Perms/Exception.php" />
+ <install name="lib/Horde/Perms/Permission.php" as="Horde/Perms/Permission.php" />
+ <install name="lib/Horde/Perms/Permission/DataTreeObject.php" as="Horde/Perms/Permission/DataTreeObject.php" />
+ <install name="lib/Horde/Perms/Permission/SqlObject.php" as="Horde/Perms/Permission/SqlObject.php" />
+ <install name="lib/Horde/Perms/Sql.php" as="Horde/Perms/Sql.php" />
+ <install name="lib/Horde/Perms/Ui.php" as="Horde/Perms/Ui.php" />
+ <install name="lib/Horde/Perms.php" as="Horde/Perms.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <date>2008-08-20</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Cache permissions with Horde_Cache (duck@obala.net).
+ * Fixed special permissions with more than one user or group (Bug #2058).
+ * Added a getParent() call instead of accessing the _datatree member directly. (duck@obala.net, Request #6150).
+ * Added beta SQL Permissions driver (duck@obala.net, Request #6150).
+ * Automatically expand the node of the currently open permission.
+ * Only show Add Permission icons if there are sub-permissions to add.
+ * Make sure Horde_Array is available.
+ * Handle and display errors if they occur in the Perms backend.
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.2</release>
+ <api>0.0.2</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2006-05-08</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Converted to package.xml 2.0 for pear.horde.org
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2003-07-05</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Initial release as a PEAR package
+ </notes>
+ </release>
+ </changelog>
+</package>
$list[] = array('path' => $path,
'props' => $this->_getProps($options['props'], $root));
- $apps = $registry->listApps(null, false, PERMS_READ);
+ $apps = $registry->listApps(null, false, Horde_Perms::READ);
if (is_a($apps, 'PEAR_Error')) {
Horde::logMessage($apps, __FILE__, __LINE__, PEAR_LOG_ERR);
return $apps;