CheckUser.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\User_LDAP\Command;
  8. use OCA\User_LDAP\Helper;
  9. use OCA\User_LDAP\Mapping\UserMapping;
  10. use OCA\User_LDAP\User\DeletedUsersIndex;
  11. use OCA\User_LDAP\User_Proxy;
  12. use Symfony\Component\Console\Command\Command;
  13. use Symfony\Component\Console\Input\InputArgument;
  14. use Symfony\Component\Console\Input\InputInterface;
  15. use Symfony\Component\Console\Input\InputOption;
  16. use Symfony\Component\Console\Output\OutputInterface;
  17. class CheckUser extends Command {
  18. protected User_Proxy $backend;
  19. public function __construct(
  20. User_Proxy $uBackend,
  21. protected Helper $helper,
  22. protected DeletedUsersIndex $dui,
  23. protected UserMapping $mapping,
  24. ) {
  25. $this->backend = $uBackend;
  26. parent::__construct();
  27. }
  28. protected function configure(): void {
  29. $this
  30. ->setName('ldap:check-user')
  31. ->setDescription('checks whether a user exists on LDAP.')
  32. ->addArgument(
  33. 'ocName',
  34. InputArgument::REQUIRED,
  35. 'the user name as used in Nextcloud, or the LDAP DN'
  36. )
  37. ->addOption(
  38. 'force',
  39. null,
  40. InputOption::VALUE_NONE,
  41. 'ignores disabled LDAP configuration'
  42. )
  43. ->addOption(
  44. 'update',
  45. null,
  46. InputOption::VALUE_NONE,
  47. 'syncs values from LDAP'
  48. )
  49. ;
  50. }
  51. protected function execute(InputInterface $input, OutputInterface $output): int {
  52. try {
  53. $this->assertAllowed($input->getOption('force'));
  54. $uid = $input->getArgument('ocName');
  55. if ($this->backend->getLDAPAccess($uid)->stringResemblesDN($uid)) {
  56. $username = $this->backend->dn2UserName($uid);
  57. if ($username !== false) {
  58. $uid = $username;
  59. }
  60. }
  61. $wasMapped = $this->userWasMapped($uid);
  62. $exists = $this->backend->userExistsOnLDAP($uid, true);
  63. if ($exists === true) {
  64. $output->writeln('The user is still available on LDAP.');
  65. if ($input->getOption('update')) {
  66. $this->updateUser($uid, $output);
  67. }
  68. return self::SUCCESS;
  69. }
  70. if ($wasMapped) {
  71. $this->dui->markUser($uid);
  72. $output->writeln('The user does not exists on LDAP anymore.');
  73. $output->writeln('Clean up the user\'s remnants by: ./occ user:delete "'
  74. . $uid . '"');
  75. return self::SUCCESS;
  76. }
  77. throw new \Exception('The given user is not a recognized LDAP user.');
  78. } catch (\Exception $e) {
  79. $output->writeln('<error>' . $e->getMessage(). '</error>');
  80. return self::FAILURE;
  81. }
  82. }
  83. /**
  84. * checks whether a user is actually mapped
  85. * @param string $ocName the username as used in Nextcloud
  86. */
  87. protected function userWasMapped(string $ocName): bool {
  88. $dn = $this->mapping->getDNByName($ocName);
  89. return $dn !== false;
  90. }
  91. /**
  92. * checks whether the setup allows reliable checking of LDAP user existence
  93. * @throws \Exception
  94. */
  95. protected function assertAllowed(bool $force): void {
  96. if ($this->helper->haveDisabledConfigurations() && !$force) {
  97. throw new \Exception('Cannot check user existence, because '
  98. . 'disabled LDAP configurations are present.');
  99. }
  100. // we don't check ldapUserCleanupInterval from config.php because this
  101. // action is triggered manually, while the setting only controls the
  102. // background job.
  103. }
  104. private function updateUser(string $uid, OutputInterface $output): void {
  105. try {
  106. $access = $this->backend->getLDAPAccess($uid);
  107. $attrs = $access->userManager->getAttributes();
  108. $user = $access->userManager->get($uid);
  109. $avatarAttributes = $access->getConnection()->resolveRule('avatar');
  110. $baseDn = $this->helper->DNasBaseParameter($user->getDN());
  111. $result = $access->search('objectclass=*', $baseDn, $attrs, 1, 0);
  112. foreach ($result[0] as $attribute => $valueSet) {
  113. $output->writeln(' ' . $attribute . ': ');
  114. foreach ($valueSet as $value) {
  115. if (in_array($attribute, $avatarAttributes)) {
  116. $value = '{ImageData}';
  117. }
  118. $output->writeln(' ' . $value);
  119. }
  120. }
  121. $access->batchApplyUserAttributes($result);
  122. } catch (\Exception $e) {
  123. $output->writeln('<error>Error while trying to lookup and update attributes from LDAP</error>');
  124. }
  125. }
  126. }