diff options
Diffstat (limited to 'apps/user_ldap')
-rw-r--r-- | apps/user_ldap/ajax/clearMappings.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/l10n/uk.js | 12 | ||||
-rw-r--r-- | apps/user_ldap/l10n/uk.json | 12 | ||||
-rw-r--r-- | apps/user_ldap/lib/DataCollector/LdapDataCollector.php | 3 | ||||
-rw-r--r-- | apps/user_ldap/lib/Group_Proxy.php | 35 | ||||
-rw-r--r-- | apps/user_ldap/lib/Jobs/CleanUp.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/lib/Jobs/Sync.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/lib/LDAP.php | 3 | ||||
-rw-r--r-- | apps/user_ldap/lib/Mapping/UserMapping.php | 39 | ||||
-rw-r--r-- | apps/user_ldap/lib/Proxy.php | 42 | ||||
-rw-r--r-- | apps/user_ldap/lib/User_LDAP.php | 9 | ||||
-rw-r--r-- | apps/user_ldap/lib/User_Proxy.php | 57 | ||||
-rw-r--r-- | apps/user_ldap/tests/Mapping/UserMappingTest.php | 3 |
13 files changed, 164 insertions, 57 deletions
diff --git a/apps/user_ldap/ajax/clearMappings.php b/apps/user_ldap/ajax/clearMappings.php index 39462f334c9..f8469cc85b1 100644 --- a/apps/user_ldap/ajax/clearMappings.php +++ b/apps/user_ldap/ajax/clearMappings.php @@ -35,7 +35,7 @@ $subject = (string)$_POST['ldap_clear_mapping']; $mapping = null; try { if ($subject === 'user') { - $mapping = new UserMapping(\OC::$server->getDatabaseConnection()); + $mapping = \OCP\Server::get(UserMapping::class); $result = $mapping->clearCb( function ($uid) { \OC::$server->getUserManager()->emit('\OC\User', 'preUnassignedUserId', [$uid]); diff --git a/apps/user_ldap/l10n/uk.js b/apps/user_ldap/l10n/uk.js index 34b1725daac..7ce76c7bf73 100644 --- a/apps/user_ldap/l10n/uk.js +++ b/apps/user_ldap/l10n/uk.js @@ -1,7 +1,7 @@ OC.L10N.register( "user_ldap", { - "Failed to clear the mappings." : "Не вдалося очистити відображення.", + "Failed to clear the mappings." : "Не вдалося очистити мапування.", "Failed to delete the server configuration" : "Не вдалося вилучити конфігурацію сервера", "Invalid configuration: Anonymous binding is not allowed." : "Неправильна конфігурація. Анонімне приєднання не дозволено.", "Valid configuration, connection established!" : "Правильна конфігурація, з'єднання встановлено!", @@ -36,7 +36,7 @@ OC.L10N.register( "An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Сталась помилка. Будь ласка, перевірте базове DN, а також налаштування підключення та облікові дані.", "Do you really want to delete the current Server Configuration?" : "Дійсно вилучити поточну конфігурацію сервера ?", "Confirm Deletion" : "Підтвердіть вилучення", - "Mappings cleared successfully!" : "Відображення успішно очищенні!", + "Mappings cleared successfully!" : "Мапування успішно очищено!", "Error while clearing the mappings." : "Помилка при очищенні відображень.", "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонімне прив'язування не допускається. Укажіть DN користувача та пароль.", "LDAP Operations error. Anonymous bind might not be allowed." : "Помилка операцій LDAP. Анонімне прив’язування може бути заборонено.", @@ -139,7 +139,7 @@ OC.L10N.register( "Give an optional backup host. It must be a replica of the main LDAP/AD server." : "Вкажіть додатковий резервний сервер. Він повинен бути копією головного LDAP/AD сервера.", "Backup (Replica) Port" : "Порт сервера для резервних копій", "Disable Main Server" : "Вимкнути Головний Сервер", - "Only connect to the replica server." : "Підключити тільки до сервера реплік.", + "Only connect to the replica server." : "З'єднатися тільки із сервером реплік.", "Turn off SSL certificate validation." : "Вимкнути перевірку SSL сертифіката.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." : "Не рекомендується, використовувати його тільки для тестування!\nЯкщо з'єднання працює лише з цією опцією, імпортуйте SSL сертифікат LDAP сервера у ваший %s сервер.", "Cache Time-To-Live" : "Час актуальності Кеша", @@ -148,16 +148,16 @@ OC.L10N.register( "User Display Name Field" : "Поле, яке відображає Ім'я Користувача", "The LDAP attribute to use to generate the user's display name." : "Атрибут LDAP, який використовується для генерації імен користувачів.", "2nd User Display Name Field" : "2-е поле відображуваного імені користувача", - "Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«." : "Додатково. Атрибут LDAP, який потрібно додати до відображуваного імені в дужках. Результати, напр. »Джон Доу (john.doe@example.org)«.", + "Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«." : "Додатково. Атрибут LDAP, який потрібно додати до відображуваного імені в дужках. Результати, напр. \"Джон Доу (john.doe@example.org)\".", "Base User Tree" : "Основне Дерево Користувачів", "One User Base DN per line" : "Один Користувач Base DN на рядок", - "User Search Attributes" : "Пошукові Атрибути Користувача", + "User Search Attributes" : "Пошукові атрибутів користувача", "Optional; one attribute per line" : "Додатково; один атрибут на рядок", "Group Display Name Field" : "Поле, яке відображає Ім'я Групи", "The LDAP attribute to use to generate the groups's display name." : "Атрибут LDAP, який використовується для генерації імен груп.", "Base Group Tree" : "Основне Дерево Груп", "One Group Base DN per line" : "Одна Група Base DN на рядок", - "Group Search Attributes" : "Пошукові Атрибути Групи", + "Group Search Attributes" : "Пошукові атрибути групи", "Group-Member association" : "Асоціація \"група-учасник\"", "Dynamic Group Member URL" : "URL-адреса учасника динамічної групи", "The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)" : "Атрибут LDAP, який об’єктів групи містить URL-адресу пошуку LDAP, яка визначає, які об’єкти належать до групи. (Пусте налаштування вимикає функцію динамічного членства в групі.)", diff --git a/apps/user_ldap/l10n/uk.json b/apps/user_ldap/l10n/uk.json index 023d601d1ad..130dd65a1f2 100644 --- a/apps/user_ldap/l10n/uk.json +++ b/apps/user_ldap/l10n/uk.json @@ -1,5 +1,5 @@ { "translations": { - "Failed to clear the mappings." : "Не вдалося очистити відображення.", + "Failed to clear the mappings." : "Не вдалося очистити мапування.", "Failed to delete the server configuration" : "Не вдалося вилучити конфігурацію сервера", "Invalid configuration: Anonymous binding is not allowed." : "Неправильна конфігурація. Анонімне приєднання не дозволено.", "Valid configuration, connection established!" : "Правильна конфігурація, з'єднання встановлено!", @@ -34,7 +34,7 @@ "An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Сталась помилка. Будь ласка, перевірте базове DN, а також налаштування підключення та облікові дані.", "Do you really want to delete the current Server Configuration?" : "Дійсно вилучити поточну конфігурацію сервера ?", "Confirm Deletion" : "Підтвердіть вилучення", - "Mappings cleared successfully!" : "Відображення успішно очищенні!", + "Mappings cleared successfully!" : "Мапування успішно очищено!", "Error while clearing the mappings." : "Помилка при очищенні відображень.", "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонімне прив'язування не допускається. Укажіть DN користувача та пароль.", "LDAP Operations error. Anonymous bind might not be allowed." : "Помилка операцій LDAP. Анонімне прив’язування може бути заборонено.", @@ -137,7 +137,7 @@ "Give an optional backup host. It must be a replica of the main LDAP/AD server." : "Вкажіть додатковий резервний сервер. Він повинен бути копією головного LDAP/AD сервера.", "Backup (Replica) Port" : "Порт сервера для резервних копій", "Disable Main Server" : "Вимкнути Головний Сервер", - "Only connect to the replica server." : "Підключити тільки до сервера реплік.", + "Only connect to the replica server." : "З'єднатися тільки із сервером реплік.", "Turn off SSL certificate validation." : "Вимкнути перевірку SSL сертифіката.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." : "Не рекомендується, використовувати його тільки для тестування!\nЯкщо з'єднання працює лише з цією опцією, імпортуйте SSL сертифікат LDAP сервера у ваший %s сервер.", "Cache Time-To-Live" : "Час актуальності Кеша", @@ -146,16 +146,16 @@ "User Display Name Field" : "Поле, яке відображає Ім'я Користувача", "The LDAP attribute to use to generate the user's display name." : "Атрибут LDAP, який використовується для генерації імен користувачів.", "2nd User Display Name Field" : "2-е поле відображуваного імені користувача", - "Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«." : "Додатково. Атрибут LDAP, який потрібно додати до відображуваного імені в дужках. Результати, напр. »Джон Доу (john.doe@example.org)«.", + "Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«." : "Додатково. Атрибут LDAP, який потрібно додати до відображуваного імені в дужках. Результати, напр. \"Джон Доу (john.doe@example.org)\".", "Base User Tree" : "Основне Дерево Користувачів", "One User Base DN per line" : "Один Користувач Base DN на рядок", - "User Search Attributes" : "Пошукові Атрибути Користувача", + "User Search Attributes" : "Пошукові атрибутів користувача", "Optional; one attribute per line" : "Додатково; один атрибут на рядок", "Group Display Name Field" : "Поле, яке відображає Ім'я Групи", "The LDAP attribute to use to generate the groups's display name." : "Атрибут LDAP, який використовується для генерації імен груп.", "Base Group Tree" : "Основне Дерево Груп", "One Group Base DN per line" : "Одна Група Base DN на рядок", - "Group Search Attributes" : "Пошукові Атрибути Групи", + "Group Search Attributes" : "Пошукові атрибути групи", "Group-Member association" : "Асоціація \"група-учасник\"", "Dynamic Group Member URL" : "URL-адреса учасника динамічної групи", "The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)" : "Атрибут LDAP, який об’єктів групи містить URL-адресу пошуку LDAP, яка визначає, які об’єкти належать до групи. (Пусте налаштування вимикає функцію динамічного членства в групі.)", diff --git a/apps/user_ldap/lib/DataCollector/LdapDataCollector.php b/apps/user_ldap/lib/DataCollector/LdapDataCollector.php index cb61de96e37..833b314b199 100644 --- a/apps/user_ldap/lib/DataCollector/LdapDataCollector.php +++ b/apps/user_ldap/lib/DataCollector/LdapDataCollector.php @@ -28,12 +28,13 @@ use OCP\AppFramework\Http\Response; use OCP\DataCollector\AbstractDataCollector; class LdapDataCollector extends AbstractDataCollector { - public function startLdapRequest(string $query, array $args): void { + public function startLdapRequest(string $query, array $args, array $backtrace): void { $this->data[] = [ 'start' => microtime(true), 'query' => $query, 'args' => $args, 'end' => microtime(true), + 'backtrace' => $backtrace, ]; } diff --git a/apps/user_ldap/lib/Group_Proxy.php b/apps/user_ldap/lib/Group_Proxy.php index ea2fcce679c..f8bdae67b72 100644 --- a/apps/user_ldap/lib/Group_Proxy.php +++ b/apps/user_ldap/lib/Group_Proxy.php @@ -34,18 +34,32 @@ use OCP\Group\Backend\INamedBackend; class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGetDisplayNameBackend, INamedBackend, IDeleteGroupBackend { private $backends = []; - private $refBackend = null; + private ?Group_LDAP $refBackend = null; + private Helper $helper; + private GroupPluginManager $groupPluginManager; + private bool $isSetUp = false; public function __construct(Helper $helper, ILDAPWrapper $ldap, GroupPluginManager $groupPluginManager) { parent::__construct($ldap); - $serverConfigPrefixes = $helper->getServerConfigurationPrefixes(true); + $this->helper = $helper; + $this->groupPluginManager = $groupPluginManager; + } + + protected function setup(): void { + if ($this->isSetUp) { + return; + } + + $serverConfigPrefixes = $this->helper->getServerConfigurationPrefixes(true); foreach ($serverConfigPrefixes as $configPrefix) { $this->backends[$configPrefix] = - new \OCA\User_LDAP\Group_LDAP($this->getAccess($configPrefix), $groupPluginManager); + new Group_LDAP($this->getAccess($configPrefix), $this->groupPluginManager); if (is_null($this->refBackend)) { $this->refBackend = &$this->backends[$configPrefix]; } } + + $this->isSetUp = true; } /** @@ -57,6 +71,8 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * @return mixed the result of the method or false */ protected function walkBackends($id, $method, $parameters) { + $this->setup(); + $gid = $id; $cacheKey = $this->getGroupCacheKey($gid); foreach ($this->backends as $configPrefix => $backend) { @@ -80,6 +96,8 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * @return mixed the result of the method or false */ protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen) { + $this->setup(); + $gid = $id; $cacheKey = $this->getGroupCacheKey($gid); $prefix = $this->getFromCache($cacheKey); @@ -105,6 +123,7 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet } protected function activeBackends(): int { + $this->setup(); return count($this->backends); } @@ -131,8 +150,9 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * if the user exists at all. */ public function getUserGroups($uid) { - $groups = []; + $this->setup(); + $groups = []; foreach ($this->backends as $backend) { $backendGroups = $backend->getUserGroups($uid); if (is_array($backendGroups)) { @@ -149,8 +169,9 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * @return string[] with user ids */ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { - $users = []; + $this->setup(); + $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->usersInGroup($gid, $search, $limit, $offset); if (is_array($backendUsers)) { @@ -237,8 +258,9 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * Returns a list with all groups */ public function getGroups($search = '', $limit = -1, $offset = 0) { - $groups = []; + $this->setup(); + $groups = []; foreach ($this->backends as $backend) { $backendGroups = $backend->getGroups($search, $limit, $offset); if (is_array($backendGroups)) { @@ -269,6 +291,7 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet * compared with \OCP\GroupInterface::CREATE_GROUP etc. */ public function implementsActions($actions) { + $this->setup(); //it's the same across all our user backends obviously return $this->refBackend->implementsActions($actions); } diff --git a/apps/user_ldap/lib/Jobs/CleanUp.php b/apps/user_ldap/lib/Jobs/CleanUp.php index 1fb423b5faf..22067d81a9d 100644 --- a/apps/user_ldap/lib/Jobs/CleanUp.php +++ b/apps/user_ldap/lib/Jobs/CleanUp.php @@ -107,7 +107,7 @@ class CleanUp extends TimedJob { if (isset($arguments['mapping'])) { $this->mapping = $arguments['mapping']; } else { - $this->mapping = new UserMapping($this->db); + $this->mapping = \OCP\Server::get(UserMapping::class); } if (isset($arguments['deletedUsersIndex'])) { diff --git a/apps/user_ldap/lib/Jobs/Sync.php b/apps/user_ldap/lib/Jobs/Sync.php index d9171f4aab7..b231089b79b 100644 --- a/apps/user_ldap/lib/Jobs/Sync.php +++ b/apps/user_ldap/lib/Jobs/Sync.php @@ -357,7 +357,7 @@ class Sync extends TimedJob { if (isset($argument['mapper'])) { $this->mapper = $argument['mapper']; } else { - $this->mapper = new UserMapping($this->dbc); + $this->mapper = \OCP\Server::get(UserMapping::class); } if (isset($argument['connectionFactory'])) { diff --git a/apps/user_ldap/lib/LDAP.php b/apps/user_ldap/lib/LDAP.php index c03337a9e51..6a54f89880d 100644 --- a/apps/user_ldap/lib/LDAP.php +++ b/apps/user_ldap/lib/LDAP.php @@ -330,7 +330,8 @@ class LDAP implements ILDAPWrapper { return $item; }, $this->curArgs); - $this->dataCollector->startLdapRequest($functionName, $args); + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $this->dataCollector->startLdapRequest($functionName, $args, $backtrace); } if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) { diff --git a/apps/user_ldap/lib/Mapping/UserMapping.php b/apps/user_ldap/lib/Mapping/UserMapping.php index 899cc015c9f..ade9c67213a 100644 --- a/apps/user_ldap/lib/Mapping/UserMapping.php +++ b/apps/user_ldap/lib/Mapping/UserMapping.php @@ -22,12 +22,51 @@ */ namespace OCA\User_LDAP\Mapping; +use OCP\HintException; +use OCP\IDBConnection; +use OCP\IRequest; +use OCP\Server; +use OCP\Support\Subscription\IAssertion; + /** * Class UserMapping + * * @package OCA\User_LDAP\Mapping */ class UserMapping extends AbstractMapping { + private IAssertion $assertion; + protected const PROV_API_REGEX = '/\/ocs\/v[1-9].php\/cloud\/(groups|users)/'; + + public function __construct(IDBConnection $dbc, IAssertion $assertion) { + $this->assertion = $assertion; + parent::__construct($dbc); + } + + /** + * @throws HintException + */ + public function map($fdn, $name, $uuid): bool { + try { + $this->assertion->createUserIsLegit(); + } catch (HintException $e) { + static $isProvisioningApi = null; + + if ($isProvisioningApi === null) { + $request = Server::get(IRequest::class); + $isProvisioningApi = \preg_match(self::PROV_API_REGEX, $request->getRequestUri()) === 1; + } + if ($isProvisioningApi) { + // only throw when prov API is being used, since functionality + // should not break for end users (e.g. when sharing). + // On direct API usage, e.g. on users page, this is desired. + throw $e; + } + return false; + } + return parent::map($fdn, $name, $uuid); + } + /** * returns the DB table name which holds the mappings * @return string diff --git a/apps/user_ldap/lib/Proxy.php b/apps/user_ldap/lib/Proxy.php index d9546a163ab..4df6c2683a6 100644 --- a/apps/user_ldap/lib/Proxy.php +++ b/apps/user_ldap/lib/Proxy.php @@ -35,7 +35,9 @@ namespace OCA\User_LDAP; use OCA\User_LDAP\Mapping\GroupMapping; use OCA\User_LDAP\Mapping\UserMapping; use OCA\User_LDAP\User\Manager; -use OCP\Share\IManager; +use OCP\IConfig; +use OCP\IUserManager; +use OCP\Server; use Psr\Log\LoggerInterface; abstract class Proxy { @@ -61,34 +63,18 @@ abstract class Proxy { /** * @param string $configPrefix */ - private function addAccess($configPrefix) { - static $ocConfig; - static $fs; - static $log; - static $avatarM; - static $userMap; - static $groupMap; - static $shareManager; - static $coreUserManager; - static $coreNotificationManager; - static $logger; - if ($fs === null) { - $ocConfig = \OC::$server->getConfig(); - $fs = new FilesystemHelper(); - $avatarM = \OC::$server->getAvatarManager(); - $db = \OC::$server->getDatabaseConnection(); - $userMap = new UserMapping($db); - $groupMap = new GroupMapping($db); - $coreUserManager = \OC::$server->getUserManager(); - $coreNotificationManager = \OC::$server->getNotificationManager(); - $shareManager = \OC::$server->get(IManager::class); - $logger = \OC::$server->get(LoggerInterface::class); - } - $userManager = - new Manager($ocConfig, $fs, $logger, $avatarM, new \OCP\Image(), - $coreUserManager, $coreNotificationManager, $shareManager); + private function addAccess(string $configPrefix): void { + $ocConfig = Server::get(IConfig::class); + $userMap = Server::get(UserMapping::class); + $groupMap = Server::get(GroupMapping::class); + $coreUserManager = Server::get(IUserManager::class); + $logger = Server::get(LoggerInterface::class); + $helper = Server::get(Helper::class); + + $userManager = Server::get(Manager::class); + $connector = new Connection($this->ldap, $configPrefix); - $access = new Access($connector, $this->ldap, $userManager, new Helper($ocConfig, \OC::$server->getDatabaseConnection()), $ocConfig, $coreUserManager, $logger); + $access = new Access($connector, $this->ldap, $userManager, $helper, $ocConfig, $coreUserManager, $logger); $access->setUserMapper($userMap); $access->setGroupMapper($groupMap); self::$accesses[$configPrefix] = $access; diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php index 5a445100052..650c974da81 100644 --- a/apps/user_ldap/lib/User_LDAP.php +++ b/apps/user_ldap/lib/User_LDAP.php @@ -45,14 +45,15 @@ use OCA\User_LDAP\Exceptions\NotOnLDAP; use OCA\User_LDAP\User\OfflineUser; use OCA\User_LDAP\User\User; use OCP\IConfig; +use OCP\IUserBackend; use OCP\IUserSession; use OCP\Notification\IManager as INotificationManager; +use OCP\User\Backend\ICountMappedUsersBackend; use OCP\User\Backend\ICountUsersBackend; -use OCP\IUserBackend; use OCP\UserInterface; use Psr\Log\LoggerInterface; -class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend { +class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend { /** @var \OCP\IConfig */ protected $ocConfig; @@ -598,6 +599,10 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I return $entries; } + public function countMappedUsers(): int { + return $this->access->getUserMapper()->count(); + } + /** * Backend name to be shown in user management * @return string the name of the backend to be shown diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php index 040d4f5aa69..b98fa8da0ff 100644 --- a/apps/user_ldap/lib/User_Proxy.php +++ b/apps/user_ldap/lib/User_Proxy.php @@ -33,15 +33,25 @@ namespace OCA\User_LDAP; use OCA\User_LDAP\User\User; use OCP\IConfig; +use OCP\IUserBackend; use OCP\IUserSession; use OCP\Notification\IManager as INotificationManager; +use OCP\User\Backend\ICountMappedUsersBackend; use OCP\User\Backend\ICountUsersBackend; +use OCP\UserInterface; -class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP, ICountUsersBackend { +class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend { private $backends = []; /** @var User_LDAP */ private $refBackend = null; + private bool $isSetUp = false; + private Helper $helper; + private IConfig $ocConfig; + private INotificationManager $notificationManager; + private IUserSession $userSession; + private UserPluginManager $userPluginManager; + public function __construct( Helper $helper, ILDAPWrapper $ldap, @@ -51,15 +61,29 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, UserPluginManager $userPluginManager ) { parent::__construct($ldap); - $serverConfigPrefixes = $helper->getServerConfigurationPrefixes(true); + $this->helper = $helper; + $this->ocConfig = $ocConfig; + $this->notificationManager = $notificationManager; + $this->userSession = $userSession; + $this->userPluginManager = $userPluginManager; + } + + protected function setup(): void { + if ($this->isSetUp) { + return; + } + + $serverConfigPrefixes = $this->helper->getServerConfigurationPrefixes(true); foreach ($serverConfigPrefixes as $configPrefix) { $this->backends[$configPrefix] = - new User_LDAP($this->getAccess($configPrefix), $ocConfig, $notificationManager, $userSession, $userPluginManager); + new User_LDAP($this->getAccess($configPrefix), $this->ocConfig, $this->notificationManager, $this->userSession, $this->userPluginManager); if (is_null($this->refBackend)) { $this->refBackend = &$this->backends[$configPrefix]; } } + + $this->isSetUp = true; } /** @@ -71,6 +95,8 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return mixed the result of the method or false */ protected function walkBackends($id, $method, $parameters) { + $this->setup(); + $uid = $id; $cacheKey = $this->getUserCacheKey($uid); foreach ($this->backends as $configPrefix => $backend) { @@ -99,6 +125,8 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return mixed the result of the method or false */ protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen) { + $this->setup(); + $uid = $id; $cacheKey = $this->getUserCacheKey($uid); $prefix = $this->getFromCache($cacheKey); @@ -129,6 +157,7 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, } protected function activeBackends(): int { + $this->setup(); return count($this->backends); } @@ -142,6 +171,7 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * compared with \OC\User\Backend::CREATE_USER etc. */ public function implementsActions($actions) { + $this->setup(); //it's the same across all our user backends obviously return $this->refBackend->implementsActions($actions); } @@ -152,6 +182,7 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return string the name of the backend to be shown */ public function getBackendName() { + $this->setup(); return $this->refBackend->getBackendName(); } @@ -164,6 +195,8 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return string[] an array of all uids */ public function getUsers($search = '', $limit = 10, $offset = 0) { + $this->setup(); + //we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends $users = []; foreach ($this->backends as $backend) { @@ -296,6 +329,8 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return array an array of all displayNames (value) and the corresponding uids (key) */ public function getDisplayNames($search = '', $limit = null, $offset = null) { + $this->setup(); + //we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends $users = []; foreach ($this->backends as $backend) { @@ -335,6 +370,7 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return bool */ public function hasUserListings() { + $this->setup(); return $this->refBackend->hasUserListings(); } @@ -344,6 +380,8 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * @return int|bool */ public function countUsers() { + $this->setup(); + $users = false; foreach ($this->backends as $backend) { $backendUsers = $backend->countUsers(); @@ -355,6 +393,19 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, } /** + * Count the number of mapped users + */ + public function countMappedUsers(): int { + $this->setup(); + + $users = 0; + foreach ($this->backends as $backend) { + $users += $backend->countMappedUsers(); + } + return $users; + } + + /** * Return access for LDAP interaction. * * @param string $uid diff --git a/apps/user_ldap/tests/Mapping/UserMappingTest.php b/apps/user_ldap/tests/Mapping/UserMappingTest.php index 081266cf3f1..e585fafb134 100644 --- a/apps/user_ldap/tests/Mapping/UserMappingTest.php +++ b/apps/user_ldap/tests/Mapping/UserMappingTest.php @@ -24,6 +24,7 @@ namespace OCA\User_LDAP\Tests\Mapping; use OCA\User_LDAP\Mapping\UserMapping; +use OCP\Support\Subscription\IAssertion; /** * Class UserMappingTest @@ -34,6 +35,6 @@ use OCA\User_LDAP\Mapping\UserMapping; */ class UserMappingTest extends AbstractMappingTest { public function getMapper(\OCP\IDBConnection $dbMock) { - return new UserMapping($dbMock); + return new UserMapping($dbMock, $this->createMock(IAssertion::class)); } } |