Skip to content

Commit

Permalink
Bug: 14577 Fix removing virtual address books with removeUserData().
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mrubinsk committed Feb 25, 2017
1 parent 5c5a1a5 commit 67f23e3
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 22 deletions.
10 changes: 8 additions & 2 deletions turba/lib/Application.php
Expand Up @@ -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;
}
Expand Down
31 changes: 28 additions & 3 deletions turba/lib/Driver/Vbook.php
Expand Up @@ -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())
{
Expand All @@ -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.
Expand Down
29 changes: 21 additions & 8 deletions turba/lib/Factory/Driver.php
Expand Up @@ -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));
Expand All @@ -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])) {
Expand Down Expand Up @@ -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. */
Expand Down
31 changes: 22 additions & 9 deletions turba/lib/Turba.php
Expand Up @@ -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
Expand All @@ -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;

Expand Down

0 comments on commit 67f23e3

Please sign in to comment.