From 67f23e355a8d2133a5a0ba9fd05a8e629c8074d0 Mon Sep 17 00:00:00 2001 From: Michael J Rubinsky Date: Fri, 24 Feb 2017 23:43:38 -0500 Subject: [PATCH] Bug: 14577 Fix removing virtual address books with removeUserData(). We need to workaround the fact that the cfgSources array is dynamically built for the currently logged in user, but when removeUserData is called, we are logged in as the admin user, not the user we are removing. In this case, built a separate cfgSource structure out of the shares we know are owned by the user being removed. --- turba/lib/Application.php | 10 ++++++++-- turba/lib/Driver/Vbook.php | 31 ++++++++++++++++++++++++++++--- turba/lib/Factory/Driver.php | 29 +++++++++++++++++++++-------- turba/lib/Turba.php | 31 ++++++++++++++++++++++--------- 4 files changed, 79 insertions(+), 22 deletions(-) diff --git a/turba/lib/Application.php b/turba/lib/Application.php index 633386fa72a..a5c13e2b896 100644 --- a/turba/lib/Application.php +++ b/turba/lib/Application.php @@ -388,12 +388,18 @@ public function removeUserData($user) ); // Look for the deleted user's shares and remove them + $sources = Turba::getConfigFromShares( + $cfgSources, + true, + array('shares' => $shares, 'auth_user' => $user) + ); + foreach ($shares as $share) { - $config = Turba::getSourceFromShare($share); + $config = $sources[$share->getName()]; try { $driver = $GLOBALS['injector'] ->getInstance('Turba_Factory_Driver') - ->create($config, $share->getName()); + ->create($config, $share->getName(), $sources); } catch (Turba_Exception $e) { continue; } diff --git a/turba/lib/Driver/Vbook.php b/turba/lib/Driver/Vbook.php index 3b090116b3e..b9b6272de95 100644 --- a/turba/lib/Driver/Vbook.php +++ b/turba/lib/Driver/Vbook.php @@ -36,9 +36,16 @@ class Turba_Driver_Vbook extends Turba_Driver protected $_driver; /** - * - * @see Turba_Driver::__construct - * @throws Turba_Exception + * Constructs a new Turba_Driver object. + * + * @param string $name Source name + * @param array $params Additional configuration parameters: + * - share: Horde_Share object representing this vbook. + * - source: The configuration array of the parent source or the + * source name of parent source in the global cfgSources + * array. + * - source_name: If providing the configuration array in 'source', + * this is the source name to use for the parent source. */ public function __construct($name = '', array $params = array()) { @@ -60,6 +67,24 @@ public function __construct($name = '', array $params = array()) : 'basic'; } + /** + * Remove all data for a specific user. + * + * @param string $user The user to remove all data for. + */ + public function removeUserData($user) + { + // Make sure we are being called by an admin. + if (!$GLOBALS['registry']->isAdmin()) { + throw new Horde_Exception_PermissionDenied(_("Permission denied")); + } + + $GLOBALS['injector'] + ->getInstance('Turba_Shares') + ->removeShare($this->_share); + unset($this->_share); + } + /** * Return the owner to use when searching or creating contacts in * this address book. diff --git a/turba/lib/Factory/Driver.php b/turba/lib/Factory/Driver.php index 6a82d2368ef..028b5ff02c6 100644 --- a/turba/lib/Factory/Driver.php +++ b/turba/lib/Factory/Driver.php @@ -37,17 +37,25 @@ class Turba_Factory_Driver extends Horde_Core_Factory_Base /** * Return the Turba_Driver:: instance. * - * @param mixed $name Either a string containing the internal name of - * this source, or a config array describing the - * source. - * @param string $name2 The internal name of this source if $name is an - * array. + * @param mixed $name Either a string containing the internal name of + * this source, or a config array describing the + * source. + * @param string $name2 The internal name of this source if $name is an + * array. + * @param array $cfgSources Override the global cfgSources configuration + * with this array. Used when an admin needs + * access to another user's sources like e.g., + * when calling removeUserData(). * * @return Turba_Driver The singleton instance. * @throws Turba_Exception */ - public function create($name, $name2 = '') + public function create($name, $name2 = '', $cfgSources = array()) { + if (empty($cfgSources)) { + $cfgSources = $GLOBALS['cfgSources']; + } + if (is_array($name)) { ksort($name); $key = md5(serialize($name)); @@ -56,10 +64,10 @@ public function create($name, $name2 = '') } else { $key = $name; $srcName = $name; - if (empty($GLOBALS['cfgSources'][$name])) { + if (empty($cfgSources[$name])) { throw new Turba_Exception(sprintf(_("The address book \"%s\" does not exist."), $name)); } - $srcConfig = $GLOBALS['cfgSources'][$name]; + $srcConfig = $cfgSources[$name]; } if (!isset($this->_instances[$key])) { @@ -92,6 +100,11 @@ public function create($name, $name2 = '') case 'Turba_Driver_Kolab': $srcConfig['params']['storage'] = $this->_injector->getInstance('Horde_Kolab_Storage'); break; + + case 'Turba_Driver_Vbook': + // $srcConfig['params']['source_name'] = $srcConfig['params']['source']; + $srcConfig['params']['source'] = $cfgSources[$srcConfig['params']['source']]; + break; } /* Make sure charset exists. */ diff --git a/turba/lib/Turba.php b/turba/lib/Turba.php index 8f3bb95818a..92f0b3d78cb 100644 --- a/turba/lib/Turba.php +++ b/turba/lib/Turba.php @@ -489,20 +489,28 @@ public static function permissionsFilter(array $in, * * @param array $sources The default $cfgSources array. * @param boolean $owner Only return shares that the current user owns? + * @param array $options An array of options: + * - shares: Use this list of provided shares. Default is to get the + * list from the share system using the current user. + * - auth_user: Use this as the authenticated user name. * * @return array The $cfgSources array. */ - public static function getConfigFromShares(array $sources, $owner = false) + public static function getConfigFromShares(array $sources, $owner = false, $options = array()) { global $notification, $registry, $conf, $injector, $prefs; - try { - $shares = self::listShares($owner); - } catch (Horde_Share_Exception $e) { - // Notify the user if we failed, but still return the $cfgSource - // array. - $notification->push($e, 'horde.error'); - return $sources; + if (empty($options['shares'])) { + try { + $shares = self::listShares($owner); + } catch (Horde_Share_Exception $e) { + // Notify the user if we failed, but still return the $cfgSource + // array. + $notification->push($e, 'horde.error'); + return $sources; + } + } else { + $shares = $options['shares']; } /* See if any of our sources are configured to handle all otherwise @@ -515,7 +523,12 @@ public static function getConfigFromShares(array $sources, $owner = false) } } - $auth_user = $registry->getAuth(); + if (empty($options['auth_user'])) { + $auth_user = $registry->getAuth(); + } else { + $auth_user = $options['auth_user']; + } + $sortedSources = $vbooks = array(); $personal = false;