Skip to content

Commit d78b213

Browse files
committed
adds ldap user:reset command
- allows to delete data of existing LDAP users, which otherwise is safe guarded - ensures that the user is not being deleted on LDAP through a plugin Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
1 parent f6cbda9 commit d78b213

File tree

5 files changed

+139
-4
lines changed

5 files changed

+139
-4
lines changed

apps/user_ldap/appinfo/register_command.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
use OCA\User_LDAP\User_Proxy;
3131
use OCA\User_LDAP\Mapping\UserMapping;
3232
use OCA\User_LDAP\User\DeletedUsersIndex;
33+
use OCA\User_LDAP\UserPluginManager;
34+
use OCP\IUserManager;
3335

3436
$dbConnection = \OC::$server->getDatabaseConnection();
3537
$userMapping = new UserMapping($dbConnection);
@@ -41,7 +43,7 @@
4143
$ocConfig,
4244
\OC::$server->getNotificationManager(),
4345
\OC::$server->getUserSession(),
44-
\OC::$server->query(\OCA\User_LDAP\UserPluginManager::class)
46+
\OC::$server->query(UserPluginManager::class)
4547
);
4648
$deletedUsersIndex = new DeletedUsersIndex(
4749
$ocConfig, $dbConnection, $userMapping
@@ -52,6 +54,11 @@
5254
$application->add(new OCA\User_LDAP\Command\TestConfig());
5355
$application->add(new OCA\User_LDAP\Command\CreateEmptyConfig($helper));
5456
$application->add(new OCA\User_LDAP\Command\DeleteConfig($helper));
57+
$application->add(new OCA\User_LDAP\Command\ResetUser(
58+
$deletedUsersIndex,
59+
\OC::$server->get(IUserManager::class),
60+
\OC::$server->get(UserPluginManager::class)
61+
));
5562
$application->add(new OCA\User_LDAP\Command\Search($ocConfig));
5663
$application->add(new OCA\User_LDAP\Command\ShowRemnants(
5764
$deletedUsersIndex, \OC::$server->getDateTimeFormatter())

apps/user_ldap/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
'OCA\\User_LDAP\\Command\\CheckUser' => $baseDir . '/../lib/Command/CheckUser.php',
1414
'OCA\\User_LDAP\\Command\\CreateEmptyConfig' => $baseDir . '/../lib/Command/CreateEmptyConfig.php',
1515
'OCA\\User_LDAP\\Command\\DeleteConfig' => $baseDir . '/../lib/Command/DeleteConfig.php',
16+
'OCA\\User_LDAP\\Command\\ResetUser' => $baseDir . '/../lib/Command/ResetUser.php',
1617
'OCA\\User_LDAP\\Command\\Search' => $baseDir . '/../lib/Command/Search.php',
1718
'OCA\\User_LDAP\\Command\\SetConfig' => $baseDir . '/../lib/Command/SetConfig.php',
1819
'OCA\\User_LDAP\\Command\\ShowConfig' => $baseDir . '/../lib/Command/ShowConfig.php',

apps/user_ldap/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ComposerStaticInitUser_LDAP
2828
'OCA\\User_LDAP\\Command\\CheckUser' => __DIR__ . '/..' . '/../lib/Command/CheckUser.php',
2929
'OCA\\User_LDAP\\Command\\CreateEmptyConfig' => __DIR__ . '/..' . '/../lib/Command/CreateEmptyConfig.php',
3030
'OCA\\User_LDAP\\Command\\DeleteConfig' => __DIR__ . '/..' . '/../lib/Command/DeleteConfig.php',
31+
'OCA\\User_LDAP\\Command\\ResetUser' => __DIR__ . '/..' . '/../lib/Command/ResetUser.php',
3132
'OCA\\User_LDAP\\Command\\Search' => __DIR__ . '/..' . '/../lib/Command/Search.php',
3233
'OCA\\User_LDAP\\Command\\SetConfig' => __DIR__ . '/..' . '/../lib/Command/SetConfig.php',
3334
'OCA\\User_LDAP\\Command\\ShowConfig' => __DIR__ . '/..' . '/../lib/Command/ShowConfig.php',
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
4+
*
5+
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
namespace OCA\User_LDAP\Command;
25+
26+
use OCA\User_LDAP\User\DeletedUsersIndex;
27+
use OCA\User_LDAP\User_Proxy;
28+
use OCA\User_LDAP\UserPluginManager;
29+
use OCP\IUser;
30+
use OCP\IUserManager;
31+
use Symfony\Component\Console\Command\Command;
32+
use Symfony\Component\Console\Helper\QuestionHelper;
33+
use Symfony\Component\Console\Input\InputArgument;
34+
use Symfony\Component\Console\Input\InputInterface;
35+
use Symfony\Component\Console\Input\InputOption;
36+
use Symfony\Component\Console\Output\OutputInterface;
37+
use Symfony\Component\Console\Question\Question;
38+
39+
class ResetUser extends Command {
40+
/** @var DeletedUsersIndex */
41+
protected $dui;
42+
/** @var IUserManager */
43+
private $userManager;
44+
/** @var UserPluginManager */
45+
private $pluginManager;
46+
47+
public function __construct(
48+
DeletedUsersIndex $dui,
49+
IUserManager $userManager,
50+
UserPluginManager $pluginManager
51+
) {
52+
$this->dui = $dui;
53+
$this->userManager = $userManager;
54+
$this->pluginManager = $pluginManager;
55+
parent::__construct();
56+
}
57+
58+
protected function configure() {
59+
$this
60+
->setName('ldap:reset-user')
61+
->setDescription('deletes an LDAP user independent of the user state')
62+
->addArgument(
63+
'uid',
64+
InputArgument::REQUIRED,
65+
'the user id as used in Nextcloud'
66+
)
67+
->addOption(
68+
'yes',
69+
'y',
70+
InputOption::VALUE_NONE,
71+
'do not ask for confirmation'
72+
);
73+
}
74+
75+
protected function execute(InputInterface $input, OutputInterface $output): int {
76+
try {
77+
$uid = $input->getArgument('uid');
78+
$user = $this->userManager->get($uid);
79+
if (!$user instanceof IUser) {
80+
throw new \Exception('User not found');
81+
}
82+
$backend = $user->getBackend();
83+
if (!$backend instanceof User_Proxy) {
84+
throw new \Exception('The given user is not a recognized LDAP user.');
85+
}
86+
if ($input->getOption('yes') === false) {
87+
/** @var QuestionHelper $helper */
88+
$helper = $this->getHelper('question');
89+
$q = new Question('Delete all local data of this user (y|N)? ');
90+
$input->setOption('yes', $helper->ask($input, $output, $q) === 'y');
91+
}
92+
if ($input->getOption('yes') !== true) {
93+
throw new \Exception('Reset cancelled by operator');
94+
}
95+
96+
$this->dui->markUser($uid);
97+
$pluginManagerSuppressed = $this->pluginManager->setSuppressDeletion(true);
98+
if ($user->delete()) {
99+
$this->pluginManager->setSuppressDeletion($pluginManagerSuppressed);
100+
return 0;
101+
}
102+
} catch (\Throwable $e) {
103+
if (isset($pluginManagerSuppressed)) {
104+
$this->pluginManager->setSuppressDeletion($pluginManagerSuppressed);
105+
}
106+
$output->writeln('<error>' . $e->getMessage() . '</error>');
107+
return 1;
108+
}
109+
$output->writeln('<error>Error while resetting user</error>');
110+
return 2;
111+
}
112+
}

apps/user_ldap/lib/UserPluginManager.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
use OC\User\Backend;
2929

3030
class UserPluginManager {
31-
public $test = false;
32-
3331
private $respondToActions = 0;
3432

3533
private $which = [
@@ -43,6 +41,9 @@ class UserPluginManager {
4341
'deleteUser' => null
4442
];
4543

44+
/** @var bool */
45+
private $suppressDeletion = false;
46+
4647
/**
4748
* @return int All implemented actions, except for 'deleteUser'
4849
*/
@@ -192,7 +193,7 @@ public function countUsers() {
192193
* @return bool
193194
*/
194195
public function canDeleteUser() {
195-
return $this->which['deleteUser'] !== null;
196+
return !$this->suppressDeletion && $this->which['deleteUser'] !== null;
196197
}
197198

198199
/**
@@ -203,8 +204,21 @@ public function canDeleteUser() {
203204
public function deleteUser($uid) {
204205
$plugin = $this->which['deleteUser'];
205206
if ($plugin) {
207+
if ($this->suppressDeletion) {
208+
return false;
209+
}
206210
return $plugin->deleteUser($uid);
207211
}
208212
throw new \Exception('No plugin implements deleteUser in this LDAP Backend.');
209213
}
214+
215+
/**
216+
* @param bool $value
217+
* @return bool – the value before the change
218+
*/
219+
public function setSuppressDeletion(bool $value): bool {
220+
$old = $this->suppressDeletion;
221+
$this->suppressDeletion = $value;
222+
return $old;
223+
}
210224
}

0 commit comments

Comments
 (0)