aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/lib/Command/CheckGroup.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_ldap/lib/Command/CheckGroup.php')
-rw-r--r--apps/user_ldap/lib/Command/CheckGroup.php162
1 files changed, 162 insertions, 0 deletions
diff --git a/apps/user_ldap/lib/Command/CheckGroup.php b/apps/user_ldap/lib/Command/CheckGroup.php
new file mode 100644
index 00000000000..9c7ccb9d3b3
--- /dev/null
+++ b/apps/user_ldap/lib/Command/CheckGroup.php
@@ -0,0 +1,162 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\User_LDAP\Command;
+
+use OCA\User_LDAP\Group_Proxy;
+use OCA\User_LDAP\Helper;
+use OCA\User_LDAP\Mapping\GroupMapping;
+use OCA\User_LDAP\Service\UpdateGroupsService;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Group\Events\GroupCreatedEvent;
+use OCP\Group\Events\UserAddedEvent;
+use OCP\Group\Events\UserRemovedEvent;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class CheckGroup extends Command {
+ public function __construct(
+ private UpdateGroupsService $service,
+ protected Group_Proxy $backend,
+ protected Helper $helper,
+ protected GroupMapping $mapping,
+ protected IEventDispatcher $dispatcher,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('ldap:check-group')
+ ->setDescription('checks whether a group exists on LDAP.')
+ ->addArgument(
+ 'ocName',
+ InputArgument::REQUIRED,
+ 'the group name as used in Nextcloud, or the LDAP DN'
+ )
+ ->addOption(
+ 'force',
+ null,
+ InputOption::VALUE_NONE,
+ 'ignores disabled LDAP configuration'
+ )
+ ->addOption(
+ 'update',
+ null,
+ InputOption::VALUE_NONE,
+ 'syncs values from LDAP'
+ )
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $this->dispatcher->addListener(GroupCreatedEvent::class, fn ($event) => $this->onGroupCreatedEvent($event, $output));
+ $this->dispatcher->addListener(UserAddedEvent::class, fn ($event) => $this->onUserAddedEvent($event, $output));
+ $this->dispatcher->addListener(UserRemovedEvent::class, fn ($event) => $this->onUserRemovedEvent($event, $output));
+ try {
+ $this->assertAllowed($input->getOption('force'));
+ $gid = $input->getArgument('ocName');
+ $wasMapped = $this->groupWasMapped($gid);
+ if ($this->backend->getLDAPAccess($gid)->stringResemblesDN($gid)) {
+ $groupname = $this->backend->dn2GroupName($gid);
+ if ($groupname !== false) {
+ $gid = $groupname;
+ }
+ }
+ /* Search to trigger mapping for new groups */
+ $this->backend->getGroups($gid);
+ $exists = $this->backend->groupExistsOnLDAP($gid, true);
+ if ($exists === true) {
+ $output->writeln('The group is still available on LDAP.');
+ if ($input->getOption('update')) {
+ $this->backend->getLDAPAccess($gid)->connection->clearCache();
+ if ($wasMapped) {
+ $this->service->handleKnownGroups([$gid]);
+ } else {
+ $this->service->handleCreatedGroups([$gid]);
+ }
+ }
+ return self::SUCCESS;
+ }
+
+ if ($wasMapped) {
+ $output->writeln('The group does not exist on LDAP anymore.');
+ if ($input->getOption('update')) {
+ $this->backend->getLDAPAccess($gid)->connection->clearCache();
+ $this->service->handleRemovedGroups([$gid]);
+ }
+ return self::SUCCESS;
+ }
+
+ throw new \Exception('The given group is not a recognized LDAP group.');
+ } catch (\Exception $e) {
+ $output->writeln('<error>' . $e->getMessage() . '</error>');
+ return self::FAILURE;
+ }
+ }
+
+ public function onGroupCreatedEvent(GroupCreatedEvent $event, OutputInterface $output): void {
+ $output->writeln('<info>The group ' . $event->getGroup()->getGID() . ' was added to Nextcloud with ' . $event->getGroup()->count() . ' users</info>');
+ }
+
+ public function onUserAddedEvent(UserAddedEvent $event, OutputInterface $output): void {
+ $user = $event->getUser();
+ $group = $event->getGroup();
+ $output->writeln('<info>The user ' . $user->getUID() . ' was added to group ' . $group->getGID() . '</info>');
+ }
+
+ public function onUserRemovedEvent(UserRemovedEvent $event, OutputInterface $output): void {
+ $user = $event->getUser();
+ $group = $event->getGroup();
+ $output->writeln('<info>The user ' . $user->getUID() . ' was removed from group ' . $group->getGID() . '</info>');
+ }
+
+ /**
+ * checks whether a group is actually mapped
+ * @param string $gid the groupname as passed to the command
+ */
+ protected function groupWasMapped(string $gid): bool {
+ $dn = $this->mapping->getDNByName($gid);
+ if ($dn !== false) {
+ return true;
+ }
+ $name = $this->mapping->getNameByDN($gid);
+ return $name !== false;
+ }
+
+ /**
+ * checks whether the setup allows reliable checking of LDAP group existence
+ * @throws \Exception
+ */
+ protected function assertAllowed(bool $force): void {
+ if ($this->helper->haveDisabledConfigurations() && !$force) {
+ throw new \Exception('Cannot check group existence, because '
+ . 'disabled LDAP configurations are present.');
+ }
+
+ // we don't check ldapUserCleanupInterval from config.php because this
+ // action is triggered manually, while the setting only controls the
+ // background job.
+ }
+
+ private function updateGroup(string $gid, OutputInterface $output, bool $wasMapped): void {
+ try {
+ if ($wasMapped) {
+ $this->service->handleKnownGroups([$gid]);
+ } else {
+ $this->service->handleCreatedGroups([$gid]);
+ }
+ } catch (\Exception $e) {
+ $output->writeln('<error>Error while trying to lookup and update attributes from LDAP</error>');
+ }
+ }
+}