aboutsummaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_ldap/lib')
-rw-r--r--apps/user_ldap/lib/Access.php306
-rw-r--r--apps/user_ldap/lib/AccessFactory.php54
-rw-r--r--apps/user_ldap/lib/AppInfo/Application.php40
-rw-r--r--apps/user_ldap/lib/BackendUtility.php32
-rw-r--r--apps/user_ldap/lib/Command/CheckGroup.php33
-rw-r--r--apps/user_ldap/lib/Command/CheckUser.php34
-rw-r--r--apps/user_ldap/lib/Command/CreateEmptyConfig.php25
-rw-r--r--apps/user_ldap/lib/Command/DeleteConfig.php25
-rw-r--r--apps/user_ldap/lib/Command/PromoteGroup.php23
-rw-r--r--apps/user_ldap/lib/Command/ResetGroup.php23
-rw-r--r--apps/user_ldap/lib/Command/ResetUser.php22
-rw-r--r--apps/user_ldap/lib/Command/Search.php32
-rw-r--r--apps/user_ldap/lib/Command/SetConfig.php31
-rw-r--r--apps/user_ldap/lib/Command/ShowConfig.php29
-rw-r--r--apps/user_ldap/lib/Command/ShowRemnants.php27
-rw-r--r--apps/user_ldap/lib/Command/TestConfig.php27
-rw-r--r--apps/user_ldap/lib/Command/TestUserSettings.php248
-rw-r--r--apps/user_ldap/lib/Command/UpdateUUID.php24
-rw-r--r--apps/user_ldap/lib/Configuration.php172
-rw-r--r--apps/user_ldap/lib/Connection.php344
-rw-r--r--apps/user_ldap/lib/ConnectionFactory.php30
-rw-r--r--apps/user_ldap/lib/Controller/ConfigAPIController.php46
-rw-r--r--apps/user_ldap/lib/Controller/RenewPasswordController.php79
-rw-r--r--apps/user_ldap/lib/DataCollector/LdapDataCollector.php21
-rw-r--r--apps/user_ldap/lib/Db/GroupMembership.php21
-rw-r--r--apps/user_ldap/lib/Db/GroupMembershipMapper.php21
-rw-r--r--apps/user_ldap/lib/Events/GroupBackendRegistered.php34
-rw-r--r--apps/user_ldap/lib/Events/UserBackendRegistered.php34
-rw-r--r--apps/user_ldap/lib/Exceptions/AttributeNotSet.php23
-rw-r--r--apps/user_ldap/lib/Exceptions/ConfigurationIssueException.php15
-rw-r--r--apps/user_ldap/lib/Exceptions/ConstraintViolationException.php23
-rw-r--r--apps/user_ldap/lib/Exceptions/NoMoreResults.php21
-rw-r--r--apps/user_ldap/lib/Exceptions/NotOnLDAP.php23
-rw-r--r--apps/user_ldap/lib/FilesystemHelper.php46
-rw-r--r--apps/user_ldap/lib/GroupPluginManager.php26
-rw-r--r--apps/user_ldap/lib/Group_LDAP.php97
-rw-r--r--apps/user_ldap/lib/Group_Proxy.php80
-rw-r--r--apps/user_ldap/lib/Handler/ExtStorageConfigHandler.php24
-rw-r--r--apps/user_ldap/lib/Helper.php139
-rw-r--r--apps/user_ldap/lib/IGroupLDAP.php22
-rw-r--r--apps/user_ldap/lib/ILDAPGroupPlugin.php22
-rw-r--r--apps/user_ldap/lib/ILDAPUserPlugin.php25
-rw-r--r--apps/user_ldap/lib/ILDAPWrapper.php30
-rw-r--r--apps/user_ldap/lib/IUserLDAP.php27
-rw-r--r--apps/user_ldap/lib/Jobs/CleanUp.php62
-rw-r--r--apps/user_ldap/lib/Jobs/Sync.php199
-rw-r--r--apps/user_ldap/lib/Jobs/UpdateGroups.php29
-rw-r--r--apps/user_ldap/lib/LDAP.php97
-rw-r--r--apps/user_ldap/lib/LDAPProvider.php54
-rw-r--r--apps/user_ldap/lib/LDAPProviderFactory.php35
-rw-r--r--apps/user_ldap/lib/LDAPUtility.php34
-rw-r--r--apps/user_ldap/lib/LoginListener.php33
-rw-r--r--apps/user_ldap/lib/Mapping/AbstractMapping.php54
-rw-r--r--apps/user_ldap/lib/Mapping/GroupMapping.php23
-rw-r--r--apps/user_ldap/lib/Mapping/UserMapping.php30
-rw-r--r--apps/user_ldap/lib/Migration/GroupMappingMigration.php29
-rw-r--r--apps/user_ldap/lib/Migration/RemoveRefreshTime.php35
-rw-r--r--apps/user_ldap/lib/Migration/SetDefaultProvider.php35
-rw-r--r--apps/user_ldap/lib/Migration/UUIDFix.php23
-rw-r--r--apps/user_ldap/lib/Migration/UUIDFixGroup.php22
-rw-r--r--apps/user_ldap/lib/Migration/UUIDFixInsert.php47
-rw-r--r--apps/user_ldap/lib/Migration/UUIDFixUser.php22
-rw-r--r--apps/user_ldap/lib/Migration/UnsetDefaultProvider.php29
-rw-r--r--apps/user_ldap/lib/Migration/Version1010Date20200630192842.php22
-rw-r--r--apps/user_ldap/lib/Migration/Version1120Date20210917155206.php37
-rw-r--r--apps/user_ldap/lib/Migration/Version1130Date20211102154716.php32
-rw-r--r--apps/user_ldap/lib/Migration/Version1130Date20220110154717.php21
-rw-r--r--apps/user_ldap/lib/Migration/Version1130Date20220110154718.php21
-rw-r--r--apps/user_ldap/lib/Migration/Version1130Date20220110154719.php21
-rw-r--r--apps/user_ldap/lib/Migration/Version1141Date20220323143801.php28
-rw-r--r--apps/user_ldap/lib/Migration/Version1190Date20230706134108.php21
-rw-r--r--apps/user_ldap/lib/Migration/Version1190Date20230706134109.php21
-rw-r--r--apps/user_ldap/lib/Notification/Notifier.php42
-rw-r--r--apps/user_ldap/lib/PagedResults/TLinkId.php22
-rw-r--r--apps/user_ldap/lib/Proxy.php85
-rw-r--r--apps/user_ldap/lib/Service/BirthdateParserService.php44
-rw-r--r--apps/user_ldap/lib/Service/UpdateGroupsService.php35
-rw-r--r--apps/user_ldap/lib/Settings/Admin.php53
-rw-r--r--apps/user_ldap/lib/Settings/Section.php41
-rw-r--r--apps/user_ldap/lib/SetupChecks/LdapConnection.php35
-rw-r--r--apps/user_ldap/lib/SetupChecks/LdapInvalidUuids.php22
-rw-r--r--apps/user_ldap/lib/User/DeletedUsersIndex.php45
-rw-r--r--apps/user_ldap/lib/User/Manager.php111
-rw-r--r--apps/user_ldap/lib/User/OfflineUser.php53
-rw-r--r--apps/user_ldap/lib/User/User.php386
-rw-r--r--apps/user_ldap/lib/UserPluginManager.php32
-rw-r--r--apps/user_ldap/lib/User_LDAP.php149
-rw-r--r--apps/user_ldap/lib/User_Proxy.php142
-rw-r--r--apps/user_ldap/lib/Wizard.php114
-rw-r--r--apps/user_ldap/lib/WizardResult.php30
90 files changed, 1849 insertions, 3188 deletions
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index 32bc8601121..9fe0aa64268 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -1,48 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Aaron Wood <aaronjwood@gmail.com>
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Benjamin Diele <benjamin@diele.be>
- * @author bline <scottbeck@gmail.com>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author J0WI <J0WI@users.noreply.github.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
- * @author Lorenzo M. Catucci <lorenzo@sancho.ccd.uniroma2.it>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Mario Kolling <mario.kolling@serpro.gov.br>
- * @author Max Kovalenko <mxss1998@yandex.ru>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Nicolas Grekas <nicolas.grekas@gmail.com>
- * @author Peter Kubica <peter@kubica.ch>
- * @author Ralph Krimmel <rkrimme1@gwdg.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Roland Tapken <roland@bitarbeiter.net>
- * @author root <root@localhost.localdomain>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -54,9 +15,15 @@ use OCA\User_LDAP\Exceptions\NoMoreResults;
use OCA\User_LDAP\Mapping\AbstractMapping;
use OCA\User_LDAP\User\Manager;
use OCA\User_LDAP\User\OfflineUser;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\HintException;
+use OCP\IAppConfig;
use OCP\IConfig;
+use OCP\IGroupManager;
use OCP\IUserManager;
+use OCP\Server;
+use OCP\User\Events\UserIdAssignedEvent;
+use OCP\Util;
use Psr\Log\LoggerInterface;
use function strlen;
use function substr;
@@ -69,10 +36,6 @@ use function substr;
class Access extends LDAPUtility {
public const UUID_ATTRIBUTES = ['entryuuid', 'nsuniqueid', 'objectguid', 'guid', 'ipauniqueid'];
- /** @var \OCA\User_LDAP\Connection */
- public $connection;
- /** @var Manager */
- public $userManager;
/**
* never ever check this var directly, always use getPagedSearchResultState
* @var ?bool
@@ -85,35 +48,21 @@ class Access extends LDAPUtility {
/** @var ?AbstractMapping */
protected $groupMapper;
- /**
- * @var \OCA\User_LDAP\Helper
- */
- private $helper;
- /** @var IConfig */
- private $config;
- /** @var IUserManager */
- private $ncUserManager;
- /** @var LoggerInterface */
- private $logger;
private string $lastCookie = '';
public function __construct(
- Connection $connection,
ILDAPWrapper $ldap,
- Manager $userManager,
- Helper $helper,
- IConfig $config,
- IUserManager $ncUserManager,
- LoggerInterface $logger
+ public Connection $connection,
+ public Manager $userManager,
+ private Helper $helper,
+ private IConfig $config,
+ private IUserManager $ncUserManager,
+ private LoggerInterface $logger,
+ private IAppConfig $appConfig,
+ private IEventDispatcher $dispatcher,
) {
parent::__construct($ldap);
- $this->connection = $connection;
- $this->userManager = $userManager;
$this->userManager->setLdapAccess($this);
- $this->helper = $helper;
- $this->config = $config;
- $this->ncUserManager = $ncUserManager;
- $this->logger = $logger;
}
/**
@@ -169,14 +118,64 @@ class Access extends LDAPUtility {
}
/**
+ * Reads several attributes for an LDAP record identified by a DN and a filter
+ * No support for ranged attributes.
+ *
+ * @param string $dn the record in question
+ * @param array $attrs the attributes that shall be retrieved
+ * if empty, just check the record's existence
+ * @param string $filter
+ * @return array|false an array of values on success or an empty
+ * array if $attr is empty, false otherwise
+ * @throws ServerNotAvailableException
+ */
+ public function readAttributes(string $dn, array $attrs, string $filter = 'objectClass=*'): array|false {
+ if (!$this->checkConnection()) {
+ $this->logger->warning(
+ 'No LDAP Connector assigned, access impossible for readAttribute.',
+ ['app' => 'user_ldap']
+ );
+ return false;
+ }
+ $cr = $this->connection->getConnectionResource();
+ $attrs = array_map(
+ fn (string $attr): string => mb_strtolower($attr, 'UTF-8'),
+ $attrs,
+ );
+
+ $values = [];
+ $record = $this->executeRead($dn, $attrs, $filter);
+ if (is_bool($record)) {
+ // when an exists request was run and it was successful, an empty
+ // array must be returned
+ return $record ? [] : false;
+ }
+
+ $result = [];
+ foreach ($attrs as $attr) {
+ $values = $this->extractAttributeValuesFromResult($record, $attr);
+ if (!empty($values)) {
+ $result[$attr] = $values;
+ }
+ }
+
+ if (!empty($result)) {
+ return $result;
+ }
+
+ $this->logger->debug('Requested attributes {attrs} not found for ' . $dn, ['app' => 'user_ldap', 'attrs' => $attrs]);
+ return false;
+ }
+
+ /**
* reads a given attribute for an LDAP record identified by a DN
*
* @param string $dn the record in question
* @param string $attr the attribute that shall be retrieved
- * if empty, just check the record's existence
+ * if empty, just check the record's existence
* @param string $filter
* @return array|false an array of values on success or an empty
- * array if $attr is empty, false otherwise
+ * array if $attr is empty, false otherwise
* @throws ServerNotAvailableException
*/
public function readAttribute(string $dn, string $attr, string $filter = 'objectClass=*') {
@@ -243,9 +242,9 @@ class Access extends LDAPUtility {
* returned data on a successful usual operation
* @throws ServerNotAvailableException
*/
- public function executeRead(string $dn, string $attribute, string $filter) {
+ public function executeRead(string $dn, string|array $attribute, string $filter) {
$dn = $this->helper->DNasBaseParameter($dn);
- $rr = @$this->invokeLDAPMethod('read', $dn, $filter, [$attribute]);
+ $rr = @$this->invokeLDAPMethod('read', $dn, $filter, (is_string($attribute) ? [$attribute] : $attribute));
if (!$this->ldap->isResource($rr)) {
if ($attribute !== '') {
//do not throw this message on userExists check, irritates
@@ -264,7 +263,7 @@ class Access extends LDAPUtility {
return false;
}
//LDAP attributes are not case sensitive
- $result = \OCP\Util::mb_array_change_key_case(
+ $result = Util::mb_array_change_key_case(
$this->invokeLDAPMethod('getAttributes', $er), MB_CASE_LOWER, 'UTF-8');
return $result;
@@ -307,20 +306,19 @@ class Access extends LDAPUtility {
* @return array If a range was detected with keys 'values', 'attributeName',
* 'attributeFull' and 'rangeHigh', otherwise empty.
*/
- public function extractRangeData($result, $attribute) {
+ public function extractRangeData(array $result, string $attribute): array {
$keys = array_keys($result);
foreach ($keys as $key) {
if ($key !== $attribute && str_starts_with((string)$key, $attribute)) {
$queryData = explode(';', (string)$key);
- if (str_starts_with($queryData[1], 'range=')) {
+ if (isset($queryData[1]) && str_starts_with($queryData[1], 'range=')) {
$high = substr($queryData[1], 1 + strpos($queryData[1], '-'));
- $data = [
+ return [
'values' => $result[$key],
'attributeName' => $queryData[0],
'attributeFull' => $key,
'rangeHigh' => $high,
];
- return $data;
}
}
}
@@ -343,10 +341,10 @@ class Access extends LDAPUtility {
$cr = $this->connection->getConnectionResource();
try {
// try PASSWD extended operation first
- return @$this->invokeLDAPMethod('exopPasswd', $userDN, '', $password) ||
- @$this->invokeLDAPMethod('modReplace', $userDN, $password);
+ return @$this->invokeLDAPMethod('exopPasswd', $userDN, '', $password)
+ || @$this->invokeLDAPMethod('modReplace', $userDN, $password);
} catch (ConstraintViolationException $e) {
- throw new HintException('Password change rejected.', \OCP\Util::getL10N('user_ldap')->t('Password change rejected. Hint: ') . $e->getMessage(), (int)$e->getCode());
+ throw new HintException('Password change rejected.', Util::getL10N('user_ldap')->t('Password change rejected. Hint: %s', $e->getMessage()), (int)$e->getCode());
}
}
@@ -440,10 +438,11 @@ class Access extends LDAPUtility {
*
* @param string $fdn the dn of the group object
* @param string $ldapName optional, the display name of the object
+ * @param bool $autoMapping Should the group be mapped if not yet mapped
* @return string|false with the name to use in Nextcloud, false on DN outside of search DN
* @throws \Exception
*/
- public function dn2groupname($fdn, $ldapName = null) {
+ public function dn2groupname($fdn, $ldapName = null, bool $autoMapping = true) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
@@ -451,7 +450,7 @@ class Access extends LDAPUtility {
return false;
}
- return $this->dn2ocname($fdn, $ldapName, false);
+ return $this->dn2ocname($fdn, $ldapName, false, autoMapping:$autoMapping);
}
/**
@@ -462,7 +461,7 @@ class Access extends LDAPUtility {
* @return string|false with with the name to use in Nextcloud
* @throws \Exception
*/
- public function dn2username($fdn, $ldapName = null) {
+ public function dn2username($fdn) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
@@ -470,7 +469,7 @@ class Access extends LDAPUtility {
return false;
}
- return $this->dn2ocname($fdn, $ldapName, true);
+ return $this->dn2ocname($fdn, null, true);
}
/**
@@ -481,10 +480,11 @@ class Access extends LDAPUtility {
* @param bool $isUser optional, whether it is a user object (otherwise group assumed)
* @param bool|null $newlyMapped
* @param array|null $record
+ * @param bool $autoMapping Should the group be mapped if not yet mapped
* @return false|string with with the name to use in Nextcloud
* @throws \Exception
*/
- public function dn2ocname($fdn, $ldapName = null, $isUser = true, &$newlyMapped = null, ?array $record = null) {
+ public function dn2ocname($fdn, $ldapName = null, $isUser = true, &$newlyMapped = null, ?array $record = null, bool $autoMapping = true) {
static $intermediates = [];
if (isset($intermediates[($isUser ? 'user-' : 'group-') . $fdn])) {
return false; // is a known intermediate
@@ -493,12 +493,8 @@ class Access extends LDAPUtility {
$newlyMapped = false;
if ($isUser) {
$mapper = $this->getUserMapper();
- $nameAttribute = $this->connection->ldapUserDisplayName;
- $filter = $this->connection->ldapUserFilter;
} else {
$mapper = $this->getGroupMapper();
- $nameAttribute = $this->connection->ldapGroupDisplayName;
- $filter = $this->connection->ldapGroupFilter;
}
//let's try to retrieve the Nextcloud name from the mappings table
@@ -507,6 +503,41 @@ class Access extends LDAPUtility {
return $ncName;
}
+ if (!$autoMapping) {
+ /* If no auto mapping, stop there */
+ return false;
+ }
+
+ if ($isUser) {
+ $nameAttribute = strtolower($this->connection->ldapUserDisplayName);
+ $filter = $this->connection->ldapUserFilter;
+ $uuidAttr = 'ldapUuidUserAttribute';
+ $uuidOverride = $this->connection->ldapExpertUUIDUserAttr;
+ $usernameAttribute = strtolower($this->connection->ldapExpertUsernameAttr);
+ $attributesToRead = [$nameAttribute,$usernameAttribute];
+ // TODO fetch also display name attributes and cache them if the user is mapped
+ } else {
+ $nameAttribute = strtolower($this->connection->ldapGroupDisplayName);
+ $filter = $this->connection->ldapGroupFilter;
+ $uuidAttr = 'ldapUuidGroupAttribute';
+ $uuidOverride = $this->connection->ldapExpertUUIDGroupAttr;
+ $attributesToRead = [$nameAttribute];
+ }
+
+ if ($this->detectUuidAttribute($fdn, $isUser, false, $record)) {
+ $attributesToRead[] = $this->connection->$uuidAttr;
+ }
+
+ if ($record === null) {
+ /* No record was passed, fetch it */
+ $record = $this->readAttributes($fdn, $attributesToRead, $filter);
+ if ($record === false) {
+ $this->logger->debug('Cannot read attributes for ' . $fdn . '. Skipping.', ['filter' => $filter]);
+ $intermediates[($isUser ? 'user-' : 'group-') . $fdn] = true;
+ return false;
+ }
+ }
+
//second try: get the UUID and check if it is known. Then, update the DN and return the name.
$uuid = $this->getUUID($fdn, $isUser, $record);
if (is_string($uuid)) {
@@ -521,20 +552,9 @@ class Access extends LDAPUtility {
return false;
}
- if (is_null($ldapName)) {
- $ldapName = $this->readAttribute($fdn, $nameAttribute, $filter);
- if (!isset($ldapName[0]) || empty($ldapName[0])) {
- $this->logger->debug('No or empty name for ' . $fdn . ' with filter ' . $filter . '.', ['app' => 'user_ldap']);
- $intermediates[($isUser ? 'user-' : 'group-') . $fdn] = true;
- return false;
- }
- $ldapName = $ldapName[0];
- }
-
if ($isUser) {
- $usernameAttribute = (string)$this->connection->ldapExpertUsernameAttr;
if ($usernameAttribute !== '') {
- $username = $this->readAttribute($fdn, $usernameAttribute);
+ $username = $record[$usernameAttribute];
if (!isset($username[0]) || empty($username[0])) {
$this->logger->debug('No or empty username (' . $usernameAttribute . ') for ' . $fdn . '.', ['app' => 'user_ldap']);
return false;
@@ -556,6 +576,15 @@ class Access extends LDAPUtility {
return false;
}
} else {
+ if (is_null($ldapName)) {
+ $ldapName = $record[$nameAttribute];
+ if (!isset($ldapName[0]) || empty($ldapName[0])) {
+ $this->logger->debug('No or empty name for ' . $fdn . ' with filter ' . $filter . '.', ['app' => 'user_ldap']);
+ $intermediates['group-' . $fdn] = true;
+ return false;
+ }
+ $ldapName = $ldapName[0];
+ }
$intName = $this->sanitizeGroupIDCandidate($ldapName);
}
@@ -567,12 +596,13 @@ class Access extends LDAPUtility {
$this->connection->setConfiguration(['ldapCacheTTL' => 0]);
if ($intName !== ''
&& (($isUser && !$this->ncUserManager->userExists($intName))
- || (!$isUser && !\OC::$server->getGroupManager()->groupExists($intName))
+ || (!$isUser && !Server::get(IGroupManager::class)->groupExists($intName))
)
) {
$this->connection->setConfiguration(['ldapCacheTTL' => $originalTTL]);
$newlyMapped = $this->mapAndAnnounceIfApplicable($mapper, $fdn, $intName, $uuid, $isUser);
if ($newlyMapped) {
+ $this->logger->debug('Mapped {fdn} as {name}', ['fdn' => $fdn,'name' => $intName]);
return $intName;
}
}
@@ -587,7 +617,6 @@ class Access extends LDAPUtility {
'fdn' => $fdn,
'altName' => $altName,
'intName' => $intName,
- 'app' => 'user_ldap',
]
);
$newlyMapped = true;
@@ -605,13 +634,16 @@ class Access extends LDAPUtility {
string $fdn,
string $name,
string $uuid,
- bool $isUser
+ bool $isUser,
): bool {
if ($mapper->map($fdn, $name, $uuid)) {
- if ($this->ncUserManager instanceof PublicEmitter && $isUser) {
+ if ($isUser) {
$this->cacheUserExists($name);
- $this->ncUserManager->emit('\OC\User', 'assignedUserId', [$name]);
- } elseif (!$isUser) {
+ $this->dispatcher->dispatchTyped(new UserIdAssignedEvent($name));
+ if ($this->ncUserManager instanceof PublicEmitter) {
+ $this->ncUserManager->emit('\OC\User', 'assignedUserId', [$name]);
+ }
+ } else {
$this->cacheGroupExists($name);
}
return true;
@@ -712,6 +744,7 @@ class Access extends LDAPUtility {
*/
public function cacheUserExists(string $ocName): void {
$this->connection->writeToCache('userExists' . $ocName, true);
+ $this->connection->writeToCache('userExistsOnLDAP' . $ocName, true);
}
/**
@@ -781,7 +814,7 @@ class Access extends LDAPUtility {
* "Developers"
*/
private function _createAltInternalOwnCloudNameForGroups(string $name) {
- $usedNames = $this->getGroupMapper()->getNamesBySearch($name, "", '_%');
+ $usedNames = $this->getGroupMapper()->getNamesBySearch($name, '', '_%');
if (count($usedNames) === 0) {
$lastNo = 1; //will become name_2
} else {
@@ -797,7 +830,7 @@ class Access extends LDAPUtility {
// Check to be really sure it is unique
// while loop is just a precaution. If a name is not generated within
// 20 attempts, something else is very wrong. Avoids infinite loop.
- if (!\OC::$server->getGroupManager()->groupExists($altName)) {
+ if (!Server::get(IGroupManager::class)->groupExists($altName)) {
return $altName;
}
$altName = $name . '_' . ($lastNo + $attempts);
@@ -861,8 +894,7 @@ class Access extends LDAPUtility {
$ldapRecords = $this->searchUsers($filter, $attr, $limit, $offset);
$recordsToUpdate = $ldapRecords;
if (!$forceApplyAttributes) {
- $isBackgroundJobModeAjax = $this->config
- ->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'ajax';
+ $isBackgroundJobModeAjax = $this->appConfig->getValueString('core', 'backgroundjobs_mode', 'ajax') === 'ajax';
$listOfDNs = array_reduce($ldapRecords, function ($listOfDNs, $entry) {
$listOfDNs[] = $entry['dn'][0];
return $listOfDNs;
@@ -926,22 +958,6 @@ class Access extends LDAPUtility {
}
$groupRecords = $this->searchGroups($filter, $attr, $limit, $offset);
- $listOfDNs = array_reduce($groupRecords, function ($listOfDNs, $entry) {
- $listOfDNs[] = $entry['dn'][0];
- return $listOfDNs;
- }, []);
- $idsByDn = $this->getGroupMapper()->getListOfIdsByDn($listOfDNs);
-
- array_walk($groupRecords, function (array $record) use ($idsByDn) {
- $newlyMapped = false;
- $gid = $idsByDn[$record['dn'][0]] ?? null;
- if ($gid === null) {
- $gid = $this->dn2ocname($record['dn'][0], null, false, $newlyMapped, $record);
- }
- if (!$newlyMapped && is_string($gid)) {
- $this->cacheGroupExists($gid);
- }
- });
$listOfGroups = $this->fetchList($groupRecords, $this->manyAttributes($attr));
$this->connection->writeToCache($cacheKey, $listOfGroups);
return $listOfGroups;
@@ -1088,7 +1104,7 @@ class Access extends LDAPUtility {
* @param int|null $limit optional, maximum results to be counted
* @param int|null $offset optional, a starting point
* @return array|false array with the search result as first value and pagedSearchOK as
- * second | false if not successful
+ * second | false if not successful
* @throws ServerNotAvailableException
*/
private function executeSearch(
@@ -1096,7 +1112,7 @@ class Access extends LDAPUtility {
string $base,
?array &$attr,
?int $pageSize,
- ?int $offset
+ ?int $offset,
) {
// See if we have a resource, in case not cancel with message
$cr = $this->connection->getConnectionResource();
@@ -1127,7 +1143,7 @@ class Access extends LDAPUtility {
* @param int $limit maximum results to be counted
* @param bool $pagedSearchOK whether a paged search has been executed
* @param bool $skipHandling required for paged search when cookies to
- * prior results need to be gained
+ * prior results need to be gained
* @return bool cookie validity, true if we have more pages, false otherwise.
* @throws ServerNotAvailableException
*/
@@ -1136,7 +1152,7 @@ class Access extends LDAPUtility {
int $foundItems,
int $limit,
bool $pagedSearchOK,
- bool $skipHandling
+ bool $skipHandling,
): bool {
$cookie = '';
if ($pagedSearchOK) {
@@ -1150,7 +1166,7 @@ class Access extends LDAPUtility {
return false;
}
// if count is bigger, then the server does not support
- // paged search. Instead, he did a normal search. We set a
+ // paged search. Instead, they did a normal search. We set a
// flag here, so the callee knows how to deal with it.
if ($foundItems <= $limit) {
$this->pagedSearchedSuccessful = true;
@@ -1177,11 +1193,11 @@ class Access extends LDAPUtility {
* @param string $filter the LDAP filter for the search
* @param array $bases an array containing the LDAP subtree(s) that shall be searched
* @param ?string[] $attr optional, array, one or more attributes that shall be
- * retrieved. Results will according to the order in the array.
+ * retrieved. Results will according to the order in the array.
* @param int $limit maximum results to be counted, 0 means no limit
* @param int $offset a starting point, defaults to 0
* @param bool $skipHandling indicates whether the pages search operation is
- * completed
+ * completed
* @return int|false Integer or false if the search could not be initialized
* @throws ServerNotAvailableException
*/
@@ -1191,7 +1207,7 @@ class Access extends LDAPUtility {
?array $attr = null,
int $limit = 0,
int $offset = 0,
- bool $skipHandling = false
+ bool $skipHandling = false,
) {
$this->logger->debug('Count filter: {filter}', [
'app' => 'user_ldap',
@@ -1256,7 +1272,7 @@ class Access extends LDAPUtility {
?array $attr = null,
?int $limit = null,
?int $offset = null,
- bool $skipHandling = false
+ bool $skipHandling = false,
): array {
$limitPerPage = (int)$this->connection->ldapPagingSize;
if (!is_null($limit) && $limit < $limitPerPage && $limit > 0) {
@@ -1307,7 +1323,7 @@ class Access extends LDAPUtility {
if (!is_array($item)) {
continue;
}
- $item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
+ $item = Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
foreach ($attr as $key) {
if (isset($item[$key])) {
if (is_array($item[$key]) && isset($item[$key]['count'])) {
@@ -1427,7 +1443,7 @@ class Access extends LDAPUtility {
*
* @param string[] $filters the filters to connect
* @return string the combined filter
- * Combines Filter arguments with OR
+ * Combines Filter arguments with OR
*/
public function combineFilterWithOr($filters) {
return $this->combineFilter($filters, '|');
@@ -1482,7 +1498,7 @@ class Access extends LDAPUtility {
*
* @param string $search the search term
* @param string[]|null|'' $searchAttributes needs to have at least two attributes,
- * otherwise it does not make sense :)
+ * otherwise it does not make sense :)
* @return string the final filter part to use in LDAP searches
* @throws DomainException
*/
@@ -1510,7 +1526,7 @@ class Access extends LDAPUtility {
* @param string $search the search term
* @param string[]|null|'' $searchAttributes
* @param string $fallbackAttribute a fallback attribute in case the user
- * did not define search attributes. Typically the display name attribute.
+ * did not define search attributes. Typically the display name attribute.
* @return string the final filter part to use in LDAP searches
*/
private function getFilterPartForSearch(string $search, $searchAttributes, string $fallbackAttribute): string {
@@ -1556,7 +1572,7 @@ class Access extends LDAPUtility {
* a *
*/
private function prepareSearchTerm(string $term): string {
- $config = \OC::$server->getConfig();
+ $config = Server::get(IConfig::class);
$allowEnum = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes');
@@ -1795,8 +1811,8 @@ class Access extends LDAPUtility {
* user. Instead we write a log message.
*/
$this->logger->info(
- 'Passed string does not resemble a valid GUID. Known UUID ' .
- '({uuid}) probably does not match UUID configuration.',
+ 'Passed string does not resemble a valid GUID. Known UUID '
+ . '({uuid}) probably does not match UUID configuration.',
['app' => 'user_ldap', 'uuid' => $guid]
);
return $guid;
@@ -1961,7 +1977,7 @@ class Access extends LDAPUtility {
string $base,
?array $attr,
int $pageSize,
- int $offset
+ int $offset,
): array {
$pagedSearchOK = false;
if ($pageSize !== 0) {
diff --git a/apps/user_ldap/lib/AccessFactory.php b/apps/user_ldap/lib/AccessFactory.php
index 693f7e8ba12..da114c467a7 100644
--- a/apps/user_ldap/lib/AccessFactory.php
+++ b/apps/user_ldap/lib/AccessFactory.php
@@ -1,64 +1,44 @@
<?php
+
/**
- * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
use OCA\User_LDAP\User\Manager;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IUserManager;
use OCP\Server;
use Psr\Log\LoggerInterface;
class AccessFactory {
- private ILDAPWrapper $ldap;
- private Helper $helper;
- private IConfig $config;
- private IUserManager $ncUserManager;
- private LoggerInterface $logger;
public function __construct(
- ILDAPWrapper $ldap,
- Helper $helper,
- IConfig $config,
- IUserManager $ncUserManager,
- LoggerInterface $logger) {
- $this->ldap = $ldap;
- $this->helper = $helper;
- $this->config = $config;
- $this->ncUserManager = $ncUserManager;
- $this->logger = $logger;
+ private ILDAPWrapper $ldap,
+ private Helper $helper,
+ private IConfig $config,
+ private IAppConfig $appConfig,
+ private IUserManager $ncUserManager,
+ private LoggerInterface $logger,
+ private IEventDispatcher $dispatcher,
+ ) {
}
public function get(Connection $connection): Access {
/* Each Access instance gets its own Manager instance, see OCA\User_LDAP\AppInfo\Application::register() */
return new Access(
- $connection,
$this->ldap,
+ $connection,
Server::get(Manager::class),
$this->helper,
$this->config,
$this->ncUserManager,
- $this->logger
+ $this->logger,
+ $this->appConfig,
+ $this->dispatcher,
);
}
}
diff --git a/apps/user_ldap/lib/AppInfo/Application.php b/apps/user_ldap/lib/AppInfo/Application.php
index 4d8a11caf3c..70b7920f7ab 100644
--- a/apps/user_ldap/lib/AppInfo/Application.php
+++ b/apps/user_ldap/lib/AppInfo/Application.php
@@ -1,28 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Roger Szabo <roger.szabo@web.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\AppInfo;
@@ -31,7 +11,6 @@ use OCA\Files_External\Service\BackendService;
use OCA\User_LDAP\Controller\RenewPasswordController;
use OCA\User_LDAP\Events\GroupBackendRegistered;
use OCA\User_LDAP\Events\UserBackendRegistered;
-use OCA\User_LDAP\FilesystemHelper;
use OCA\User_LDAP\Group_Proxy;
use OCA\User_LDAP\GroupPluginManager;
use OCA\User_LDAP\Handler\ExtStorageConfigHandler;
@@ -61,6 +40,7 @@ use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use OCP\Share\IManager as IShareManager;
use OCP\User\Events\PostLoginEvent;
+use OCP\Util;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
@@ -105,7 +85,6 @@ class Application extends App implements IBootstrap {
function (ContainerInterface $c) {
return new Manager(
$c->get(IConfig::class),
- $c->get(FilesystemHelper::class),
$c->get(LoggerInterface::class),
$c->get(IAvatarManager::class),
$c->get(Image::class),
@@ -127,17 +106,18 @@ class Application extends App implements IBootstrap {
INotificationManager $notificationManager,
IAppContainer $appContainer,
IEventDispatcher $dispatcher,
+ IUserManager $userManager,
IGroupManager $groupManager,
User_Proxy $userBackend,
Group_Proxy $groupBackend,
- Helper $helper
- ) {
+ Helper $helper,
+ ): void {
$configPrefixes = $helper->getServerConfigurationPrefixes(true);
if (count($configPrefixes) > 0) {
$userPluginManager = $appContainer->get(UserPluginManager::class);
$groupPluginManager = $appContainer->get(GroupPluginManager::class);
- \OC_User::useBackend($userBackend);
+ $userManager->registerBackend($userBackend);
$groupManager->addBackend($groupBackend);
$userBackendRegisteredEvent = new UserBackendRegistered($userBackend, $userPluginManager);
@@ -150,7 +130,7 @@ class Application extends App implements IBootstrap {
$context->injectFn(Closure::fromCallable([$this, 'registerBackendDependents']));
- \OCP\Util::connectHook(
+ Util::connectHook(
'\OCA\Files_Sharing\API\Server2Server',
'preLoginNameUsedAsUserName',
'\OCA\User_LDAP\Helper',
@@ -161,7 +141,7 @@ class Application extends App implements IBootstrap {
private function registerBackendDependents(IAppContainer $appContainer, IEventDispatcher $dispatcher): void {
$dispatcher->addListener(
'OCA\\Files_External::loadAdditionalBackends',
- function () use ($appContainer) {
+ function () use ($appContainer): void {
$storagesBackendService = $appContainer->get(BackendService::class);
$storagesBackendService->registerConfigHandler('home', function () use ($appContainer) {
return $appContainer->get(ExtStorageConfigHandler::class);
diff --git a/apps/user_ldap/lib/BackendUtility.php b/apps/user_ldap/lib/BackendUtility.php
index 4afcb6799d8..88d7311cde0 100644
--- a/apps/user_ldap/lib/BackendUtility.php
+++ b/apps/user_ldap/lib/BackendUtility.php
@@ -1,37 +1,19 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
abstract class BackendUtility {
- protected $access;
-
/**
* constructor, make sure the subclasses call this one!
* @param Access $access an instance of Access for LDAP interaction
*/
- public function __construct(Access $access) {
- $this->access = $access;
+ public function __construct(
+ protected Access $access,
+ ) {
}
}
diff --git a/apps/user_ldap/lib/Command/CheckGroup.php b/apps/user_ldap/lib/Command/CheckGroup.php
index 0a9aff55fc9..9c7ccb9d3b3 100644
--- a/apps/user_ldap/lib/Command/CheckGroup.php
+++ b/apps/user_ldap/lib/Command/CheckGroup.php
@@ -3,29 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Command;
@@ -120,25 +99,25 @@ class CheckGroup extends Command {
throw new \Exception('The given group is not a recognized LDAP group.');
} catch (\Exception $e) {
- $output->writeln('<error>' . $e->getMessage(). '</error>');
+ $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>');
+ $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>');
+ $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>');
+ $output->writeln('<info>The user ' . $user->getUID() . ' was removed from group ' . $group->getGID() . '</info>');
}
/**
diff --git a/apps/user_ldap/lib/Command/CheckUser.php b/apps/user_ldap/lib/Command/CheckUser.php
index 4e9fefd9b55..8bb26ce3d0e 100644
--- a/apps/user_ldap/lib/Command/CheckUser.php
+++ b/apps/user_ldap/lib/Command/CheckUser.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
@@ -37,15 +18,12 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CheckUser extends Command {
- protected User_Proxy $backend;
-
public function __construct(
- User_Proxy $uBackend,
+ protected User_Proxy $backend,
protected Helper $helper,
protected DeletedUsersIndex $dui,
protected UserMapping $mapping,
) {
- $this->backend = $uBackend;
parent::__construct();
}
@@ -103,7 +81,7 @@ class CheckUser extends Command {
throw new \Exception('The given user is not a recognized LDAP user.');
} catch (\Exception $e) {
- $output->writeln('<error>' . $e->getMessage(). '</error>');
+ $output->writeln('<error>' . $e->getMessage() . '</error>');
return self::FAILURE;
}
}
diff --git a/apps/user_ldap/lib/Command/CreateEmptyConfig.php b/apps/user_ldap/lib/Command/CreateEmptyConfig.php
index b9cc50fb09b..7c381cf431f 100644
--- a/apps/user_ldap/lib/Command/CreateEmptyConfig.php
+++ b/apps/user_ldap/lib/Command/CreateEmptyConfig.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Martin Konrad <konrad@frib.msu.edu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/DeleteConfig.php b/apps/user_ldap/lib/Command/DeleteConfig.php
index b2a8e3fa484..7604e229bed 100644
--- a/apps/user_ldap/lib/Command/DeleteConfig.php
+++ b/apps/user_ldap/lib/Command/DeleteConfig.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Martin Konrad <info@martin-konrad.net>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/PromoteGroup.php b/apps/user_ldap/lib/Command/PromoteGroup.php
index 7ec18064332..b203a910b14 100644
--- a/apps/user_ldap/lib/Command/PromoteGroup.php
+++ b/apps/user_ldap/lib/Command/PromoteGroup.php
@@ -2,25 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Command;
@@ -39,7 +22,7 @@ class PromoteGroup extends Command {
public function __construct(
private IGroupManager $groupManager,
- private Group_Proxy $backend
+ private Group_Proxy $backend,
) {
parent::__construct();
}
diff --git a/apps/user_ldap/lib/Command/ResetGroup.php b/apps/user_ldap/lib/Command/ResetGroup.php
index 1588e8b0e0d..5833ca980f2 100644
--- a/apps/user_ldap/lib/Command/ResetGroup.php
+++ b/apps/user_ldap/lib/Command/ResetGroup.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/ResetUser.php b/apps/user_ldap/lib/Command/ResetUser.php
index 4224c9ff7a6..1409806e4ac 100644
--- a/apps/user_ldap/lib/Command/ResetUser.php
+++ b/apps/user_ldap/lib/Command/ResetUser.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/Search.php b/apps/user_ldap/lib/Command/Search.php
index 0aba7581d4b..85906b20e9a 100644
--- a/apps/user_ldap/lib/Command/Search.php
+++ b/apps/user_ldap/lib/Command/Search.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
@@ -31,6 +12,7 @@ use OCA\User_LDAP\Helper;
use OCA\User_LDAP\LDAP;
use OCA\User_LDAP\User_Proxy;
use OCP\IConfig;
+use OCP\Server;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -100,7 +82,7 @@ class Search extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output): int {
- $helper = new Helper($this->ocConfig, \OC::$server->getDatabaseConnection());
+ $helper = Server::get(Helper::class);
$configPrefixes = $helper->getServerConfigurationPrefixes(true);
$ldapWrapper = new LDAP();
@@ -125,7 +107,7 @@ class Search extends Command {
$result = $proxy->$getMethod($input->getArgument('search'), $limit, $offset);
foreach ($result as $id => $name) {
- $line = $name . ($printID ? ' ('.$id.')' : '');
+ $line = $name . ($printID ? ' (' . $id . ')' : '');
$output->writeln($line);
}
return self::SUCCESS;
diff --git a/apps/user_ldap/lib/Command/SetConfig.php b/apps/user_ldap/lib/Command/SetConfig.php
index 37b18fa8107..7e9efcf34d0 100644
--- a/apps/user_ldap/lib/Command/SetConfig.php
+++ b/apps/user_ldap/lib/Command/SetConfig.php
@@ -1,27 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
@@ -29,6 +11,7 @@ use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\ConnectionFactory;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\LDAP;
+use OCP\Server;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@@ -58,11 +41,11 @@ class SetConfig extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output): int {
- $helper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
+ $helper = Server::get(Helper::class);
$availableConfigs = $helper->getServerConfigurationPrefixes();
$configID = $input->getArgument('configID');
if (!in_array($configID, $availableConfigs)) {
- $output->writeln("Invalid configID");
+ $output->writeln('Invalid configID');
return self::FAILURE;
}
diff --git a/apps/user_ldap/lib/Command/ShowConfig.php b/apps/user_ldap/lib/Command/ShowConfig.php
index 0aae70205d5..fa021192ac4 100644
--- a/apps/user_ldap/lib/Command/ShowConfig.php
+++ b/apps/user_ldap/lib/Command/ShowConfig.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Johannes Leuker <j.leuker@hosting.de>
- * @author Laurens Post <Crote@users.noreply.github.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
@@ -73,7 +54,7 @@ class ShowConfig extends Base {
if (!is_null($configID)) {
$configIDs[] = $configID;
if (!in_array($configIDs[0], $availableConfigs)) {
- $output->writeln("Invalid configID");
+ $output->writeln('Invalid configID');
return self::FAILURE;
}
} else {
diff --git a/apps/user_ldap/lib/Command/ShowRemnants.php b/apps/user_ldap/lib/Command/ShowRemnants.php
index df74f73d965..d255aac1368 100644
--- a/apps/user_ldap/lib/Command/ShowRemnants.php
+++ b/apps/user_ldap/lib/Command/ShowRemnants.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author scolebrook <scolebrook@mac.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/TestConfig.php b/apps/user_ldap/lib/Command/TestConfig.php
index 17f73fdea81..77eaac91d85 100644
--- a/apps/user_ldap/lib/Command/TestConfig.php
+++ b/apps/user_ldap/lib/Command/TestConfig.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Command;
diff --git a/apps/user_ldap/lib/Command/TestUserSettings.php b/apps/user_ldap/lib/Command/TestUserSettings.php
new file mode 100644
index 00000000000..12690158f98
--- /dev/null
+++ b/apps/user_ldap/lib/Command/TestUserSettings.php
@@ -0,0 +1,248 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+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\Mapping\UserMapping;
+use OCA\User_LDAP\User\DeletedUsersIndex;
+use OCA\User_LDAP\User_Proxy;
+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 TestUserSettings extends Command {
+ public function __construct(
+ protected User_Proxy $backend,
+ protected Group_Proxy $groupBackend,
+ protected Helper $helper,
+ protected DeletedUsersIndex $dui,
+ protected UserMapping $mapping,
+ protected GroupMapping $groupMapping,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('ldap:test-user-settings')
+ ->setDescription('Runs tests and show information about user related LDAP settings')
+ ->addArgument(
+ 'user',
+ InputArgument::REQUIRED,
+ 'the user name as used in Nextcloud, or the LDAP DN'
+ )
+ ->addOption(
+ 'group',
+ 'g',
+ InputOption::VALUE_REQUIRED,
+ 'A group DN to check if the user is a member or not'
+ )
+ ->addOption(
+ 'clearcache',
+ null,
+ InputOption::VALUE_NONE,
+ 'Clear the cache of the LDAP connection before the beginning of tests'
+ )
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ try {
+ $uid = $input->getArgument('user');
+ $access = $this->backend->getLDAPAccess($uid);
+ $connection = $access->getConnection();
+ if ($input->getOption('clearcache')) {
+ $connection->clearCache();
+ }
+ $configPrefix = $connection->getConfigPrefix();
+ $knownDn = '';
+ if ($access->stringResemblesDN($uid)) {
+ $knownDn = $uid;
+ $username = $access->dn2username($uid);
+ if ($username !== false) {
+ $uid = $username;
+ }
+ }
+
+ $dn = $this->mapping->getDNByName($uid);
+ if ($dn !== false) {
+ $output->writeln("User <info>$dn</info> is mapped with account name <info>$uid</info>.");
+ $uuid = $this->mapping->getUUIDByDN($dn);
+ $output->writeln("Known UUID is <info>$uuid</info>.");
+ if ($knownDn === '') {
+ $knownDn = $dn;
+ }
+ } else {
+ $output->writeln("User <info>$uid</info> is not mapped.");
+ }
+
+ if ($knownDn === '') {
+ return self::SUCCESS;
+ }
+
+ if (!$access->isDNPartOfBase($knownDn, $access->getConnection()->ldapBaseUsers)) {
+ $output->writeln(
+ "User <info>$knownDn</info> is not in one of the configured user bases: <info>"
+ . implode(',', $access->getConnection()->ldapBaseUsers)
+ . '</info>.'
+ );
+ }
+
+ $output->writeln("Configuration prefix is <info>$configPrefix</info>");
+ $output->writeln('');
+
+ $attributeNames = [
+ 'ldapBase',
+ 'ldapBaseUsers',
+ 'ldapExpertUsernameAttr',
+ 'ldapUuidUserAttribute',
+ 'ldapExpertUUIDUserAttr',
+ 'ldapQuotaAttribute',
+ 'ldapEmailAttribute',
+ 'ldapUserDisplayName',
+ 'ldapUserDisplayName2',
+ 'ldapExtStorageHomeAttribute',
+ 'ldapAttributePhone',
+ 'ldapAttributeWebsite',
+ 'ldapAttributeAddress',
+ 'ldapAttributeTwitter',
+ 'ldapAttributeFediverse',
+ 'ldapAttributeOrganisation',
+ 'ldapAttributeRole',
+ 'ldapAttributeHeadline',
+ 'ldapAttributeBiography',
+ 'ldapAttributeBirthDate',
+ 'ldapAttributePronouns',
+ 'ldapGidNumber',
+ 'hasGidNumber',
+ ];
+ $output->writeln('Attributes set in configuration:');
+ foreach ($attributeNames as $attributeName) {
+ if (($connection->$attributeName !== '') && ($connection->$attributeName !== [])) {
+ if (\is_string($connection->$attributeName)) {
+ $output->writeln("- $attributeName: <info>" . $connection->$attributeName . '</info>');
+ } else {
+ $output->writeln("- $attributeName: <info>" . \json_encode($connection->$attributeName) . '</info>');
+ }
+ }
+ }
+
+ $filter = $connection->ldapUserFilter;
+ $attrs = $access->userManager->getAttributes(true);
+ $attrs[] = strtolower($connection->ldapExpertUsernameAttr);
+ if ($connection->ldapUuidUserAttribute !== 'auto') {
+ $attrs[] = strtolower($connection->ldapUuidUserAttribute);
+ }
+ if ($connection->hasGidNumber) {
+ $attrs[] = strtolower($connection->ldapGidNumber);
+ }
+ $attrs[] = 'memberof';
+ $attrs = array_values(array_unique($attrs));
+ $attributes = $access->readAttributes($knownDn, $attrs, $filter);
+
+ if ($attributes === false) {
+ $output->writeln(
+ "LDAP read on <info>$knownDn</info> with filter <info>$filter</info> failed."
+ );
+ return self::FAILURE;
+ }
+
+ $output->writeln("Attributes fetched from LDAP using filter <info>$filter</info>:");
+ foreach ($attributes as $attribute => $value) {
+ $output->writeln(
+ "- $attribute: <info>" . json_encode($value) . '</info>'
+ );
+ }
+
+ $uuid = $access->getUUID($knownDn);
+ if ($connection->ldapUuidUserAttribute === 'auto') {
+ $output->writeln('<error>Failed to detect UUID attribute</error>');
+ } else {
+ $output->writeln('Detected UUID attribute: <info>' . $connection->ldapUuidUserAttribute . '</info>');
+ }
+ if ($uuid === false) {
+ $output->writeln("<error>Failed to find UUID for $knownDn</error>");
+ } else {
+ $output->writeln("UUID for <info>$knownDn</info>: <info>$uuid</info>");
+ }
+
+ $groupLdapInstance = $this->groupBackend->getBackend($configPrefix);
+
+ $output->writeln('');
+ $output->writeln('Group information:');
+
+ $attributeNames = [
+ 'ldapBaseGroups',
+ 'ldapDynamicGroupMemberURL',
+ 'ldapGroupFilter',
+ 'ldapGroupMemberAssocAttr',
+ ];
+ $output->writeln('Configuration:');
+ foreach ($attributeNames as $attributeName) {
+ if ($connection->$attributeName !== '') {
+ $output->writeln("- $attributeName: <info>" . $connection->$attributeName . '</info>');
+ }
+ }
+
+ $primaryGroup = $groupLdapInstance->getUserPrimaryGroup($knownDn);
+ $output->writeln('Primary group: <info>' . ($primaryGroup !== false? $primaryGroup:'') . '</info>');
+
+ $groupByGid = $groupLdapInstance->getUserGroupByGid($knownDn);
+ $output->writeln('Group from gidNumber: <info>' . ($groupByGid !== false? $groupByGid:'') . '</info>');
+
+ $groups = $groupLdapInstance->getUserGroups($uid);
+ $output->writeln('All known groups: <info>' . json_encode($groups) . '</info>');
+
+ $memberOfUsed = ((int)$access->connection->hasMemberOfFilterSupport === 1
+ && (int)$access->connection->useMemberOfToDetectMembership === 1);
+
+ $output->writeln('MemberOf usage: <info>' . ($memberOfUsed ? 'on' : 'off') . '</info> (' . $access->connection->hasMemberOfFilterSupport . ',' . $access->connection->useMemberOfToDetectMembership . ')');
+
+ $gid = (string)$input->getOption('group');
+ if ($gid === '') {
+ return self::SUCCESS;
+ }
+
+ $output->writeln('');
+ $output->writeln("Group $gid:");
+ $knownGroupDn = '';
+ if ($access->stringResemblesDN($gid)) {
+ $knownGroupDn = $gid;
+ $groupname = $access->dn2groupname($gid);
+ if ($groupname !== false) {
+ $gid = $groupname;
+ }
+ }
+
+ $groupDn = $this->groupMapping->getDNByName($gid);
+ if ($groupDn !== false) {
+ $output->writeln("Group <info>$groupDn</info> is mapped with name <info>$gid</info>.");
+ $groupUuid = $this->groupMapping->getUUIDByDN($groupDn);
+ $output->writeln("Known UUID is <info>$groupUuid</info>.");
+ if ($knownGroupDn === '') {
+ $knownGroupDn = $groupDn;
+ }
+ } else {
+ $output->writeln("Group <info>$gid</info> is not mapped.");
+ }
+
+ $members = $groupLdapInstance->usersInGroup($gid);
+ $output->writeln('Members: <info>' . json_encode($members) . '</info>');
+
+ return self::SUCCESS;
+
+ } catch (\Exception $e) {
+ $output->writeln('<error>' . $e->getMessage() . '</error>');
+ return self::FAILURE;
+ }
+ }
+}
diff --git a/apps/user_ldap/lib/Command/UpdateUUID.php b/apps/user_ldap/lib/Command/UpdateUUID.php
index a89b068c726..93dcc37bada 100644
--- a/apps/user_ldap/lib/Command/UpdateUUID.php
+++ b/apps/user_ldap/lib/Command/UpdateUUID.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Command;
@@ -284,7 +266,7 @@ class UpdateUUID extends Command {
protected function handleMappingBasedUpdates(bool $invalidatedOnly): \Generator {
$limit = 1000;
- /** @var AbstractMapping $mapping*/
+ /** @var AbstractMapping $mapping */
foreach ([$this->userMapping, $this->groupMapping] as $mapping) {
$offset = 0;
do {
diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php
index b0bb600cb3b..b4a5b847204 100644
--- a/apps/user_ldap/lib/Configuration.php
+++ b/apps/user_ldap/lib/Configuration.php
@@ -1,45 +1,89 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Alexander Bergolth <leo@strike.wu.ac.at>
- * @author Alex Weirig <alex.weirig@technolink.lu>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lennart Rosam <hello@takuto.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Marc Hefter <marchefter@march42.net>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Xuanwo <xuanwo@yunify.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
+use OCP\IConfig;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
- * @property int ldapPagingSize holds an integer
- * @property string ldapUserAvatarRule
+ * @property string $ldapHost
+ * @property string $ldapPort
+ * @property string $ldapBackupHost
+ * @property string $ldapBackupPort
+ * @property string $ldapBackgroundHost
+ * @property string $ldapBackgroundPort
+ * @property array|'' $ldapBase
+ * @property array|'' $ldapBaseUsers
+ * @property array|'' $ldapBaseGroups
+ * @property string $ldapAgentName
+ * @property string $ldapAgentPassword
+ * @property string $ldapTLS
+ * @property string $turnOffCertCheck
+ * @property string $ldapIgnoreNamingRules
+ * @property string $ldapUserDisplayName
+ * @property string $ldapUserDisplayName2
+ * @property string $ldapUserAvatarRule
+ * @property string $ldapGidNumber
+ * @property array|'' $ldapUserFilterObjectclass
+ * @property array|'' $ldapUserFilterGroups
+ * @property string $ldapUserFilter
+ * @property string $ldapUserFilterMode
+ * @property string $ldapGroupFilter
+ * @property string $ldapGroupFilterMode
+ * @property array|'' $ldapGroupFilterObjectclass
+ * @property array|'' $ldapGroupFilterGroups
+ * @property string $ldapGroupDisplayName
+ * @property string $ldapGroupMemberAssocAttr
+ * @property string $ldapLoginFilter
+ * @property string $ldapLoginFilterMode
+ * @property string $ldapLoginFilterEmail
+ * @property string $ldapLoginFilterUsername
+ * @property array|'' $ldapLoginFilterAttributes
+ * @property string $ldapQuotaAttribute
+ * @property string $ldapQuotaDefault
+ * @property string $ldapEmailAttribute
+ * @property string $ldapCacheTTL
+ * @property string $ldapUuidUserAttribute
+ * @property string $ldapUuidGroupAttribute
+ * @property string $ldapOverrideMainServer
+ * @property string $ldapConfigurationActive
+ * @property array|'' $ldapAttributesForUserSearch
+ * @property array|'' $ldapAttributesForGroupSearch
+ * @property string $ldapExperiencedAdmin
+ * @property string $homeFolderNamingRule
+ * @property string $hasMemberOfFilterSupport
+ * @property string $useMemberOfToDetectMembership
+ * @property string $ldapExpertUsernameAttr
+ * @property string $ldapExpertUUIDUserAttr
+ * @property string $ldapExpertUUIDGroupAttr
+ * @property string $markRemnantsAsDisabled
+ * @property string $lastJpegPhotoLookup
+ * @property string $ldapNestedGroups
+ * @property string $ldapPagingSize
+ * @property string $turnOnPasswordChange
+ * @property string $ldapDynamicGroupMemberURL
+ * @property string $ldapDefaultPPolicyDN
+ * @property string $ldapExtStorageHomeAttribute
+ * @property string $ldapMatchingRuleInChainState
+ * @property string $ldapConnectionTimeout
+ * @property string $ldapAttributePhone
+ * @property string $ldapAttributeWebsite
+ * @property string $ldapAttributeAddress
+ * @property string $ldapAttributeTwitter
+ * @property string $ldapAttributeFediverse
+ * @property string $ldapAttributeOrganisation
+ * @property string $ldapAttributeRole
+ * @property string $ldapAttributeHeadline
+ * @property string $ldapAttributeBiography
+ * @property string $ldapAdminGroup
+ * @property string $ldapAttributeBirthDate
+ * @property string $ldapAttributePronouns
*/
class Configuration {
public const AVATAR_PREFIX_DEFAULT = 'default';
@@ -49,11 +93,6 @@ class Configuration {
public const LDAP_SERVER_FEATURE_UNKNOWN = 'unknown';
public const LDAP_SERVER_FEATURE_AVAILABLE = 'available';
public const LDAP_SERVER_FEATURE_UNAVAILABLE = 'unavailable';
-
- /**
- * @var string
- */
- protected $configPrefix;
/**
* @var bool
*/
@@ -137,10 +176,15 @@ class Configuration {
'ldapAttributeHeadline' => null,
'ldapAttributeBiography' => null,
'ldapAdminGroup' => '',
+ 'ldapAttributeBirthDate' => null,
+ 'ldapAttributeAnniversaryDate' => null,
+ 'ldapAttributePronouns' => null,
];
- public function __construct(string $configPrefix, bool $autoRead = true) {
- $this->configPrefix = $configPrefix;
+ public function __construct(
+ protected string $configPrefix,
+ bool $autoRead = true,
+ ) {
if ($autoRead) {
$this->readConfiguration();
}
@@ -174,7 +218,7 @@ class Configuration {
* from configuration. It does not save the configuration! To do so, you
* must call saveConfiguration afterwards.
* @param array $config array that holds the config parameters in an associated
- * array
+ * array
* @param array &$applied optional; array where the set fields will be given to
*/
public function setConfiguration(array $config, ?array &$applied = null): void {
@@ -196,7 +240,7 @@ class Configuration {
case 'homeFolderNamingRule':
$trimmedVal = trim($val);
if ($trimmedVal !== '' && !str_contains($val, 'attr:')) {
- $val = 'attr:'.$trimmedVal;
+ $val = 'attr:' . $trimmedVal;
}
break;
case 'ldapBase':
@@ -252,6 +296,28 @@ class Configuration {
break;
case 'ldapUserDisplayName2':
case 'ldapGroupDisplayName':
+ case 'ldapGidNumber':
+ case 'ldapGroupMemberAssocAttr':
+ case 'ldapQuotaAttribute':
+ case 'ldapEmailAttribute':
+ case 'ldapUuidUserAttribute':
+ case 'ldapUuidGroupAttribute':
+ case 'ldapExpertUsernameAttr':
+ case 'ldapExpertUUIDUserAttr':
+ case 'ldapExpertUUIDGroupAttr':
+ case 'ldapExtStorageHomeAttribute':
+ case 'ldapAttributePhone':
+ case 'ldapAttributeWebsite':
+ case 'ldapAttributeAddress':
+ case 'ldapAttributeTwitter':
+ case 'ldapAttributeFediverse':
+ case 'ldapAttributeOrganisation':
+ case 'ldapAttributeRole':
+ case 'ldapAttributeHeadline':
+ case 'ldapAttributeBiography':
+ case 'ldapAttributeBirthDate':
+ case 'ldapAttributeAnniversaryDate':
+ case 'ldapAttributePronouns':
$readMethod = 'getLcValue';
break;
case 'ldapUserDisplayName':
@@ -374,7 +440,7 @@ class Configuration {
protected function getSystemValue(string $varName): string {
//FIXME: if another system value is added, softcode the default value
- return \OC::$server->getConfig()->getSystemValue($varName, false);
+ return Server::get(IConfig::class)->getSystemValue($varName, false);
}
protected function getValue(string $varName): string {
@@ -382,8 +448,8 @@ class Configuration {
if (is_null($defaults)) {
$defaults = $this->getDefaults();
}
- return \OC::$server->getConfig()->getAppValue('user_ldap',
- $this->configPrefix.$varName,
+ return Server::get(IConfig::class)->getAppValue('user_ldap',
+ $this->configPrefix . $varName,
$defaults[$varName]);
}
@@ -411,9 +477,9 @@ class Configuration {
}
protected function saveValue(string $varName, string $value): bool {
- \OC::$server->getConfig()->setAppValue(
+ Server::get(IConfig::class)->setAppValue(
'user_ldap',
- $this->configPrefix.$varName,
+ $this->configPrefix . $varName,
$value
);
return true;
@@ -421,7 +487,7 @@ class Configuration {
/**
* @return array an associative array with the default values. Keys are correspond
- * to config-value entries in the database table
+ * to config-value entries in the database table
*/
public function getDefaults(): array {
return [
@@ -494,6 +560,9 @@ class Configuration {
'ldap_attr_headline' => '',
'ldap_attr_biography' => '',
'ldap_admin_group' => '',
+ 'ldap_attr_birthdate' => '',
+ 'ldap_attr_anniversarydate' => '',
+ 'ldap_attr_pronouns' => '',
];
}
@@ -571,6 +640,9 @@ class Configuration {
'ldap_attr_headline' => 'ldapAttributeHeadline',
'ldap_attr_biography' => 'ldapAttributeBiography',
'ldap_admin_group' => 'ldapAdminGroup',
+ 'ldap_attr_birthdate' => 'ldapAttributeBirthDate',
+ 'ldap_attr_anniversarydate' => 'ldapAttributeAnniversaryDate',
+ 'ldap_attr_pronouns' => 'ldapAttributePronouns',
];
return $array;
}
@@ -600,7 +672,7 @@ class Configuration {
return [strtolower($attribute)];
}
if ($value !== self::AVATAR_PREFIX_DEFAULT) {
- \OCP\Server::get(LoggerInterface::class)->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
+ Server::get(LoggerInterface::class)->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
}
return $defaultAttributes;
}
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index 7c780ccbb4a..336179ac341 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -1,94 +1,100 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Jarkko Lehtoranta <devel@jlranta.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author root <root@localhost.localdomain>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Xuanwo <xuanwo@yunify.com>
- * @author Vincent Van Houtte <vvh@aplusv.be>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
use OC\ServerNotAvailableException;
+use OCA\User_LDAP\Exceptions\ConfigurationIssueException;
+use OCP\ICache;
+use OCP\ICacheFactory;
+use OCP\IL10N;
+use OCP\Server;
+use OCP\Util;
use Psr\Log\LoggerInterface;
/**
- * magic properties (incomplete)
+ * magic properties
* responsible for LDAP connections in context with the provided configuration
*
- * @property string ldapHost
- * @property string ldapPort holds the port number
- * @property string ldapUserFilter
- * @property string ldapUserDisplayName
- * @property string ldapUserDisplayName2
- * @property string ldapUserAvatarRule
- * @property boolean turnOnPasswordChange
- * @property string[] ldapBaseUsers
- * @property int|null ldapPagingSize holds an integer
- * @property bool|mixed|void ldapGroupMemberAssocAttr
- * @property string ldapUuidUserAttribute
- * @property string ldapUuidGroupAttribute
- * @property string ldapExpertUUIDUserAttr
- * @property string ldapExpertUUIDGroupAttr
- * @property string ldapQuotaAttribute
- * @property string ldapQuotaDefault
- * @property string ldapEmailAttribute
- * @property string ldapExtStorageHomeAttribute
- * @property string homeFolderNamingRule
- * @property bool|string markRemnantsAsDisabled
- * @property bool|string ldapNestedGroups
- * @property string[] ldapBaseGroups
- * @property string ldapGroupFilter
- * @property string ldapGroupDisplayName
- * @property string ldapLoginFilter
- * @property string ldapDynamicGroupMemberURL
- * @property string ldapGidNumber
- * @property int hasMemberOfFilterSupport
- * @property int useMemberOfToDetectMembership
- * @property string ldapMatchingRuleInChainState
- * @property string ldapAttributePhone
- * @property string ldapAttributeWebsite
- * @property string ldapAttributeAddress
- * @property string ldapAttributeTwitter
- * @property string ldapAttributeFediverse
- * @property string ldapAttributeOrganisation
- * @property string ldapAttributeRole
- * @property string ldapAttributeHeadline
- * @property string ldapAttributeBiography
- * @property string ldapAdminGroup
+ * @property string $ldapHost
+ * @property string $ldapPort
+ * @property string $ldapBackupHost
+ * @property string $ldapBackupPort
+ * @property string $ldapBackgroundHost
+ * @property string $ldapBackgroundPort
+ * @property array|'' $ldapBase
+ * @property array|'' $ldapBaseUsers
+ * @property array|'' $ldapBaseGroups
+ * @property string $ldapAgentName
+ * @property string $ldapAgentPassword
+ * @property string $ldapTLS
+ * @property string $turnOffCertCheck
+ * @property string $ldapIgnoreNamingRules
+ * @property string $ldapUserDisplayName
+ * @property string $ldapUserDisplayName2
+ * @property string $ldapUserAvatarRule
+ * @property string $ldapGidNumber
+ * @property array|'' $ldapUserFilterObjectclass
+ * @property array|'' $ldapUserFilterGroups
+ * @property string $ldapUserFilter
+ * @property string $ldapUserFilterMode
+ * @property string $ldapGroupFilter
+ * @property string $ldapGroupFilterMode
+ * @property array|'' $ldapGroupFilterObjectclass
+ * @property array|'' $ldapGroupFilterGroups
+ * @property string $ldapGroupDisplayName
+ * @property string $ldapGroupMemberAssocAttr
+ * @property string $ldapLoginFilter
+ * @property string $ldapLoginFilterMode
+ * @property string $ldapLoginFilterEmail
+ * @property string $ldapLoginFilterUsername
+ * @property array|'' $ldapLoginFilterAttributes
+ * @property string $ldapQuotaAttribute
+ * @property string $ldapQuotaDefault
+ * @property string $ldapEmailAttribute
+ * @property string $ldapCacheTTL
+ * @property string $ldapUuidUserAttribute
+ * @property string $ldapUuidGroupAttribute
+ * @property string $ldapOverrideMainServer
+ * @property string $ldapConfigurationActive
+ * @property array|'' $ldapAttributesForUserSearch
+ * @property array|'' $ldapAttributesForGroupSearch
+ * @property string $ldapExperiencedAdmin
+ * @property string $homeFolderNamingRule
+ * @property string $hasMemberOfFilterSupport
+ * @property string $useMemberOfToDetectMembership
+ * @property string $ldapExpertUsernameAttr
+ * @property string $ldapExpertUUIDUserAttr
+ * @property string $ldapExpertUUIDGroupAttr
+ * @property string $markRemnantsAsDisabled
+ * @property string $lastJpegPhotoLookup
+ * @property string $ldapNestedGroups
+ * @property string $ldapPagingSize
+ * @property string $turnOnPasswordChange
+ * @property string $ldapDynamicGroupMemberURL
+ * @property string $ldapDefaultPPolicyDN
+ * @property string $ldapExtStorageHomeAttribute
+ * @property string $ldapMatchingRuleInChainState
+ * @property string $ldapConnectionTimeout
+ * @property string $ldapAttributePhone
+ * @property string $ldapAttributeWebsite
+ * @property string $ldapAttributeAddress
+ * @property string $ldapAttributeTwitter
+ * @property string $ldapAttributeFediverse
+ * @property string $ldapAttributeOrganisation
+ * @property string $ldapAttributeRole
+ * @property string $ldapAttributeHeadline
+ * @property string $ldapAttributeBiography
+ * @property string $ldapAdminGroup
+ * @property string $ldapAttributeBirthDate
+ * @property string $ldapAttributePronouns
*/
class Connection extends LDAPUtility {
private ?\LDAP\Connection $ldapConnectionRes = null;
- private string $configPrefix;
- private ?string $configID;
private bool $configured = false;
/**
@@ -107,11 +113,11 @@ class Connection extends LDAPUtility {
public $hasGidNumber = true;
/**
- * @var \OCP\ICache|null
+ * @var ICache|null
*/
protected $cache = null;
- /** @var Configuration settings handler **/
+ /** @var Configuration settings handler * */
protected $configuration;
/**
@@ -129,27 +135,30 @@ class Connection extends LDAPUtility {
*/
protected $bindResult = [];
- /** @var LoggerInterface */
- protected $logger;
+ protected LoggerInterface $logger;
+ private IL10N $l10n;
/**
* Constructor
* @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
* @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
*/
- public function __construct(ILDAPWrapper $ldap, string $configPrefix = '', ?string $configID = 'user_ldap') {
+ public function __construct(
+ ILDAPWrapper $ldap,
+ private string $configPrefix = '',
+ private ?string $configID = 'user_ldap',
+ ) {
parent::__construct($ldap);
- $this->configPrefix = $configPrefix;
- $this->configID = $configID;
- $this->configuration = new Configuration($configPrefix, !is_null($configID));
- $memcache = \OC::$server->getMemCacheFactory();
+ $this->configuration = new Configuration($this->configPrefix, !is_null($this->configID));
+ $memcache = Server::get(ICacheFactory::class);
if ($memcache->isAvailable()) {
$this->cache = $memcache->createDistributed();
}
- $helper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
+ $helper = Server::get(Helper::class);
$this->doNotValidate = !in_array($this->configPrefix,
$helper->getServerConfigurationPrefixes());
- $this->logger = \OC::$server->get(LoggerInterface::class);
+ $this->logger = Server::get(LoggerInterface::class);
+ $this->l10n = Util::getL10N('user_ldap');
}
public function __destruct() {
@@ -257,11 +266,11 @@ class Connection extends LDAPUtility {
* @param string|null $key
*/
private function getCacheKey($key): string {
- $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
+ $prefix = 'LDAP-' . $this->configID . '-' . $this->configPrefix . '-';
if (is_null($key)) {
return $prefix;
}
- return $prefix.hash('sha256', $key);
+ return $prefix . hash('sha256', $key);
}
/**
@@ -312,7 +321,7 @@ class Connection extends LDAPUtility {
/**
* Caches the general LDAP configuration.
* @param bool $force optional. true, if the re-read should be forced. defaults
- * to false.
+ * to false.
*/
private function readConfiguration(bool $force = false): void {
if ((!$this->configured || $force) && !is_null($this->configID)) {
@@ -325,16 +334,17 @@ class Connection extends LDAPUtility {
* set LDAP configuration with values delivered by an array, not read from configuration
* @param array $config array that holds the config parameters in an associated array
* @param array &$setParameters optional; array where the set fields will be given to
+ * @param bool $throw if true, throw ConfigurationIssueException with details instead of returning false
* @return bool true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
*/
- public function setConfiguration($config, &$setParameters = null): bool {
+ public function setConfiguration(array $config, ?array &$setParameters = null, bool $throw = false): bool {
if (is_null($setParameters)) {
$setParameters = [];
}
$this->doNotValidate = false;
$this->configuration->setConfiguration($config, $setParameters);
if (count($setParameters) > 0) {
- $this->configured = $this->validateConfiguration();
+ $this->configured = $this->validateConfiguration($throw);
}
@@ -396,8 +406,7 @@ class Connection extends LDAPUtility {
}
foreach (['ldapExpertUUIDUserAttr' => 'ldapUuidUserAttribute',
- 'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute']
- as $expertSetting => $effectiveSetting) {
+ 'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute'] as $expertSetting => $effectiveSetting) {
$uuidOverride = $this->configuration->$expertSetting;
if (!empty($uuidOverride)) {
$this->configuration->$effectiveSetting = $uuidOverride;
@@ -409,7 +418,7 @@ class Connection extends LDAPUtility {
$this->configuration->$effectiveSetting = 'auto';
$this->configuration->saveConfiguration();
$this->logger->info(
- 'Illegal value for the '.$effectiveSetting.', reset to autodetect.',
+ 'Illegal value for the ' . $effectiveSetting . ', reset to autodetect.',
['app' => 'user_ldap']
);
}
@@ -418,7 +427,7 @@ class Connection extends LDAPUtility {
$backupPort = (int)$this->configuration->ldapBackupPort;
if ($backupPort <= 0) {
- $this->configuration->backupPort = $this->configuration->ldapPort;
+ $this->configuration->ldapBackupPort = $this->configuration->ldapPort;
}
//make sure empty search attributes are saved as simple, empty array
@@ -433,7 +442,7 @@ class Connection extends LDAPUtility {
if ((stripos((string)$this->configuration->ldapHost, 'ldaps://') === 0)
&& $this->configuration->ldapTLS) {
- $this->configuration->ldapTLS = false;
+ $this->configuration->ldapTLS = (string)false;
$this->logger->info(
'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.',
['app' => 'user_ldap']
@@ -441,10 +450,10 @@ class Connection extends LDAPUtility {
}
}
- private function doCriticalValidation(): bool {
- $configurationOK = true;
- $errorStr = 'Configuration Error (prefix ' . $this->configPrefix . '): ';
-
+ /**
+ * @throws ConfigurationIssueException
+ */
+ private function doCriticalValidation(): void {
//options that shall not be empty
$options = ['ldapHost', 'ldapUserDisplayName',
'ldapGroupDisplayName', 'ldapLoginFilter'];
@@ -477,10 +486,9 @@ class Connection extends LDAPUtility {
$subj = $key;
break;
}
- $configurationOK = false;
- $this->logger->warning(
- $errorStr.'No '.$subj.' given!',
- ['app' => 'user_ldap']
+ throw new ConfigurationIssueException(
+ 'No ' . $subj . ' given!',
+ $this->l10n->t('Mandatory field "%s" left empty', $subj),
);
}
}
@@ -488,47 +496,76 @@ class Connection extends LDAPUtility {
//combinations
$agent = $this->configuration->ldapAgentName;
$pwd = $this->configuration->ldapAgentPassword;
- if (
- ($agent === '' && $pwd !== '')
- || ($agent !== '' && $pwd === '')
- ) {
- $this->logger->warning(
- $errorStr.'either no password is given for the user ' .
- 'agent or a password is given, but not an LDAP agent.',
- ['app' => 'user_ldap']
+ if ($agent === '' && $pwd !== '') {
+ throw new ConfigurationIssueException(
+ 'A password is given, but not an LDAP agent',
+ $this->l10n->t('A password is given, but not an LDAP agent'),
+ );
+ }
+ if ($agent !== '' && $pwd === '') {
+ throw new ConfigurationIssueException(
+ 'No password is given for the user agent',
+ $this->l10n->t('No password is given for the user agent'),
);
- $configurationOK = false;
}
$base = $this->configuration->ldapBase;
$baseUsers = $this->configuration->ldapBaseUsers;
$baseGroups = $this->configuration->ldapBaseGroups;
- if (empty($base) && empty($baseUsers) && empty($baseGroups)) {
- $this->logger->warning(
- $errorStr.'Not a single Base DN given.',
- ['app' => 'user_ldap']
+ if (empty($base)) {
+ throw new ConfigurationIssueException(
+ 'Not a single Base DN given',
+ $this->l10n->t('No LDAP base DN was given'),
);
- $configurationOK = false;
}
- if (mb_strpos((string)$this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
- === false) {
- $this->logger->warning(
- $errorStr.'login filter does not contain %uid place holder.',
- ['app' => 'user_ldap']
+ if (!empty($baseUsers) && !$this->checkBasesAreValid($baseUsers, $base)) {
+ throw new ConfigurationIssueException(
+ 'User base is not in root base',
+ $this->l10n->t('User base DN is not a subnode of global base DN'),
);
- $configurationOK = false;
}
- return $configurationOK;
+ if (!empty($baseGroups) && !$this->checkBasesAreValid($baseGroups, $base)) {
+ throw new ConfigurationIssueException(
+ 'Group base is not in root base',
+ $this->l10n->t('Group base DN is not a subnode of global base DN'),
+ );
+ }
+
+ if (mb_strpos((string)$this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8') === false) {
+ throw new ConfigurationIssueException(
+ 'Login filter does not contain %uid placeholder.',
+ $this->l10n->t('Login filter does not contain %s placeholder.', ['%uid']),
+ );
+ }
+ }
+
+ /**
+ * Checks that all bases are subnodes of one of the root bases
+ */
+ private function checkBasesAreValid(array $bases, array $rootBases): bool {
+ foreach ($bases as $base) {
+ $ok = false;
+ foreach ($rootBases as $rootBase) {
+ if (str_ends_with($base, $rootBase)) {
+ $ok = true;
+ break;
+ }
+ }
+ if (!$ok) {
+ return false;
+ }
+ }
+ return true;
}
/**
* Validates the user specified configuration
* @return bool true if configuration seems OK, false otherwise
*/
- private function validateConfiguration(): bool {
+ private function validateConfiguration(bool $throw = false): bool {
if ($this->doNotValidate) {
//don't do a validation if it is a new configuration with pure
//default values. Will be allowed on changes via __set or
@@ -542,7 +579,19 @@ class Connection extends LDAPUtility {
//second step: critical checks. If left empty or filled wrong, mark as
//not configured and give a warning.
- return $this->doCriticalValidation();
+ try {
+ $this->doCriticalValidation();
+ return true;
+ } catch (ConfigurationIssueException $e) {
+ if ($throw) {
+ throw $e;
+ }
+ $this->logger->warning(
+ 'Configuration Error (prefix ' . $this->configPrefix . '): ' . $e->getMessage(),
+ ['exception' => $e]
+ );
+ return false;
+ }
}
@@ -576,19 +625,6 @@ class Connection extends LDAPUtility {
return false;
}
- if ($this->configuration->turnOffCertCheck) {
- if (putenv('LDAPTLS_REQCERT=never')) {
- $this->logger->debug(
- 'Turned off SSL certificate validation successfully.',
- ['app' => 'user_ldap']
- );
- } else {
- $this->logger->warning(
- 'Could not turn off SSL certificate validation.',
- ['app' => 'user_ldap']
- );
- }
- }
$hasBackupHost = (trim($this->configuration->ldapBackupHost ?? '') !== '');
$hasBackgroundHost = (trim($this->configuration->ldapBackgroundHost ?? '') !== '');
@@ -612,9 +648,11 @@ class Connection extends LDAPUtility {
}
}
$this->logger->warning(
- 'Main LDAP not reachable, connecting to backup',
+ 'Main LDAP not reachable, connecting to backup: {msg}',
[
- 'app' => 'user_ldap'
+ 'app' => 'user_ldap',
+ 'msg' => $e->getMessage(),
+ 'exception' => $e,
]
);
}
@@ -623,8 +661,8 @@ class Connection extends LDAPUtility {
$this->doConnect($this->configuration->ldapBackupHost ?? '', $this->configuration->ldapBackupPort ?? '');
$this->bindResult = [];
$bindStatus = $this->bind();
- $error = $this->ldap->isResource($this->ldapConnectionRes) ?
- $this->ldap->errno($this->ldapConnectionRes) : -1;
+ $error = $this->ldap->isResource($this->ldapConnectionRes)
+ ? $this->ldap->errno($this->ldapConnectionRes) : -1;
if ($bindStatus && $error === 0 && !$forceBackupHost) {
//when bind to backup server succeeded and failed to main server,
//skip contacting it for 15min
@@ -665,6 +703,20 @@ class Connection extends LDAPUtility {
}
if ($this->configuration->ldapTLS) {
+ if ($this->configuration->turnOffCertCheck) {
+ if ($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER)) {
+ $this->logger->debug(
+ 'Turned off SSL certificate validation successfully.',
+ ['app' => 'user_ldap']
+ );
+ } else {
+ $this->logger->warning(
+ 'Could not turn off SSL certificate validation.',
+ ['app' => 'user_ldap']
+ );
+ }
+ }
+
if (!$this->ldap->startTls($this->ldapConnectionRes)) {
throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
}
diff --git a/apps/user_ldap/lib/ConnectionFactory.php b/apps/user_ldap/lib/ConnectionFactory.php
index cf2bacebc85..dd0ad31920a 100644
--- a/apps/user_ldap/lib/ConnectionFactory.php
+++ b/apps/user_ldap/lib/ConnectionFactory.php
@@ -1,33 +1,15 @@
<?php
+
/**
- * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
class ConnectionFactory {
- /** @var ILDAPWrapper */
- private $ldap;
-
- public function __construct(ILDAPWrapper $ldap) {
- $this->ldap = $ldap;
+ public function __construct(
+ private ILDAPWrapper $ldap,
+ ) {
}
public function get($prefix) {
diff --git a/apps/user_ldap/lib/Controller/ConfigAPIController.php b/apps/user_ldap/lib/Controller/ConfigAPIController.php
index 5d54ba56401..d98e6d41b52 100644
--- a/apps/user_ldap/lib/Controller/ConfigAPIController.php
+++ b/apps/user_ldap/lib/Controller/ConfigAPIController.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Controller;
@@ -29,7 +12,9 @@ use OC\Security\IdentityProof\Manager;
use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\ConnectionFactory;
use OCA\User_LDAP\Helper;
+use OCA\User_LDAP\Settings\Admin;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSException;
@@ -37,6 +22,7 @@ use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\IRequest;
use OCP\IUserManager;
use OCP\IUserSession;
+use OCP\ServerVersion;
use Psr\Log\LoggerInterface;
class ConfigAPIController extends OCSController {
@@ -47,9 +33,10 @@ class ConfigAPIController extends OCSController {
IUserSession $userSession,
IUserManager $userManager,
Manager $keyManager,
+ ServerVersion $serverVersion,
private Helper $ldapHelper,
private LoggerInterface $logger,
- private ConnectionFactory $connectionFactory
+ private ConnectionFactory $connectionFactory,
) {
parent::__construct(
$appName,
@@ -57,19 +44,20 @@ class ConfigAPIController extends OCSController {
$capabilitiesManager,
$userSession,
$userManager,
- $keyManager
+ $keyManager,
+ $serverVersion,
);
}
/**
* Create a new (empty) configuration and return the resulting prefix
*
- * @AuthorizedAdminSetting(settings=OCA\User_LDAP\Settings\Admin)
* @return DataResponse<Http::STATUS_OK, array{configID: string}, array{}>
* @throws OCSException
*
* 200: Config created successfully
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
public function create() {
try {
$configPrefix = $this->ldapHelper->getNextServerConfigurationPrefix();
@@ -86,14 +74,14 @@ class ConfigAPIController extends OCSController {
/**
* Delete a LDAP configuration
*
- * @AuthorizedAdminSetting(settings=OCA\User_LDAP\Settings\Admin)
* @param string $configID ID of the config
- * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
* @throws OCSException
* @throws OCSNotFoundException Config not found
*
* 200: Config deleted successfully
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
public function delete($configID) {
try {
$this->ensureConfigIDExists($configID);
@@ -113,16 +101,16 @@ class ConfigAPIController extends OCSController {
/**
* Modify a configuration
*
- * @AuthorizedAdminSetting(settings=OCA\User_LDAP\Settings\Admin)
* @param string $configID ID of the config
* @param array<string, mixed> $configData New config
- * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
* @throws OCSException
* @throws OCSBadRequestException Modifying config is not possible
* @throws OCSNotFoundException Config not found
*
* 200: Config returned
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
public function modify($configID, $configData) {
try {
$this->ensureConfigIDExists($configID);
@@ -218,7 +206,6 @@ class ConfigAPIController extends OCSController {
* </data>
* </ocs>
*
- * @AuthorizedAdminSetting(settings=OCA\User_LDAP\Settings\Admin)
* @param string $configID ID of the config
* @param bool $showPassword Whether to show the password
* @return DataResponse<Http::STATUS_OK, array<string, mixed>, array{}>
@@ -227,6 +214,7 @@ class ConfigAPIController extends OCSController {
*
* 200: Config returned
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
public function show($configID, $showPassword = false) {
try {
$this->ensureConfigIDExists($configID);
@@ -255,10 +243,10 @@ class ConfigAPIController extends OCSController {
/**
* If the given config ID is not available, an exception is thrown
*
- * @AuthorizedAdminSetting(settings=OCA\User_LDAP\Settings\Admin)
* @param string $configID
* @throws OCSNotFoundException
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
private function ensureConfigIDExists($configID): void {
$prefixes = $this->ldapHelper->getServerConfigurationPrefixes();
if (!in_array($configID, $prefixes, true)) {
diff --git a/apps/user_ldap/lib/Controller/RenewPasswordController.php b/apps/user_ldap/lib/Controller/RenewPasswordController.php
index 75015f28bcd..8389a362b8f 100644
--- a/apps/user_ldap/lib/Controller/RenewPasswordController.php
+++ b/apps/user_ldap/lib/Controller/RenewPasswordController.php
@@ -1,30 +1,16 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Roger Szabo <roger.szabo@web.de>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Roger Szabo <roger.szabo@web.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Controller;
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\OpenAPI;
+use OCP\AppFramework\Http\Attribute\PublicPage;
+use OCP\AppFramework\Http\Attribute\UseSession;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\HintException;
@@ -38,17 +24,6 @@ use OCP\IUserManager;
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
class RenewPasswordController extends Controller {
- /** @var IUserManager */
- private $userManager;
- /** @var IConfig */
- private $config;
- /** @var IL10N */
- protected $l10n;
- /** @var ISession */
- private $session;
- /** @var IURLGenerator */
- private $urlGenerator;
-
/**
* @param string $appName
* @param IRequest $request
@@ -56,35 +31,35 @@ class RenewPasswordController extends Controller {
* @param IConfig $config
* @param IURLGenerator $urlGenerator
*/
- public function __construct($appName, IRequest $request, IUserManager $userManager,
- IConfig $config, IL10N $l10n, ISession $session, IURLGenerator $urlGenerator) {
+ public function __construct(
+ $appName,
+ IRequest $request,
+ private IUserManager $userManager,
+ private IConfig $config,
+ protected IL10N $l10n,
+ private ISession $session,
+ private IURLGenerator $urlGenerator,
+ ) {
parent::__construct($appName, $request);
- $this->userManager = $userManager;
- $this->config = $config;
- $this->l10n = $l10n;
- $this->session = $session;
- $this->urlGenerator = $urlGenerator;
}
/**
- * @PublicPage
- * @NoCSRFRequired
- *
* @return RedirectResponse
*/
+ #[PublicPage]
+ #[NoCSRFRequired]
public function cancel() {
return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
}
/**
- * @PublicPage
- * @NoCSRFRequired
- * @UseSession
- *
* @param string $user
*
* @return TemplateResponse|RedirectResponse
*/
+ #[PublicPage]
+ #[NoCSRFRequired]
+ #[UseSession]
public function showRenewPasswordForm($user) {
if ($this->config->getUserValue($user, 'user_ldap', 'needsPasswordReset') !== 'true') {
return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
@@ -120,15 +95,14 @@ class RenewPasswordController extends Controller {
}
/**
- * @PublicPage
- * @UseSession
- *
* @param string $user
* @param string $oldPassword
* @param string $newPassword
*
* @return RedirectResponse
*/
+ #[PublicPage]
+ #[UseSession]
public function tryRenewPassword($user, $oldPassword, $newPassword) {
if ($this->config->getUserValue($user, 'user_ldap', 'needsPasswordReset') !== 'true') {
return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
@@ -145,7 +119,7 @@ class RenewPasswordController extends Controller {
try {
if (!is_null($newPassword) && \OC_User::setPassword($user, $newPassword)) {
$this->session->set('loginMessages', [
- [], [$this->l10n->t("Please login with the new password")]
+ [], [$this->l10n->t('Please login with the new password')]
]);
$this->config->setUserValue($user, 'user_ldap', 'needsPasswordReset', 'false');
return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
@@ -164,12 +138,11 @@ class RenewPasswordController extends Controller {
}
/**
- * @PublicPage
- * @NoCSRFRequired
- * @UseSession
- *
* @return RedirectResponse
*/
+ #[PublicPage]
+ #[NoCSRFRequired]
+ #[UseSession]
public function showLoginFormInvalidPassword($user) {
$args = !is_null($user) ? ['user' => $user] : [];
$this->session->set('loginMessages', [
diff --git a/apps/user_ldap/lib/DataCollector/LdapDataCollector.php b/apps/user_ldap/lib/DataCollector/LdapDataCollector.php
index 015248f914d..2f74a628a32 100644
--- a/apps/user_ldap/lib/DataCollector/LdapDataCollector.php
+++ b/apps/user_ldap/lib/DataCollector/LdapDataCollector.php
@@ -2,25 +2,8 @@
declare(strict_types = 1);
/**
- * @copyright 2022 Carl Schwan <carl@carlschwan.eu>
- *
- * @author Carl Schwan <carl@carlschwan.eu>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\DataCollector;
diff --git a/apps/user_ldap/lib/Db/GroupMembership.php b/apps/user_ldap/lib/Db/GroupMembership.php
index 25be5296d52..6141f1b18c9 100644
--- a/apps/user_ldap/lib/Db/GroupMembership.php
+++ b/apps/user_ldap/lib/Db/GroupMembership.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Db;
diff --git a/apps/user_ldap/lib/Db/GroupMembershipMapper.php b/apps/user_ldap/lib/Db/GroupMembershipMapper.php
index cd722b64f04..b3d6c31dda6 100644
--- a/apps/user_ldap/lib/Db/GroupMembershipMapper.php
+++ b/apps/user_ldap/lib/Db/GroupMembershipMapper.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Db;
diff --git a/apps/user_ldap/lib/Events/GroupBackendRegistered.php b/apps/user_ldap/lib/Events/GroupBackendRegistered.php
index e0302b87b1f..a94c239c1b3 100644
--- a/apps/user_ldap/lib/Events/GroupBackendRegistered.php
+++ b/apps/user_ldap/lib/Events/GroupBackendRegistered.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Events;
@@ -37,14 +19,10 @@ use OCP\EventDispatcher\Event;
*/
class GroupBackendRegistered extends Event {
- /** @var GroupPluginManager */
- private $pluginManager;
- /** @var IGroupLDAP */
- private $backend;
-
- public function __construct(IGroupLDAP $backend, GroupPluginManager $pluginManager) {
- $this->pluginManager = $pluginManager;
- $this->backend = $backend;
+ public function __construct(
+ private IGroupLDAP $backend,
+ private GroupPluginManager $pluginManager,
+ ) {
}
public function getBackend(): IGroupLDAP {
diff --git a/apps/user_ldap/lib/Events/UserBackendRegistered.php b/apps/user_ldap/lib/Events/UserBackendRegistered.php
index 91743089ccf..a26e23f8f83 100644
--- a/apps/user_ldap/lib/Events/UserBackendRegistered.php
+++ b/apps/user_ldap/lib/Events/UserBackendRegistered.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Events;
@@ -37,14 +19,10 @@ use OCP\EventDispatcher\Event;
*/
class UserBackendRegistered extends Event {
- /** @var IUserLDAP */
- private $backend;
- /** @var UserPluginManager */
- private $pluginManager;
-
- public function __construct(IUserLDAP $backend, UserPluginManager $pluginManager) {
- $this->backend = $backend;
- $this->pluginManager = $pluginManager;
+ public function __construct(
+ private IUserLDAP $backend,
+ private UserPluginManager $pluginManager,
+ ) {
}
public function getBackend(): IUserLDAP {
diff --git a/apps/user_ldap/lib/Exceptions/AttributeNotSet.php b/apps/user_ldap/lib/Exceptions/AttributeNotSet.php
index 63e255b85d6..4d6053eda66 100644
--- a/apps/user_ldap/lib/Exceptions/AttributeNotSet.php
+++ b/apps/user_ldap/lib/Exceptions/AttributeNotSet.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2019 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Exceptions;
diff --git a/apps/user_ldap/lib/Exceptions/ConfigurationIssueException.php b/apps/user_ldap/lib/Exceptions/ConfigurationIssueException.php
new file mode 100644
index 00000000000..efeb426b13d
--- /dev/null
+++ b/apps/user_ldap/lib/Exceptions/ConfigurationIssueException.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\User_LDAP\Exceptions;
+
+use OCP\HintException;
+
+class ConfigurationIssueException extends HintException {
+}
diff --git a/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php
index 912d6039a60..d0d384c31de 100644
--- a/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php
+++ b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Roger Szabo <roger.szabo@web.de>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Roger Szabo <roger.szabo@web.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Exceptions;
diff --git a/apps/user_ldap/lib/Exceptions/NoMoreResults.php b/apps/user_ldap/lib/Exceptions/NoMoreResults.php
index 26dc4a58992..b5621d86eb6 100644
--- a/apps/user_ldap/lib/Exceptions/NoMoreResults.php
+++ b/apps/user_ldap/lib/Exceptions/NoMoreResults.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Exceptions;
diff --git a/apps/user_ldap/lib/Exceptions/NotOnLDAP.php b/apps/user_ldap/lib/Exceptions/NotOnLDAP.php
index 30a82106655..cd74e918829 100644
--- a/apps/user_ldap/lib/Exceptions/NotOnLDAP.php
+++ b/apps/user_ldap/lib/Exceptions/NotOnLDAP.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Exceptions;
diff --git a/apps/user_ldap/lib/FilesystemHelper.php b/apps/user_ldap/lib/FilesystemHelper.php
deleted file mode 100644
index 0596b109deb..00000000000
--- a/apps/user_ldap/lib/FilesystemHelper.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\User_LDAP;
-
-/**
- * @brief wraps around static Nextcloud core methods
- */
-class FilesystemHelper {
-
- /**
- * @brief states whether the filesystem was loaded
- * @return bool
- */
- public function isLoaded() {
- return \OC\Files\Filesystem::$loaded;
- }
-
- /**
- * @brief initializes the filesystem for the given user
- * @param string $uid the Nextcloud username of the user
- */
- public function setup($uid) {
- \OC_Util::setupFS($uid);
- }
-}
diff --git a/apps/user_ldap/lib/GroupPluginManager.php b/apps/user_ldap/lib/GroupPluginManager.php
index 92bf0cb8888..9e8ae6805a4 100644
--- a/apps/user_ldap/lib/GroupPluginManager.php
+++ b/apps/user_ldap/lib/GroupPluginManager.php
@@ -1,29 +1,13 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 EITA Cooperative (eita.org.br)
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
use OCP\GroupInterface;
+use OCP\Server;
use Psr\Log\LoggerInterface;
class GroupPluginManager {
@@ -59,7 +43,7 @@ class GroupPluginManager {
foreach ($this->which as $action => $v) {
if ((bool)($respondToActions & $action)) {
$this->which[$action] = $plugin;
- \OCP\Server::get(LoggerInterface::class)->debug("Registered action ".$action." to plugin ".get_class($plugin), ['app' => 'user_ldap']);
+ Server::get(LoggerInterface::class)->debug('Registered action ' . $action . ' to plugin ' . get_class($plugin), ['app' => 'user_ldap']);
}
}
}
diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php
index 09bdbd6db96..271cc96afbd 100644
--- a/apps/user_ldap/lib/Group_LDAP.php
+++ b/apps/user_ldap/lib/Group_LDAP.php
@@ -1,46 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Alexander Bergolth <leo@strike.wu.ac.at>
- * @author Alex Weirig <alex.weirig@technolink.lu>
- * @author alexweirig <alex.weirig@technolink.lu>
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Andreas Pflug <dev@admin4.org>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Clement Wong <git@clement.hk>
- * @author Frédéric Fortier <frederic.fortier@oronospolytechnique.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Nicolas Grekas <nicolas.grekas@gmail.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roland Tapken <roland@bitarbeiter.net>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Tobias Perschon <tobias@perschon.at>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- * @author Xuanwo <xuanwo@yunify.com>
- * @author Carl Schwan <carl@carlschwan.eu>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -68,24 +31,19 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
protected CappedMemoryCache $cachedGroupsByMember;
/** @var CappedMemoryCache<string[]> $cachedNestedGroups array of groups with gid (DN) as key */
protected CappedMemoryCache $cachedNestedGroups;
- protected GroupPluginManager $groupPluginManager;
protected LoggerInterface $logger;
- protected Access $access;
/**
* @var string $ldapGroupMemberAssocAttr contains the LDAP setting (in lower case) with the same name
*/
protected string $ldapGroupMemberAssocAttr;
- private IConfig $config;
- private IUserManager $ncUserManager;
public function __construct(
- Access $access,
- GroupPluginManager $groupPluginManager,
- IConfig $config,
- IUserManager $ncUserManager
+ protected Access $access,
+ protected GroupPluginManager $groupPluginManager,
+ private IConfig $config,
+ private IUserManager $ncUserManager,
) {
- $this->access = $access;
$filter = $this->access->connection->ldapGroupFilter;
$gAssoc = $this->access->connection->ldapGroupMemberAssocAttr;
if (!empty($filter) && !empty($gAssoc)) {
@@ -95,11 +53,8 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
$this->cachedGroupMembers = new CappedMemoryCache();
$this->cachedGroupsByMember = new CappedMemoryCache();
$this->cachedNestedGroups = new CappedMemoryCache();
- $this->groupPluginManager = $groupPluginManager;
$this->logger = Server::get(LoggerInterface::class);
$this->ldapGroupMemberAssocAttr = strtolower((string)$gAssoc);
- $this->config = $config;
- $this->ncUserManager = $ncUserManager;
}
/**
@@ -491,7 +446,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
string $groupDN,
string $search = '',
?int $limit = -1,
- ?int $offset = 0
+ ?int $offset = 0,
): array {
try {
$filter = $this->prepareFilterForUsersHasGidNumber($groupDN, $search);
@@ -615,7 +570,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
string $groupDN,
string $search = '',
?int $limit = -1,
- ?int $offset = 0
+ ?int $offset = 0,
): array {
try {
$filter = $this->prepareFilterForUsersInPrimaryGroup($groupDN, $search);
@@ -640,7 +595,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
string $groupDN,
string $search = '',
int $limit = -1,
- int $offset = 0
+ int $offset = 0,
): int {
try {
$filter = $this->prepareFilterForUsersInPrimaryGroup($groupDN, $search);
@@ -683,6 +638,10 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
return false;
}
+ /**
+ * @param string $uid
+ * @return list<string>
+ */
protected function getCachedGroupsForUserId(string $uid): array {
$groupStr = $this->config->getUserValue($uid, 'user_ldap', 'cached-group-memberships-' . $this->access->connection->getConfigPrefix(), '[]');
return json_decode($groupStr, true) ?? [];
@@ -695,7 +654,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
* This function includes groups based on dynamic group membership.
*
* @param string $uid Name of the user
- * @return string[] Group names
+ * @return list<string> Group names
* @throws Exception
* @throws ServerNotAvailableException
*/
@@ -1060,9 +1019,9 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
return $groupUsers;
}
$search = $this->access->escapeFilterPart($search, true);
- $isMemberUid =
- ($this->ldapGroupMemberAssocAttr === 'memberuid' ||
- $this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress');
+ $isMemberUid
+ = ($this->ldapGroupMemberAssocAttr === 'memberuid'
+ || $this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress');
//we need to apply the search filter
//alternatives that need to be checked:
@@ -1219,7 +1178,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
continue;
}
$name = $item[$this->access->connection->ldapGroupDisplayName][0] ?? null;
- $gid = $this->access->dn2groupname($dn, $name);
+ $gid = $this->access->dn2groupname($dn, $name, false);
if (!$gid) {
continue;
}
@@ -1240,10 +1199,10 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
* compared with GroupInterface::CREATE_GROUP etc.
*/
public function implementsActions($actions): bool {
- return (bool)((GroupInterface::COUNT_USERS |
- GroupInterface::DELETE_GROUP |
- GroupInterface::IS_ADMIN |
- $this->groupPluginManager->getImplementedActions()) & $actions);
+ return (bool)((GroupInterface::COUNT_USERS
+ | GroupInterface::DELETE_GROUP
+ | GroupInterface::IS_ADMIN
+ | $this->groupPluginManager->getImplementedActions()) & $actions);
}
/**
@@ -1295,7 +1254,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
if ($ret = $this->groupPluginManager->deleteGroup($gid)) {
// Delete group in nextcloud internal db
$this->access->getGroupMapper()->unmap($gid);
- $this->access->connection->writeToCache("groupExists" . $gid, false);
+ $this->access->connection->writeToCache('groupExists' . $gid, false);
}
return $ret;
}
@@ -1303,17 +1262,17 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
// Getting dn, if false the group is not mapped
$dn = $this->access->groupname2dn($gid);
if (!$dn) {
- throw new Exception('Could not delete unknown group '.$gid.' in LDAP backend.');
+ throw new Exception('Could not delete unknown group ' . $gid . ' in LDAP backend.');
}
if (!$this->groupExists($gid)) {
// The group does not exist in the LDAP, remove the mapping
$this->access->getGroupMapper()->unmap($gid);
- $this->access->connection->writeToCache("groupExists" . $gid, false);
+ $this->access->connection->writeToCache('groupExists' . $gid, false);
return true;
}
- throw new Exception('Could not delete existing group '.$gid.' in LDAP backend.');
+ throw new Exception('Could not delete existing group ' . $gid . ' in LDAP backend.');
}
/**
diff --git a/apps/user_ldap/lib/Group_Proxy.php b/apps/user_ldap/lib/Group_Proxy.php
index 1544d5f91e9..f0cdc7a465d 100644
--- a/apps/user_ldap/lib/Group_Proxy.php
+++ b/apps/user_ldap/lib/Group_Proxy.php
@@ -1,30 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Johannes Leuker <j.leuker@hosting.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -39,45 +18,24 @@ use OCP\GroupInterface;
use OCP\IConfig;
use OCP\IUserManager;
-class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGetDisplayNameBackend, INamedBackend, IDeleteGroupBackend, IBatchMethodsBackend, IIsAdminBackend {
- private $backends = [];
- private ?Group_LDAP $refBackend = null;
- private Helper $helper;
- private GroupPluginManager $groupPluginManager;
- private bool $isSetUp = false;
- private IConfig $config;
- private IUserManager $ncUserManager;
-
+/**
+ * @template-extends Proxy<Group_LDAP>
+ */
+class Group_Proxy extends Proxy implements GroupInterface, IGroupLDAP, IGetDisplayNameBackend, INamedBackend, IDeleteGroupBackend, IBatchMethodsBackend, IIsAdminBackend {
public function __construct(
- Helper $helper,
+ private Helper $helper,
ILDAPWrapper $ldap,
AccessFactory $accessFactory,
- GroupPluginManager $groupPluginManager,
- IConfig $config,
- IUserManager $ncUserManager,
+ private GroupPluginManager $groupPluginManager,
+ private IConfig $config,
+ private IUserManager $ncUserManager,
) {
- parent::__construct($ldap, $accessFactory);
- $this->helper = $helper;
- $this->groupPluginManager = $groupPluginManager;
- $this->config = $config;
- $this->ncUserManager = $ncUserManager;
+ parent::__construct($helper, $ldap, $accessFactory);
}
- protected function setup(): void {
- if ($this->isSetUp) {
- return;
- }
-
- $serverConfigPrefixes = $this->helper->getServerConfigurationPrefixes(true);
- foreach ($serverConfigPrefixes as $configPrefix) {
- $this->backends[$configPrefix] =
- new Group_LDAP($this->getAccess($configPrefix), $this->groupPluginManager, $this->config, $this->ncUserManager);
- if (is_null($this->refBackend)) {
- $this->refBackend = &$this->backends[$configPrefix];
- }
- }
- $this->isSetUp = true;
+ protected function newInstance(string $configPrefix): Group_LDAP {
+ return new Group_LDAP($this->getAccess($configPrefix), $this->groupPluginManager, $this->config, $this->ncUserManager);
}
/**
@@ -162,7 +120,7 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet
* Get all groups a user belongs to
*
* @param string $uid Name of the user
- * @return string[] with group names
+ * @return list<string> with group names
*
* This function fetches all groups a user belongs to. It does not check
* if the user exists at all.
@@ -173,9 +131,7 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet
$groups = [];
foreach ($this->backends as $backend) {
$backendGroups = $backend->getUserGroups($uid);
- if (is_array($backendGroups)) {
- $groups = array_merge($groups, $backendGroups);
- }
+ $groups = array_merge($groups, $backendGroups);
}
return array_values(array_unique($groups));
@@ -273,7 +229,7 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet
*/
public function getGroupsDetails(array $gids): array {
if (!($this instanceof IGroupDetailsBackend || $this->implementsActions(GroupInterface::GROUP_DETAILS))) {
- throw new \Exception("Should not have been called");
+ throw new \Exception('Should not have been called');
}
$groupData = [];
diff --git a/apps/user_ldap/lib/Handler/ExtStorageConfigHandler.php b/apps/user_ldap/lib/Handler/ExtStorageConfigHandler.php
index 6f2a1007c16..8b63d54aa66 100644
--- a/apps/user_ldap/lib/Handler/ExtStorageConfigHandler.php
+++ b/apps/user_ldap/lib/Handler/ExtStorageConfigHandler.php
@@ -1,26 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2019 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Julius Härtl <jus@bitgrid.net>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Handler;
diff --git a/apps/user_ldap/lib/Helper.php b/apps/user_ldap/lib/Helper.php
index b9e5405d014..d3abf04fd1e 100644
--- a/apps/user_ldap/lib/Helper.php
+++ b/apps/user_ldap/lib/Helper.php
@@ -1,49 +1,26 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author root <root@localhost.localdomain>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
use OCP\Cache\CappedMemoryCache;
use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IConfig;
+use OCP\IAppConfig;
use OCP\IDBConnection;
+use OCP\Server;
class Helper {
- private IConfig $config;
- private IDBConnection $connection;
/** @var CappedMemoryCache<string> */
protected CappedMemoryCache $sanitizeDnCache;
- public function __construct(IConfig $config,
- IDBConnection $connection) {
- $this->config = $config;
- $this->connection = $connection;
+ public function __construct(
+ private IAppConfig $appConfig,
+ private IDBConnection $connection,
+ ) {
$this->sanitizeDnCache = new CappedMemoryCache(10000);
}
@@ -51,7 +28,7 @@ class Helper {
* returns prefixes for each saved LDAP/AD server configuration.
*
* @param bool $activeConfigurations optional, whether only active configuration shall be
- * retrieved, defaults to false
+ * retrieved, defaults to false
* @return array with a list of the available prefixes
*
* Configuration prefixes are used to set up configurations for n LDAP or
@@ -68,21 +45,37 @@ class Helper {
* except the default (first) server shall be connected to.
*
*/
- public function getServerConfigurationPrefixes($activeConfigurations = false): array {
+ public function getServerConfigurationPrefixes(bool $activeConfigurations = false): array {
+ $all = $this->getAllServerConfigurationPrefixes();
+ if (!$activeConfigurations) {
+ return $all;
+ }
+ return array_values(array_filter(
+ $all,
+ fn (string $prefix): bool => ($this->appConfig->getValueString('user_ldap', $prefix . 'ldap_configuration_active') === '1')
+ ));
+ }
+
+ protected function getAllServerConfigurationPrefixes(): array {
+ $unfilled = ['UNFILLED'];
+ $prefixes = $this->appConfig->getValueArray('user_ldap', 'configuration_prefixes', $unfilled);
+ if ($prefixes !== $unfilled) {
+ return $prefixes;
+ }
+
+ /* Fallback to browsing key for migration from Nextcloud<32 */
$referenceConfigkey = 'ldap_configuration_active';
$keys = $this->getServersConfig($referenceConfigkey);
$prefixes = [];
foreach ($keys as $key) {
- if ($activeConfigurations && $this->config->getAppValue('user_ldap', $key, '0') !== '1') {
- continue;
- }
-
$len = strlen($key) - strlen($referenceConfigkey);
$prefixes[] = substr($key, 0, $len);
}
- asort($prefixes);
+ sort($prefixes);
+
+ $this->appConfig->setValueArray('user_ldap', 'configuration_prefixes', $prefixes);
return $prefixes;
}
@@ -91,46 +84,45 @@ class Helper {
*
* determines the host for every configured connection
*
- * @return array an array with configprefix as keys
+ * @return array<string,string> an array with configprefix as keys
*
*/
- public function getServerConfigurationHosts() {
- $referenceConfigkey = 'ldap_host';
-
- $keys = $this->getServersConfig($referenceConfigkey);
+ public function getServerConfigurationHosts(): array {
+ $prefixes = $this->getServerConfigurationPrefixes();
+ $referenceConfigkey = 'ldap_host';
$result = [];
- foreach ($keys as $key) {
- $len = strlen($key) - strlen($referenceConfigkey);
- $prefix = substr($key, 0, $len);
- $result[$prefix] = $this->config->getAppValue('user_ldap', $key);
+ foreach ($prefixes as $prefix) {
+ $result[$prefix] = $this->appConfig->getValueString('user_ldap', $prefix . $referenceConfigkey);
}
return $result;
}
/**
- * return the next available configuration prefix
- *
- * @return string
+ * return the next available configuration prefix and register it as used
*/
- public function getNextServerConfigurationPrefix() {
- $serverConnections = $this->getServerConfigurationPrefixes();
-
- if (count($serverConnections) === 0) {
- return 's01';
+ public function getNextServerConfigurationPrefix(): string {
+ $prefixes = $this->getServerConfigurationPrefixes();
+
+ if (count($prefixes) === 0) {
+ $prefix = 's01';
+ } else {
+ sort($prefixes);
+ $lastKey = array_pop($prefixes);
+ $lastNumber = (int)str_replace('s', '', $lastKey);
+ $prefix = 's' . str_pad((string)($lastNumber + 1), 2, '0', STR_PAD_LEFT);
}
- sort($serverConnections);
- $lastKey = array_pop($serverConnections);
- $lastNumber = (int)str_replace('s', '', $lastKey);
- return 's' . str_pad((string)($lastNumber + 1), 2, '0', STR_PAD_LEFT);
+ $prefixes[] = $prefix;
+ $this->appConfig->setValueArray('user_ldap', 'configuration_prefixes', $prefixes);
+ return $prefix;
}
private function getServersConfig(string $value): array {
$regex = '/' . $value . '$/S';
- $keys = $this->config->getAppKeys('user_ldap');
+ $keys = $this->appConfig->getKeys('user_ldap');
$result = [];
foreach ($keys as $key) {
if (preg_match($regex, $key) === 1) {
@@ -148,7 +140,9 @@ class Helper {
* @return bool true on success, false otherwise
*/
public function deleteServerConfiguration($prefix) {
- if (!in_array($prefix, self::getServerConfigurationPrefixes())) {
+ $prefixes = $this->getServerConfigurationPrefixes();
+ $index = array_search($prefix, $prefixes);
+ if ($index === false) {
return false;
}
@@ -167,7 +161,11 @@ class Helper {
$query->andWhere($query->expr()->notLike('configkey', $query->createNamedParameter('s%')));
}
- $deletedRows = $query->execute();
+ $deletedRows = $query->executeStatement();
+
+ unset($prefixes[$index]);
+ $this->appConfig->setValueArray('user_ldap', 'configuration_prefixes', array_values($prefixes));
+
return $deletedRows !== 0;
}
@@ -175,10 +173,13 @@ class Helper {
* checks whether there is one or more disabled LDAP configurations
*/
public function haveDisabledConfigurations(): bool {
- $all = $this->getServerConfigurationPrefixes(false);
- $active = $this->getServerConfigurationPrefixes(true);
-
- return count($all) !== count($active) || count($all) === 0;
+ $all = $this->getServerConfigurationPrefixes();
+ foreach ($all as $prefix) {
+ if ($this->appConfig->getValueString('user_ldap', $prefix . 'ldap_configuration_active') !== '1') {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -293,7 +294,7 @@ class Helper {
throw new \Exception('key uid is expected to be set in $param');
}
- $userBackend = \OC::$server->get(User_Proxy::class);
+ $userBackend = Server::get(User_Proxy::class);
$uid = $userBackend->loginName2UserName($param['uid']);
if ($uid !== false) {
$param['uid'] = $uid;
diff --git a/apps/user_ldap/lib/IGroupLDAP.php b/apps/user_ldap/lib/IGroupLDAP.php
index ee83c18a8c6..667eb421004 100644
--- a/apps/user_ldap/lib/IGroupLDAP.php
+++ b/apps/user_ldap/lib/IGroupLDAP.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017, EITA Cooperative (eita.org.br)
- *
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
diff --git a/apps/user_ldap/lib/ILDAPGroupPlugin.php b/apps/user_ldap/lib/ILDAPGroupPlugin.php
index 20cff50e801..261b9383dc1 100644
--- a/apps/user_ldap/lib/ILDAPGroupPlugin.php
+++ b/apps/user_ldap/lib/ILDAPGroupPlugin.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 EITA Cooperative (eita.org.br)
- *
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
diff --git a/apps/user_ldap/lib/ILDAPUserPlugin.php b/apps/user_ldap/lib/ILDAPUserPlugin.php
index 06b86c50385..80437bef452 100644
--- a/apps/user_ldap/lib/ILDAPUserPlugin.php
+++ b/apps/user_ldap/lib/ILDAPUserPlugin.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 EITA Cooperative (eita.org.br)
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
@@ -76,7 +59,7 @@ interface ILDAPUserPlugin {
public function setDisplayName($uid, $displayName);
/**
- * checks whether the user is allowed to change his avatar in Nextcloud
+ * checks whether the user is allowed to change their avatar in Nextcloud
* @param string $uid the Nextcloud user name
* @return boolean either the user can or cannot
*/
diff --git a/apps/user_ldap/lib/ILDAPWrapper.php b/apps/user_ldap/lib/ILDAPWrapper.php
index ecf949c145a..de2b9c50241 100644
--- a/apps/user_ldap/lib/ILDAPWrapper.php
+++ b/apps/user_ldap/lib/ILDAPWrapper.php
@@ -1,31 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author J0WI <J0WI@users.noreply.github.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
diff --git a/apps/user_ldap/lib/IUserLDAP.php b/apps/user_ldap/lib/IUserLDAP.php
index b4df16728a2..5e8e29c3adf 100644
--- a/apps/user_ldap/lib/IUserLDAP.php
+++ b/apps/user_ldap/lib/IUserLDAP.php
@@ -1,39 +1,22 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
- *
- * @author Roger Szabo <roger.szabo@web.de>
- * @author root <root@localhost.localdomain>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
interface IUserLDAP {
//Functions used by LDAPProvider
-
+
/**
* Return access for LDAP interaction.
* @param string $uid
* @return Access instance of Access for LDAP interaction
*/
public function getLDAPAccess($uid);
-
+
/**
* Return a new LDAP connection for the specified user.
* @param string $uid
diff --git a/apps/user_ldap/lib/Jobs/CleanUp.php b/apps/user_ldap/lib/Jobs/CleanUp.php
index f4e23446352..76277b43c0b 100644
--- a/apps/user_ldap/lib/Jobs/CleanUp.php
+++ b/apps/user_ldap/lib/Jobs/CleanUp.php
@@ -1,37 +1,21 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Jobs;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\Mapping\UserMapping;
use OCA\User_LDAP\User\DeletedUsersIndex;
-use OCA\User_LDAP\User_LDAP;
use OCA\User_LDAP\User_Proxy;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\Server;
/**
* Class CleanUp
@@ -45,15 +29,12 @@ class CleanUp extends TimedJob {
protected $limit;
/** @var int $defaultIntervalMin default interval in minutes */
- protected $defaultIntervalMin = 51;
+ protected $defaultIntervalMin = 60;
- /** @var User_LDAP|User_Proxy $userBackend */
- protected $userBackend;
-
- /** @var \OCP\IConfig $ocConfig */
+ /** @var IConfig $ocConfig */
protected $ocConfig;
- /** @var \OCP\IDBConnection $db */
+ /** @var IDBConnection $db */
protected $db;
/** @var Helper $ldapHelper */
@@ -62,20 +43,15 @@ class CleanUp extends TimedJob {
/** @var UserMapping */
protected $mapping;
- /** @var DeletedUsersIndex */
- protected $dui;
-
public function __construct(
ITimeFactory $timeFactory,
- User_Proxy $userBackend,
- DeletedUsersIndex $dui
+ protected User_Proxy $userBackend,
+ protected DeletedUsersIndex $dui,
) {
parent::__construct($timeFactory);
- $minutes = \OC::$server->getConfig()->getSystemValue(
+ $minutes = Server::get(IConfig::class)->getSystemValue(
'ldapUserCleanupInterval', (string)$this->defaultIntervalMin);
$this->setInterval((int)$minutes * 60);
- $this->userBackend = $userBackend;
- $this->dui = $dui;
}
/**
@@ -91,13 +67,13 @@ class CleanUp extends TimedJob {
if (isset($arguments['helper'])) {
$this->ldapHelper = $arguments['helper'];
} else {
- $this->ldapHelper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
+ $this->ldapHelper = Server::get(Helper::class);
}
if (isset($arguments['ocConfig'])) {
$this->ocConfig = $arguments['ocConfig'];
} else {
- $this->ocConfig = \OC::$server->getConfig();
+ $this->ocConfig = Server::get(IConfig::class);
}
if (isset($arguments['userBackend'])) {
@@ -107,13 +83,13 @@ class CleanUp extends TimedJob {
if (isset($arguments['db'])) {
$this->db = $arguments['db'];
} else {
- $this->db = \OC::$server->getDatabaseConnection();
+ $this->db = Server::get(IDBConnection::class);
}
if (isset($arguments['mapping'])) {
$this->mapping = $arguments['mapping'];
} else {
- $this->mapping = \OCP\Server::get(UserMapping::class);
+ $this->mapping = Server::get(UserMapping::class);
}
if (isset($arguments['deletedUsersIndex'])) {
@@ -203,8 +179,8 @@ class CleanUp extends TimedJob {
* @param bool $reset whether the offset should be set to 0
*/
public function setOffset(bool $reset = false): void {
- $newOffset = $reset ? 0 :
- $this->getOffset() + $this->getChunkSize();
+ $newOffset = $reset ? 0
+ : $this->getOffset() + $this->getChunkSize();
$this->ocConfig->setAppValue('user_ldap', 'cleanUpJobOffset', (string)$newOffset);
}
diff --git a/apps/user_ldap/lib/Jobs/Sync.php b/apps/user_ldap/lib/Jobs/Sync.php
index b92aa2fcfaa..26888ae96ae 100644
--- a/apps/user_ldap/lib/Jobs/Sync.php
+++ b/apps/user_ldap/lib/Jobs/Sync.php
@@ -1,27 +1,10 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
+
namespace OCA\User_LDAP\Jobs;
use OC\ServerNotAvailableException;
@@ -33,6 +16,7 @@ use OCA\User_LDAP\LDAP;
use OCA\User_LDAP\Mapping\UserMapping;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\IDBConnection;
@@ -43,44 +27,38 @@ use Psr\Log\LoggerInterface;
class Sync extends TimedJob {
public const MAX_INTERVAL = 12 * 60 * 60; // 12h
public const MIN_INTERVAL = 30 * 60; // 30min
- /** @var Helper */
- protected $ldapHelper;
- /** @var LDAP */
- protected $ldap;
- /** @var UserMapping */
- protected $mapper;
- /** @var IConfig */
- protected $config;
- /** @var IAvatarManager */
- protected $avatarManager;
- /** @var IDBConnection */
- protected $dbc;
- /** @var IUserManager */
- protected $ncUserManager;
- /** @var LoggerInterface */
- protected $logger;
- /** @var IManager */
- protected $notificationManager;
- /** @var ConnectionFactory */
- protected $connectionFactory;
- /** @var AccessFactory */
- protected $accessFactory;
- public function __construct(ITimeFactory $time) {
- parent::__construct($time);
+ protected LDAP $ldap;
+
+ public function __construct(
+ ITimeFactory $timeFactory,
+ private IEventDispatcher $dispatcher,
+ private IConfig $config,
+ private IDBConnection $dbc,
+ private IAvatarManager $avatarManager,
+ private IUserManager $ncUserManager,
+ private LoggerInterface $logger,
+ private IManager $notificationManager,
+ private UserMapping $mapper,
+ private Helper $ldapHelper,
+ private ConnectionFactory $connectionFactory,
+ private AccessFactory $accessFactory,
+ ) {
+ parent::__construct($timeFactory);
$this->setInterval(
- (int)\OC::$server->getConfig()->getAppValue(
+ (int)$this->config->getAppValue(
'user_ldap',
'background_sync_interval',
(string)self::MIN_INTERVAL
)
);
+ $this->ldap = new LDAP($this->config->getSystemValueString('ldap_log_file'));
}
/**
- * updates the interval
+ * Updates the interval
*
- * the idea is to adjust the interval depending on the amount of known users
+ * The idea is to adjust the interval depending on the amount of known users
* and the attempt to update each user one day. At most it would run every
* 30 minutes, and at least every 12 hours.
*/
@@ -98,9 +76,8 @@ class Sync extends TimedJob {
/**
* returns the smallest configured paging size
- * @return int
*/
- protected function getMinPagingSize() {
+ protected function getMinPagingSize(): int {
$configKeys = $this->config->getAppKeys('user_ldap');
$configKeys = array_filter($configKeys, function ($key) {
return str_contains($key, 'ldap_paging_size');
@@ -117,10 +94,8 @@ class Sync extends TimedJob {
* @param array $argument
*/
public function run($argument) {
- $this->setArgument($argument);
-
$isBackgroundJobModeAjax = $this->config
- ->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'ajax';
+ ->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'ajax';
if ($isBackgroundJobModeAjax) {
return;
}
@@ -153,10 +128,10 @@ class Sync extends TimedJob {
}
/**
- * @param array $cycleData
+ * @param array{offset: int, prefix: string} $cycleData
* @return bool whether more results are expected from the same configuration
*/
- public function runCycle($cycleData) {
+ public function runCycle(array $cycleData): bool {
$connection = $this->connectionFactory->get($cycleData['prefix']);
$access = $this->accessFactory->get($connection);
$access->setUserMapper($this->mapper);
@@ -169,7 +144,7 @@ class Sync extends TimedJob {
$results = $access->fetchListOfUsers(
$filter,
$access->userManager->getAttributes(),
- $connection->ldapPagingSize,
+ (int)$connection->ldapPagingSize,
$cycleData['offset'],
true
);
@@ -181,24 +156,22 @@ class Sync extends TimedJob {
}
/**
- * returns the info about the current cycle that should be run, if any,
+ * Returns the info about the current cycle that should be run, if any,
* otherwise null
- *
- * @return array|null
*/
- public function getCycle() {
+ public function getCycle(): ?array {
$prefixes = $this->ldapHelper->getServerConfigurationPrefixes(true);
if (count($prefixes) === 0) {
return null;
}
$cycleData = [
- 'prefix' => $this->config->getAppValue('user_ldap', 'background_sync_prefix', null),
+ 'prefix' => $this->config->getAppValue('user_ldap', 'background_sync_prefix', 'none'),
'offset' => (int)$this->config->getAppValue('user_ldap', 'background_sync_offset', '0'),
];
if (
- $cycleData['prefix'] !== null
+ $cycleData['prefix'] !== 'none'
&& in_array($cycleData['prefix'], $prefixes)
) {
return $cycleData;
@@ -210,21 +183,21 @@ class Sync extends TimedJob {
/**
* Save the provided cycle information in the DB
*
- * @param array $cycleData
+ * @param array{prefix: ?string, offset: int} $cycleData
*/
- public function setCycle(array $cycleData) {
+ public function setCycle(array $cycleData): void {
$this->config->setAppValue('user_ldap', 'background_sync_prefix', $cycleData['prefix']);
- $this->config->setAppValue('user_ldap', 'background_sync_offset', $cycleData['offset']);
+ $this->config->setAppValue('user_ldap', 'background_sync_offset', (string)$cycleData['offset']);
}
/**
* returns data about the next cycle that should run, if any, otherwise
* null. It also always goes for the next LDAP configuration!
*
- * @param array|null $cycleData the old cycle
- * @return array|null
+ * @param ?array{prefix: string, offset: int} $cycleData the old cycle
+ * @return ?array{prefix: string, offset: int}
*/
- public function determineNextCycle(?array $cycleData = null) {
+ public function determineNextCycle(?array $cycleData = null): ?array {
$prefixes = $this->ldapHelper->getServerConfigurationPrefixes(true);
if (count($prefixes) === 0) {
return null;
@@ -244,13 +217,12 @@ class Sync extends TimedJob {
}
/**
- * Checks whether the provided cycle should be run. Currently only the
+ * Checks whether the provided cycle should be run. Currently, only the
* last configuration change goes into account (at least one hour).
*
- * @param $cycleData
- * @return bool
+ * @param array{prefix: string} $cycleData
*/
- public function qualifiesToRun($cycleData) {
+ public function qualifiesToRun(array $cycleData): bool {
$lastChange = (int)$this->config->getAppValue('user_ldap', $cycleData['prefix'] . '_lastChange', '0');
if ((time() - $lastChange) > 60 * 30) {
return true;
@@ -259,23 +231,20 @@ class Sync extends TimedJob {
}
/**
- * increases the offset of the current cycle for the next run
+ * Increases the offset of the current cycle for the next run
*
- * @param $cycleData
+ * @param array{prefix: string, offset: int} $cycleData
*/
- protected function increaseOffset($cycleData) {
+ protected function increaseOffset(array $cycleData): void {
$ldapConfig = new Configuration($cycleData['prefix']);
$cycleData['offset'] += (int)$ldapConfig->ldapPagingSize;
$this->setCycle($cycleData);
}
/**
- * determines the next configuration prefix based on the last one (if any)
- *
- * @param string|null $lastPrefix
- * @return string|null
+ * Determines the next configuration prefix based on the last one (if any)
*/
- protected function getNextPrefix($lastPrefix) {
+ protected function getNextPrefix(?string $lastPrefix): ?string {
$prefixes = $this->ldapHelper->getServerConfigurationPrefixes(true);
$noOfPrefixes = count($prefixes);
if ($noOfPrefixes === 0) {
@@ -295,73 +264,9 @@ class Sync extends TimedJob {
}
/**
- * "fixes" DI
+ * Only used in tests
*/
- public function setArgument($argument) {
- if (isset($argument['config'])) {
- $this->config = $argument['config'];
- } else {
- $this->config = \OC::$server->getConfig();
- }
-
- if (isset($argument['helper'])) {
- $this->ldapHelper = $argument['helper'];
- } else {
- $this->ldapHelper = new Helper($this->config, \OC::$server->getDatabaseConnection());
- }
-
- if (isset($argument['ldapWrapper'])) {
- $this->ldap = $argument['ldapWrapper'];
- } else {
- $this->ldap = new LDAP($this->config->getSystemValueString('ldap_log_file'));
- }
-
- if (isset($argument['avatarManager'])) {
- $this->avatarManager = $argument['avatarManager'];
- } else {
- $this->avatarManager = \OC::$server->getAvatarManager();
- }
-
- if (isset($argument['dbc'])) {
- $this->dbc = $argument['dbc'];
- } else {
- $this->dbc = \OC::$server->getDatabaseConnection();
- }
-
- if (isset($argument['ncUserManager'])) {
- $this->ncUserManager = $argument['ncUserManager'];
- } else {
- $this->ncUserManager = \OC::$server->getUserManager();
- }
-
- if (isset($argument['logger'])) {
- $this->logger = $argument['logger'];
- } else {
- $this->logger = \OC::$server->get(LoggerInterface::class);
- }
-
- if (isset($argument['notificationManager'])) {
- $this->notificationManager = $argument['notificationManager'];
- } else {
- $this->notificationManager = \OC::$server->getNotificationManager();
- }
-
- if (isset($argument['mapper'])) {
- $this->mapper = $argument['mapper'];
- } else {
- $this->mapper = \OCP\Server::get(UserMapping::class);
- }
-
- if (isset($argument['connectionFactory'])) {
- $this->connectionFactory = $argument['connectionFactory'];
- } else {
- $this->connectionFactory = new ConnectionFactory($this->ldap);
- }
-
- if (isset($argument['accessFactory'])) {
- $this->accessFactory = $argument['accessFactory'];
- } else {
- $this->accessFactory = \OCP\Server::get(AccessFactory::class);
- }
+ public function overwritePropertiesForTest(LDAP $ldapWrapper): void {
+ $this->ldap = $ldapWrapper;
}
}
diff --git a/apps/user_ldap/lib/Jobs/UpdateGroups.php b/apps/user_ldap/lib/Jobs/UpdateGroups.php
index 3f7ae8f21d2..9e72bcd8432 100644
--- a/apps/user_ldap/lib/Jobs/UpdateGroups.php
+++ b/apps/user_ldap/lib/Jobs/UpdateGroups.php
@@ -3,32 +3,9 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Jobs;
diff --git a/apps/user_ldap/lib/LDAP.php b/apps/user_ldap/lib/LDAP.php
index 01f4e16ab10..1cf20c4b939 100644
--- a/apps/user_ldap/lib/LDAP.php
+++ b/apps/user_ldap/lib/LDAP.php
@@ -1,35 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Alexander Bergolth <leo@strike.wu.ac.at>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author J0WI <J0WI@users.noreply.github.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Peter Kubica <peter@kubica.ch>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Carl Schwan <carl@carlschwan.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -37,27 +11,30 @@ use OC\ServerNotAvailableException;
use OCA\User_LDAP\DataCollector\LdapDataCollector;
use OCA\User_LDAP\Exceptions\ConstraintViolationException;
use OCP\IConfig;
+use OCP\ILogger;
use OCP\Profiler\IProfiler;
+use OCP\Server;
use Psr\Log\LoggerInterface;
class LDAP implements ILDAPWrapper {
- protected string $logFile = '';
protected array $curArgs = [];
protected LoggerInterface $logger;
+ protected IConfig $config;
private ?LdapDataCollector $dataCollector = null;
- public function __construct(string $logFile = '') {
- $this->logFile = $logFile;
-
+ public function __construct(
+ protected string $logFile = '',
+ ) {
/** @var IProfiler $profiler */
- $profiler = \OC::$server->get(IProfiler::class);
+ $profiler = Server::get(IProfiler::class);
if ($profiler->isEnabled()) {
$this->dataCollector = new LdapDataCollector();
$profiler->add($this->dataCollector);
}
- $this->logger = \OCP\Server::get(LoggerInterface::class);
+ $this->logger = Server::get(LoggerInterface::class);
+ $this->config = Server::get(IConfig::class);
}
/**
@@ -204,6 +181,7 @@ class LDAP implements ILDAPWrapper {
$serverControls = [];
}
+ /** @psalm-suppress UndefinedVariable $oldHandler is defined when the closure is called but psalm fails to get that */
$oldHandler = set_error_handler(function ($no, $message, $file, $line) use (&$oldHandler) {
if (str_contains($message, 'Partial search results returned: Sizelimit exceeded')) {
return true;
@@ -316,9 +294,24 @@ class LDAP implements ILDAPWrapper {
return null;
}
+ /**
+ * Turn resources into string, and removes potentially problematic cookie string to avoid breaking logfiles
+ */
+ private function sanitizeFunctionParameters(array $args): array {
+ return array_map(function ($item) {
+ if ($this->isResource($item)) {
+ return '(resource)';
+ }
+ if (isset($item[0]['value']['cookie']) && $item[0]['value']['cookie'] !== '') {
+ $item[0]['value']['cookie'] = '*opaque cookie*';
+ }
+ return $item;
+ }, $args);
+ }
+
private function preFunctionCall(string $functionName, array $args): void {
$this->curArgs = $args;
- if(strcasecmp($functionName, 'ldap_bind') === 0) {
+ if (strcasecmp($functionName, 'ldap_bind') === 0 || strcasecmp($functionName, 'ldap_exop_passwd') === 0) {
// The arguments are not key value pairs
// \OCA\User_LDAP\LDAP::bind passes 3 arguments, the 3rd being the pw
// Remove it via direct array access for now, although a better solution could be found mebbe?
@@ -326,32 +319,24 @@ class LDAP implements ILDAPWrapper {
$args[2] = IConfig::SENSITIVE_VALUE;
}
- $this->logger->debug('Calling LDAP function {func} with parameters {args}', [
- 'app' => 'user_ldap',
- 'func' => $functionName,
- 'args' => json_encode($args),
- ]);
+ if ($this->config->getSystemValue('loglevel') === ILogger::DEBUG) {
+ /* Only running this if debug loglevel is on, to avoid processing parameters on production */
+ $this->logger->debug('Calling LDAP function {func} with parameters {args}', [
+ 'app' => 'user_ldap',
+ 'func' => $functionName,
+ 'args' => $this->sanitizeFunctionParameters($args),
+ ]);
+ }
if ($this->dataCollector !== null) {
- $args = array_map(function ($item) {
- if ($this->isResource($item)) {
- return '(resource)';
- }
- if (isset($item[0]['value']['cookie']) && $item[0]['value']['cookie'] !== "") {
- $item[0]['value']['cookie'] = "*opaque cookie*";
- }
- return $item;
- }, $this->curArgs);
-
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
- $this->dataCollector->startLdapRequest($functionName, $args, $backtrace);
+ $this->dataCollector->startLdapRequest($functionName, $this->sanitizeFunctionParameters($args), $backtrace);
}
if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
- $args = array_map(fn ($item) => (!$this->isResource($item) ? $item : '(resource)'), $this->curArgs);
file_put_contents(
$this->logFile,
- $functionName . '::' . json_encode($args) . "\n",
+ $functionName . '::' . json_encode($this->sanitizeFunctionParameters($args)) . "\n",
FILE_APPEND
);
}
@@ -394,7 +379,7 @@ class LDAP implements ILDAPWrapper {
/**
* Called after an ldap method is run to act on LDAP error if necessary
- * @throw \Exception
+ * @throws \Exception
*/
private function postFunctionCall(string $functionName): void {
if ($this->isResource($this->curArgs[0])) {
diff --git a/apps/user_ldap/lib/LDAPProvider.php b/apps/user_ldap/lib/LDAPProvider.php
index 353eefb7be4..d9750ae3fcf 100644
--- a/apps/user_ldap/lib/LDAPProvider.php
+++ b/apps/user_ldap/lib/LDAPProvider.php
@@ -1,30 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author root <root@localhost.localdomain>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
@@ -32,32 +11,33 @@ use OCA\User_LDAP\User\DeletedUsersIndex;
use OCP\IServerContainer;
use OCP\LDAP\IDeletionFlagSupport;
use OCP\LDAP\ILDAPProvider;
+use Psr\Log\LoggerInterface;
/**
- * LDAP provider for pulic access to the LDAP backend.
+ * LDAP provider for public access to the LDAP backend.
*/
class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
private $userBackend;
private $groupBackend;
private $logger;
- private $helper;
- private $deletedUsersIndex;
/**
* Create new LDAPProvider
- * @param \OCP\IServerContainer $serverContainer
+ * @param IServerContainer $serverContainer
* @param Helper $helper
* @param DeletedUsersIndex $deletedUsersIndex
* @throws \Exception if user_ldap app was not enabled
*/
- public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
- $this->logger = $serverContainer->getLogger();
- $this->helper = $helper;
- $this->deletedUsersIndex = $deletedUsersIndex;
+ public function __construct(
+ IServerContainer $serverContainer,
+ private Helper $helper,
+ private DeletedUsersIndex $deletedUsersIndex,
+ ) {
+ $this->logger = $serverContainer->get(LoggerInterface::class);
$userBackendFound = false;
$groupBackendFound = false;
foreach ($serverContainer->getUserManager()->getBackends() as $backend) {
- $this->logger->debug('instance '.get_class($backend).' user backend.', ['app' => 'user_ldap']);
+ $this->logger->debug('instance ' . get_class($backend) . ' user backend.', ['app' => 'user_ldap']);
if ($backend instanceof IUserLDAP) {
$this->userBackend = $backend;
$userBackendFound = true;
@@ -65,7 +45,7 @@ class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
}
}
foreach ($serverContainer->getGroupManager()->getBackends() as $backend) {
- $this->logger->debug('instance '.get_class($backend).' group backend.', ['app' => 'user_ldap']);
+ $this->logger->debug('instance ' . get_class($backend) . ' group backend.', ['app' => 'user_ldap']);
if ($backend instanceof IGroupLDAP) {
$this->groupBackend = $backend;
$groupBackendFound = true;
@@ -138,8 +118,8 @@ class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
/**
* Sanitize a DN received from the LDAP server.
- * @param array $dn the DN in question
- * @return array the sanitized DN
+ * @param array|string $dn the DN in question
+ * @return array|string the sanitized DN
*/
public function sanitizeDN($dn) {
return $this->helper->sanitizeDN($dn);
diff --git a/apps/user_ldap/lib/LDAPProviderFactory.php b/apps/user_ldap/lib/LDAPProviderFactory.php
index 13887921603..8fad9d52206 100644
--- a/apps/user_ldap/lib/LDAPProviderFactory.php
+++ b/apps/user_ldap/lib/LDAPProviderFactory.php
@@ -1,27 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author root <root@localhost.localdomain>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
@@ -30,11 +12,10 @@ use OCP\LDAP\ILDAPProvider;
use OCP\LDAP\ILDAPProviderFactory;
class LDAPProviderFactory implements ILDAPProviderFactory {
- /** * @var IServerContainer */
- private $serverContainer;
-
- public function __construct(IServerContainer $serverContainer) {
- $this->serverContainer = $serverContainer;
+ public function __construct(
+ /** * @var IServerContainer */
+ private IServerContainer $serverContainer,
+ ) {
}
public function getLDAPProvider(): ILDAPProvider {
diff --git a/apps/user_ldap/lib/LDAPUtility.php b/apps/user_ldap/lib/LDAPUtility.php
index a8e4c16fac7..39b517528e2 100644
--- a/apps/user_ldap/lib/LDAPUtility.php
+++ b/apps/user_ldap/lib/LDAPUtility.php
@@ -1,37 +1,19 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
abstract class LDAPUtility {
- protected ILDAPWrapper $ldap;
-
/**
* constructor, make sure the subclasses call this one!
- * @param ILDAPWrapper $ldapWrapper an instance of an ILDAPWrapper
+ * @param ILDAPWrapper $ldap an instance of an ILDAPWrapper
*/
- public function __construct(ILDAPWrapper $ldapWrapper) {
- $this->ldap = $ldapWrapper;
+ public function __construct(
+ protected ILDAPWrapper $ldap,
+ ) {
}
}
diff --git a/apps/user_ldap/lib/LoginListener.php b/apps/user_ldap/lib/LoginListener.php
index 3a223b97cd8..f397f4694d2 100644
--- a/apps/user_ldap/lib/LoginListener.php
+++ b/apps/user_ldap/lib/LoginListener.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023, Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
@@ -59,7 +42,7 @@ class LoginListener implements IEventListener {
public function onPostLogin(IUser $user): void {
$this->logger->info(
- __CLASS__ . ' - {user} postLogin',
+ self::class . ' - {user} postLogin',
[
'app' => 'user_ldap',
'user' => $user->getUID(),
@@ -84,7 +67,7 @@ class LoginListener implements IEventListener {
$groupObject = $this->groupManager->get($groupId);
if ($groupObject === null) {
$this->logger->error(
- __CLASS__ . ' - group {group} could not be found (user {user})',
+ self::class . ' - group {group} could not be found (user {user})',
[
'app' => 'user_ldap',
'user' => $userId,
@@ -98,7 +81,7 @@ class LoginListener implements IEventListener {
} catch (Exception $e) {
if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
$this->logger->error(
- __CLASS__ . ' - group {group} membership failed to be added (user {user})',
+ self::class . ' - group {group} membership failed to be added (user {user})',
[
'app' => 'user_ldap',
'user' => $userId,
@@ -113,7 +96,7 @@ class LoginListener implements IEventListener {
$this->groupBackend->addRelationshipToCaches($userId, null, $groupId);
$this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject));
$this->logger->info(
- __CLASS__ . ' - {user} added to {group}',
+ self::class . ' - {user} added to {group}',
[
'app' => 'user_ldap',
'user' => $userId,
@@ -127,7 +110,7 @@ class LoginListener implements IEventListener {
} catch (Exception $e) {
if ($e->getReason() !== Exception::REASON_DATABASE_OBJECT_NOT_FOUND) {
$this->logger->error(
- __CLASS__ . ' - group {group} membership failed to be removed (user {user})',
+ self::class . ' - group {group} membership failed to be removed (user {user})',
[
'app' => 'user_ldap',
'user' => $userId,
@@ -142,7 +125,7 @@ class LoginListener implements IEventListener {
$groupObject = $this->groupManager->get($groupId);
if ($groupObject === null) {
$this->logger->error(
- __CLASS__ . ' - group {group} could not be found (user {user})',
+ self::class . ' - group {group} could not be found (user {user})',
[
'app' => 'user_ldap',
'user' => $userId,
diff --git a/apps/user_ldap/lib/Mapping/AbstractMapping.php b/apps/user_ldap/lib/Mapping/AbstractMapping.php
index 6c2938661e2..fa10312a915 100644
--- a/apps/user_ldap/lib/Mapping/AbstractMapping.php
+++ b/apps/user_ldap/lib/Mapping/AbstractMapping.php
@@ -1,35 +1,17 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Aaron Wood <aaronjwood@gmail.com>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author blizzz <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Mapping;
use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use OCP\DB\IPreparedStatement;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
@@ -39,11 +21,6 @@ use Psr\Log\LoggerInterface;
*/
abstract class AbstractMapping {
/**
- * @var \OCP\IDBConnection $dbc
- */
- protected $dbc;
-
- /**
* returns the DB table name which holds the mappings
*
* @return string
@@ -51,10 +28,11 @@ abstract class AbstractMapping {
abstract protected function getTableName(bool $includePrefix = true);
/**
- * @param \OCP\IDBConnection $dbc
+ * @param IDBConnection $dbc
*/
- public function __construct(\OCP\IDBConnection $dbc) {
- $this->dbc = $dbc;
+ public function __construct(
+ protected IDBConnection $dbc,
+ ) {
}
/** @var array caches Names (value) by DN (key) */
@@ -235,7 +213,7 @@ abstract class AbstractMapping {
public function getListOfIdsByDn(array $fdns): array {
$totalDBParamLimit = 65000;
$sliceSize = 1000;
- $maxSlices = $this->dbc->getDatabasePlatform() instanceof SqlitePlatform ? 9 : $totalDBParamLimit / $sliceSize;
+ $maxSlices = $this->dbc->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE ? 9 : $totalDBParamLimit / $sliceSize;
$results = [];
$slice = 1;
@@ -278,7 +256,7 @@ abstract class AbstractMapping {
*
* @return string[]
*/
- public function getNamesBySearch(string $search, string $prefixMatch = "", string $postfixMatch = ""): array {
+ public function getNamesBySearch(string $search, string $prefixMatch = '', string $postfixMatch = ''): array {
$statement = $this->dbc->prepare('
SELECT `owncloud_name`
FROM `' . $this->getTableName() . '`
@@ -352,7 +330,7 @@ abstract class AbstractMapping {
*/
public function map($fdn, $name, $uuid) {
if (mb_strlen($fdn) > 4000) {
- \OCP\Server::get(LoggerInterface::class)->error(
+ Server::get(LoggerInterface::class)->error(
'Cannot map, because the DN exceeds 4000 characters: {dn}',
[
'app' => 'user_ldap',
@@ -425,7 +403,7 @@ abstract class AbstractMapping {
* @param callable $preCallback
* @param callable $postCallback
* @return bool true on success, false when at least one row was not
- * deleted
+ * deleted
*/
public function clearCb(callable $preCallback, callable $postCallback): bool {
$picker = $this->dbc->getQueryBuilder();
@@ -453,7 +431,7 @@ abstract class AbstractMapping {
$query = $this->dbc->getQueryBuilder();
$query->select($query->func()->count('ldap_dn_hash'))
->from($this->getTableName());
- $res = $query->execute();
+ $res = $query->executeQuery();
$count = $res->fetchOne();
$res->closeCursor();
return (int)$count;
@@ -464,7 +442,7 @@ abstract class AbstractMapping {
$query->select($query->func()->count('ldap_dn_hash'))
->from($this->getTableName())
->where($query->expr()->like('directory_uuid', $query->createNamedParameter('invalidated_%')));
- $res = $query->execute();
+ $res = $query->executeQuery();
$count = $res->fetchOne();
$res->closeCursor();
return (int)$count;
diff --git a/apps/user_ldap/lib/Mapping/GroupMapping.php b/apps/user_ldap/lib/Mapping/GroupMapping.php
index e8518e5e9fc..d9ae5e749fc 100644
--- a/apps/user_ldap/lib/Mapping/GroupMapping.php
+++ b/apps/user_ldap/lib/Mapping/GroupMapping.php
@@ -1,24 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Mapping;
diff --git a/apps/user_ldap/lib/Mapping/UserMapping.php b/apps/user_ldap/lib/Mapping/UserMapping.php
index ade9c67213a..a030cd0ab52 100644
--- a/apps/user_ldap/lib/Mapping/UserMapping.php
+++ b/apps/user_ldap/lib/Mapping/UserMapping.php
@@ -1,24 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Mapping;
@@ -35,11 +20,12 @@ use OCP\Support\Subscription\IAssertion;
*/
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;
+ public function __construct(
+ IDBConnection $dbc,
+ private IAssertion $assertion,
+ ) {
parent::__construct($dbc);
}
diff --git a/apps/user_ldap/lib/Migration/GroupMappingMigration.php b/apps/user_ldap/lib/Migration/GroupMappingMigration.php
index d5d7aa367a1..7dfb8705770 100644
--- a/apps/user_ldap/lib/Migration/GroupMappingMigration.php
+++ b/apps/user_ldap/lib/Migration/GroupMappingMigration.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -31,11 +14,9 @@ use OCP\Migration\SimpleMigrationStep;
abstract class GroupMappingMigration extends SimpleMigrationStep {
- /** @var IDBConnection */
- private $dbc;
-
- public function __construct(IDBConnection $dbc) {
- $this->dbc = $dbc;
+ public function __construct(
+ private IDBConnection $dbc,
+ ) {
}
protected function copyGroupMappingData(string $sourceTable, string $destinationTable): void {
diff --git a/apps/user_ldap/lib/Migration/RemoveRefreshTime.php b/apps/user_ldap/lib/Migration/RemoveRefreshTime.php
index 501076ed0e8..88ac56ccb84 100644
--- a/apps/user_ldap/lib/Migration/RemoveRefreshTime.php
+++ b/apps/user_ldap/lib/Migration/RemoveRefreshTime.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -39,14 +22,10 @@ use OCP\Migration\IRepairStep;
*/
class RemoveRefreshTime implements IRepairStep {
- /** @var IDBConnection */
- private $dbc;
- /** @var IConfig */
- private $config;
-
- public function __construct(IDBConnection $dbc, IConfig $config) {
- $this->dbc = $dbc;
- $this->config = $config;
+ public function __construct(
+ private IDBConnection $dbc,
+ private IConfig $config,
+ ) {
}
public function getName() {
@@ -60,6 +39,6 @@ class RemoveRefreshTime implements IRepairStep {
$qb->delete('preferences')
->where($qb->expr()->eq('appid', $qb->createNamedParameter('user_ldap')))
->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter('lastFeatureRefresh')))
- ->execute();
+ ->executeStatement();
}
}
diff --git a/apps/user_ldap/lib/Migration/SetDefaultProvider.php b/apps/user_ldap/lib/Migration/SetDefaultProvider.php
index fd9a79c8494..0bb04438a1d 100644
--- a/apps/user_ldap/lib/Migration/SetDefaultProvider.php
+++ b/apps/user_ldap/lib/Migration/SetDefaultProvider.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -33,16 +16,10 @@ use OCP\Migration\IRepairStep;
class SetDefaultProvider implements IRepairStep {
- /** @var IConfig */
- private $config;
-
- /** @var Helper */
- private $helper;
-
- public function __construct(IConfig $config,
- Helper $helper) {
- $this->config = $config;
- $this->helper = $helper;
+ public function __construct(
+ private IConfig $config,
+ private Helper $helper,
+ ) {
}
public function getName(): string {
diff --git a/apps/user_ldap/lib/Migration/UUIDFix.php b/apps/user_ldap/lib/Migration/UUIDFix.php
index e36ddd1140f..e853f3bba66 100644
--- a/apps/user_ldap/lib/Migration/UUIDFix.php
+++ b/apps/user_ldap/lib/Migration/UUIDFix.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/UUIDFixGroup.php b/apps/user_ldap/lib/Migration/UUIDFixGroup.php
index c0ed3f9d48d..3924c91e7ba 100644
--- a/apps/user_ldap/lib/Migration/UUIDFixGroup.php
+++ b/apps/user_ldap/lib/Migration/UUIDFixGroup.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/UUIDFixInsert.php b/apps/user_ldap/lib/Migration/UUIDFixInsert.php
index 68b33e1b95b..bb92314d93a 100644
--- a/apps/user_ldap/lib/Migration/UUIDFixInsert.php
+++ b/apps/user_ldap/lib/Migration/UUIDFixInsert.php
@@ -1,26 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -33,23 +15,12 @@ use OCP\Migration\IRepairStep;
class UUIDFixInsert implements IRepairStep {
- /** @var IConfig */
- protected $config;
-
- /** @var UserMapping */
- protected $userMapper;
-
- /** @var GroupMapping */
- protected $groupMapper;
-
- /** @var IJobList */
- protected $jobList;
-
- public function __construct(IConfig $config, UserMapping $userMapper, GroupMapping $groupMapper, IJobList $jobList) {
- $this->config = $config;
- $this->userMapper = $userMapper;
- $this->groupMapper = $groupMapper;
- $this->jobList = $jobList;
+ public function __construct(
+ protected IConfig $config,
+ protected UserMapping $userMapper,
+ protected GroupMapping $groupMapper,
+ protected IJobList $jobList,
+ ) {
}
/**
diff --git a/apps/user_ldap/lib/Migration/UUIDFixUser.php b/apps/user_ldap/lib/Migration/UUIDFixUser.php
index 3f811e434ad..71c3f638095 100644
--- a/apps/user_ldap/lib/Migration/UUIDFixUser.php
+++ b/apps/user_ldap/lib/Migration/UUIDFixUser.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/UnsetDefaultProvider.php b/apps/user_ldap/lib/Migration/UnsetDefaultProvider.php
index a696b815856..025415cf712 100644
--- a/apps/user_ldap/lib/Migration/UnsetDefaultProvider.php
+++ b/apps/user_ldap/lib/Migration/UnsetDefaultProvider.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -32,11 +15,9 @@ use OCP\Migration\IRepairStep;
class UnsetDefaultProvider implements IRepairStep {
- /** @var IConfig */
- private $config;
-
- public function __construct(IConfig $config) {
- $this->config = $config;
+ public function __construct(
+ private IConfig $config,
+ ) {
}
public function getName(): string {
diff --git a/apps/user_ldap/lib/Migration/Version1010Date20200630192842.php b/apps/user_ldap/lib/Migration/Version1010Date20200630192842.php
index 8031741bc4d..1464e50e359 100644
--- a/apps/user_ldap/lib/Migration/Version1010Date20200630192842.php
+++ b/apps/user_ldap/lib/Migration/Version1010Date20200630192842.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/Version1120Date20210917155206.php b/apps/user_ldap/lib/Migration/Version1120Date20210917155206.php
index adc502e6747..dc3823bf771 100644
--- a/apps/user_ldap/lib/Migration/Version1120Date20210917155206.php
+++ b/apps/user_ldap/lib/Migration/Version1120Date20210917155206.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -39,17 +22,11 @@ use Psr\Log\LoggerInterface;
class Version1120Date20210917155206 extends SimpleMigrationStep {
- /** @var IDBConnection */
- private $dbc;
- /** @var IUserManager */
- private $userManager;
- /** @var LoggerInterface */
- private $logger;
-
- public function __construct(IDBConnection $dbc, IUserManager $userManager, LoggerInterface $logger) {
- $this->dbc = $dbc;
- $this->userManager = $userManager;
- $this->logger = $logger;
+ public function __construct(
+ private IDBConnection $dbc,
+ private IUserManager $userManager,
+ private LoggerInterface $logger,
+ ) {
}
public function getName() {
diff --git a/apps/user_ldap/lib/Migration/Version1130Date20211102154716.php b/apps/user_ldap/lib/Migration/Version1130Date20211102154716.php
index 5c5ed44c899..2457acd840d 100644
--- a/apps/user_ldap/lib/Migration/Version1130Date20211102154716.php
+++ b/apps/user_ldap/lib/Migration/Version1130Date20211102154716.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -39,16 +22,13 @@ use Psr\Log\LoggerInterface;
class Version1130Date20211102154716 extends SimpleMigrationStep {
- /** @var IDBConnection */
- private $dbc;
- /** @var LoggerInterface */
- private $logger;
/** @var string[] */
private $hashColumnAddedToTables = [];
- public function __construct(IDBConnection $dbc, LoggerInterface $logger) {
- $this->dbc = $dbc;
- $this->logger = $logger;
+ public function __construct(
+ private IDBConnection $dbc,
+ private LoggerInterface $logger,
+ ) {
}
public function getName() {
diff --git a/apps/user_ldap/lib/Migration/Version1130Date20220110154717.php b/apps/user_ldap/lib/Migration/Version1130Date20220110154717.php
index 2ffda4198c1..80960373edf 100644
--- a/apps/user_ldap/lib/Migration/Version1130Date20220110154717.php
+++ b/apps/user_ldap/lib/Migration/Version1130Date20220110154717.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/Version1130Date20220110154718.php b/apps/user_ldap/lib/Migration/Version1130Date20220110154718.php
index 74dd2d873bc..f67b791daad 100644
--- a/apps/user_ldap/lib/Migration/Version1130Date20220110154718.php
+++ b/apps/user_ldap/lib/Migration/Version1130Date20220110154718.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/Version1130Date20220110154719.php b/apps/user_ldap/lib/Migration/Version1130Date20220110154719.php
index 9e9ed38cb70..c34ee5357f5 100644
--- a/apps/user_ldap/lib/Migration/Version1130Date20220110154719.php
+++ b/apps/user_ldap/lib/Migration/Version1130Date20220110154719.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/Version1141Date20220323143801.php b/apps/user_ldap/lib/Migration/Version1141Date20220323143801.php
index 10043371aae..ecedbf1de20 100644
--- a/apps/user_ldap/lib/Migration/Version1141Date20220323143801.php
+++ b/apps/user_ldap/lib/Migration/Version1141Date20220323143801.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2022 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
@@ -35,10 +18,9 @@ use OCP\Migration\SimpleMigrationStep;
class Version1141Date20220323143801 extends SimpleMigrationStep {
- private IDBConnection $dbc;
-
- public function __construct(IDBConnection $dbc) {
- $this->dbc = $dbc;
+ public function __construct(
+ private IDBConnection $dbc,
+ ) {
}
/**
diff --git a/apps/user_ldap/lib/Migration/Version1190Date20230706134108.php b/apps/user_ldap/lib/Migration/Version1190Date20230706134108.php
index e0740514d75..85b046ab7c9 100644
--- a/apps/user_ldap/lib/Migration/Version1190Date20230706134108.php
+++ b/apps/user_ldap/lib/Migration/Version1190Date20230706134108.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Migration/Version1190Date20230706134109.php b/apps/user_ldap/lib/Migration/Version1190Date20230706134109.php
index 2cb68e25dc5..2d3c26f0d49 100644
--- a/apps/user_ldap/lib/Migration/Version1190Date20230706134109.php
+++ b/apps/user_ldap/lib/Migration/Version1190Date20230706134109.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Migration;
diff --git a/apps/user_ldap/lib/Notification/Notifier.php b/apps/user_ldap/lib/Notification/Notifier.php
index 04c03febb0e..0195cb9e65b 100644
--- a/apps/user_ldap/lib/Notification/Notifier.php
+++ b/apps/user_ldap/lib/Notification/Notifier.php
@@ -1,44 +1,24 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Roger Szabo <roger.szabo@web.de>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Notification;
use OCP\L10N\IFactory;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
+use OCP\Notification\UnknownNotificationException;
class Notifier implements INotifier {
- /** @var IFactory */
- protected $l10nFactory;
-
/**
* @param IFactory $l10nFactory
*/
- public function __construct(\OCP\L10N\IFactory $l10nFactory) {
- $this->l10nFactory = $l10nFactory;
+ public function __construct(
+ protected IFactory $l10nFactory,
+ ) {
}
/**
@@ -65,12 +45,12 @@ class Notifier implements INotifier {
* @param INotification $notification
* @param string $languageCode The code of the language that should be used to prepare the notification
* @return INotification
- * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+ * @throws UnknownNotificationException When the notification was not prepared by a notifier
*/
public function prepare(INotification $notification, string $languageCode): INotification {
if ($notification->getApp() !== 'user_ldap') {
// Not my app => throw
- throw new \InvalidArgumentException();
+ throw new UnknownNotificationException();
}
// Read the language from the notification
@@ -80,7 +60,7 @@ class Notifier implements INotifier {
// Deal with known subjects
case 'pwd_exp_warn_days':
$params = $notification->getSubjectParameters();
- $days = (int) $params[0];
+ $days = (int)$params[0];
if ($days === 2) {
$notification->setParsedSubject($l->t('Your password will expire tomorrow.'));
} elseif ($days === 1) {
@@ -96,7 +76,7 @@ class Notifier implements INotifier {
default:
// Unknown subject => Unknown notification => throw
- throw new \InvalidArgumentException();
+ throw new UnknownNotificationException();
}
}
}
diff --git a/apps/user_ldap/lib/PagedResults/TLinkId.php b/apps/user_ldap/lib/PagedResults/TLinkId.php
index 02c36da97f9..46d392995e0 100644
--- a/apps/user_ldap/lib/PagedResults/TLinkId.php
+++ b/apps/user_ldap/lib/PagedResults/TLinkId.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\PagedResults;
diff --git a/apps/user_ldap/lib/Proxy.php b/apps/user_ldap/lib/Proxy.php
index e2e33f3007b..22b2c6617af 100644
--- a/apps/user_ldap/lib/Proxy.php
+++ b/apps/user_ldap/lib/Proxy.php
@@ -1,62 +1,75 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
use OCA\User_LDAP\Mapping\GroupMapping;
use OCA\User_LDAP\Mapping\UserMapping;
use OCP\ICache;
+use OCP\ICacheFactory;
use OCP\Server;
+/**
+ * @template T
+ */
abstract class Proxy {
/** @var array<string,Access> */
private static array $accesses = [];
- private ILDAPWrapper $ldap;
private ?bool $isSingleBackend = null;
private ?ICache $cache = null;
- private AccessFactory $accessFactory;
+
+ /** @var T[] */
+ protected array $backends = [];
+ /** @var ?T */
+ protected $refBackend = null;
+
+ protected bool $isSetUp = false;
public function __construct(
- ILDAPWrapper $ldap,
- AccessFactory $accessFactory
+ private Helper $helper,
+ private ILDAPWrapper $ldap,
+ private AccessFactory $accessFactory,
) {
- $this->ldap = $ldap;
- $this->accessFactory = $accessFactory;
- $memcache = \OC::$server->getMemCacheFactory();
+ $memcache = Server::get(ICacheFactory::class);
if ($memcache->isAvailable()) {
$this->cache = $memcache->createDistributed();
}
}
+ protected function setup(): void {
+ if ($this->isSetUp) {
+ return;
+ }
+
+ $serverConfigPrefixes = $this->helper->getServerConfigurationPrefixes(true);
+ foreach ($serverConfigPrefixes as $configPrefix) {
+ $this->backends[$configPrefix] = $this->newInstance($configPrefix);
+
+ if (is_null($this->refBackend)) {
+ $this->refBackend = $this->backends[$configPrefix];
+ }
+ }
+
+ $this->isSetUp = true;
+ }
+
+ /**
+ * @return T
+ */
+ abstract protected function newInstance(string $configPrefix): object;
+
+ /**
+ * @return T
+ */
+ public function getBackend(string $configPrefix): object {
+ $this->setup();
+ return $this->backends[$configPrefix];
+ }
+
private function addAccess(string $configPrefix): void {
$userMap = Server::get(UserMapping::class);
$groupMap = Server::get(GroupMapping::class);
diff --git a/apps/user_ldap/lib/Service/BirthdateParserService.php b/apps/user_ldap/lib/Service/BirthdateParserService.php
new file mode 100644
index 00000000000..8234161b3d8
--- /dev/null
+++ b/apps/user_ldap/lib/Service/BirthdateParserService.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\User_LDAP\Service;
+
+use DateTimeImmutable;
+use Exception;
+use InvalidArgumentException;
+
+class BirthdateParserService {
+ /**
+ * Try to parse the birthdate from LDAP.
+ * Supports LDAP's generalized time syntax, YYYYMMDD and YYYY-MM-DD.
+ *
+ * @throws InvalidArgumentException If the format of then given date is unknown
+ */
+ public function parseBirthdate(string $value): DateTimeImmutable {
+ // Minimum LDAP generalized date is "1994121610Z" with 11 chars
+ // While maximum other format is "1994-12-16" with 10 chars
+ if (strlen($value) > strlen('YYYY-MM-DD')) {
+ // Probably LDAP generalized time syntax
+ $value = substr($value, 0, 8);
+ }
+
+ // Should be either YYYYMMDD or YYYY-MM-DD
+ if (!preg_match('/^(\d{8}|\d{4}-\d{2}-\d{2})$/', $value)) {
+ throw new InvalidArgumentException("Unknown date format: $value");
+ }
+
+ try {
+ return new DateTimeImmutable($value);
+ } catch (Exception $e) {
+ throw new InvalidArgumentException(
+ "Unknown date format: $value",
+ 0,
+ $e,
+ );
+ }
+ }
+}
diff --git a/apps/user_ldap/lib/Service/UpdateGroupsService.php b/apps/user_ldap/lib/Service/UpdateGroupsService.php
index 79cd809ff6a..94f2a7fd4a1 100644
--- a/apps/user_ldap/lib/Service/UpdateGroupsService.php
+++ b/apps/user_ldap/lib/Service/UpdateGroupsService.php
@@ -3,32 +3,9 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\Service;
@@ -113,7 +90,7 @@ class UpdateGroupsService {
if ($e->getReason() !== Exception::REASON_DATABASE_OBJECT_NOT_FOUND) {
/* If reason is not found something else removed the membership, that’s fine */
$this->logger->error(
- __CLASS__ . ' - group {group} membership failed to be removed (user {user})',
+ self::class . ' - group {group} membership failed to be removed (user {user})',
[
'app' => 'user_ldap',
'user' => $removedUser,
@@ -144,7 +121,7 @@ class UpdateGroupsService {
if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
/* If reason is unique constraint something else added the membership, that’s fine */
$this->logger->error(
- __CLASS__ . ' - group {group} membership failed to be added (user {user})',
+ self::class . ' - group {group} membership failed to be added (user {user})',
[
'app' => 'user_ldap',
'user' => $addedUser,
@@ -190,7 +167,7 @@ class UpdateGroupsService {
} catch (Exception $e) {
if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
$this->logger->error(
- __CLASS__ . ' - group {group} membership failed to be added (user {user})',
+ self::class . ' - group {group} membership failed to be added (user {user})',
[
'app' => 'user_ldap',
'user' => $user,
diff --git a/apps/user_ldap/lib/Settings/Admin.php b/apps/user_ldap/lib/Settings/Admin.php
index 21805b6f7b5..89fb063265b 100644
--- a/apps/user_ldap/lib/Settings/Admin.php
+++ b/apps/user_ldap/lib/Settings/Admin.php
@@ -1,27 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Settings;
@@ -29,25 +10,22 @@ use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\Helper;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IL10N;
+use OCP\Server;
use OCP\Settings\IDelegatedSettings;
-use OCP\Template;
+use OCP\Template\ITemplateManager;
class Admin implements IDelegatedSettings {
- /** @var IL10N */
- private $l;
-
- /**
- * @param IL10N $l
- */
- public function __construct(IL10N $l) {
- $this->l = $l;
+ public function __construct(
+ private IL10N $l,
+ private ITemplateManager $templateManager,
+ ) {
}
/**
* @return TemplateResponse
*/
public function getForm() {
- $helper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
+ $helper = Server::get(Helper::class);
$prefixes = $helper->getServerConfigurationPrefixes();
if (count($prefixes) === 0) {
$newPrefix = $helper->getNextServerConfigurationPrefix();
@@ -59,11 +37,12 @@ class Admin implements IDelegatedSettings {
$hosts = $helper->getServerConfigurationHosts();
- $wControls = new Template('user_ldap', 'part.wizardcontrols');
+ $wControls = $this->templateManager->getTemplate('user_ldap', 'part.wizardcontrols');
$wControls = $wControls->fetchPage();
- $sControls = new Template('user_ldap', 'part.settingcontrols');
+ $sControls = $this->templateManager->getTemplate('user_ldap', 'part.settingcontrols');
$sControls = $sControls->fetchPage();
+ $parameters = [];
$parameters['serverConfigurationPrefixes'] = $prefixes;
$parameters['serverConfigurationHosts'] = $hosts;
$parameters['settingControls'] = $sControls;
@@ -75,7 +54,7 @@ class Admin implements IDelegatedSettings {
}
$defaults = $config->getDefaults();
foreach ($defaults as $key => $default) {
- $parameters[$key.'_default'] = $default;
+ $parameters[$key . '_default'] = $default;
}
return new TemplateResponse('user_ldap', 'settings', $parameters);
@@ -90,8 +69,8 @@ class Admin implements IDelegatedSettings {
/**
* @return int whether the form should be rather on the top or bottom of
- * the admin section. The forms are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
+ * the admin section. The forms are arranged in ascending order of the
+ * priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
*/
diff --git a/apps/user_ldap/lib/Settings/Section.php b/apps/user_ldap/lib/Settings/Section.php
index 7c4bc5bf44d..3b95e25513d 100644
--- a/apps/user_ldap/lib/Settings/Section.php
+++ b/apps/user_ldap/lib/Settings/Section.php
@@ -1,27 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Valdnet <47037905+Valdnet@users.noreply.github.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\Settings;
@@ -30,18 +11,14 @@ use OCP\IURLGenerator;
use OCP\Settings\IIconSection;
class Section implements IIconSection {
- /** @var IL10N */
- private $l;
- /** @var IURLGenerator */
- private $url;
-
/**
* @param IURLGenerator $url
* @param IL10N $l
*/
- public function __construct(IURLGenerator $url, IL10N $l) {
- $this->url = $url;
- $this->l = $l;
+ public function __construct(
+ private IURLGenerator $url,
+ private IL10N $l,
+ ) {
}
/**
@@ -66,8 +43,8 @@ class Section implements IIconSection {
/**
* @return int whether the form should be rather on the top or bottom of
- * the settings navigation. The sections are arranged in ascending order of
- * the priority values. It is required to return a value between 0 and 99.
+ * the settings navigation. The sections are arranged in ascending order of
+ * the priority values. It is required to return a value between 0 and 99.
*
* E.g.: 70
*/
diff --git a/apps/user_ldap/lib/SetupChecks/LdapConnection.php b/apps/user_ldap/lib/SetupChecks/LdapConnection.php
index 63877ff06ae..ee8c4ddd595 100644
--- a/apps/user_ldap/lib/SetupChecks/LdapConnection.php
+++ b/apps/user_ldap/lib/SetupChecks/LdapConnection.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2024 Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\SetupChecks;
@@ -75,26 +58,26 @@ class LdapConnection implements ISetupCheck {
if (!empty($bindFailedConfigurations)) {
$output .= $this->l10n->n(
'Binding failed for this LDAP configuration: %s',
- 'Binding failed for these LDAP configurations: %s',
+ 'Binding failed for %n LDAP configurations: %s',
count($bindFailedConfigurations),
[implode(',', $bindFailedConfigurations)]
- )."\n";
+ ) . "\n";
}
if (!empty($searchFailedConfigurations)) {
$output .= $this->l10n->n(
'Searching failed for this LDAP configuration: %s',
- 'Searching failed for these LDAP configurations: %s',
+ 'Searching failed for %n LDAP configurations: %s',
count($searchFailedConfigurations),
[implode(',', $searchFailedConfigurations)]
- )."\n";
+ ) . "\n";
}
if (!empty($inactiveConfigurations)) {
$output .= $this->l10n->n(
'There is an inactive LDAP configuration: %s',
- 'There are inactive LDAP configurations: %s',
+ 'There are %n inactive LDAP configurations: %s',
count($inactiveConfigurations),
[implode(',', $inactiveConfigurations)]
- )."\n";
+ ) . "\n";
}
if (!empty($bindFailedConfigurations) || !empty($searchFailedConfigurations)) {
return SetupResult::error($output);
@@ -103,7 +86,7 @@ class LdapConnection implements ISetupCheck {
}
return SetupResult::success($this->l10n->n(
'Binding and searching works on the configured LDAP connection (%s)',
- 'Binding and searching works on all of the configured LDAP connections (%s)',
+ 'Binding and searching works on all of the %n configured LDAP connections (%s)',
count($availableConfigs),
[implode(',', $availableConfigs)]
));
diff --git a/apps/user_ldap/lib/SetupChecks/LdapInvalidUuids.php b/apps/user_ldap/lib/SetupChecks/LdapInvalidUuids.php
index 2cf3b700b01..ac502b6b59e 100644
--- a/apps/user_ldap/lib/SetupChecks/LdapInvalidUuids.php
+++ b/apps/user_ldap/lib/SetupChecks/LdapInvalidUuids.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2022 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP\SetupChecks;
diff --git a/apps/user_ldap/lib/User/DeletedUsersIndex.php b/apps/user_ldap/lib/User/DeletedUsersIndex.php
index d679ca86d93..f57f71a9d47 100644
--- a/apps/user_ldap/lib/User/DeletedUsersIndex.php
+++ b/apps/user_ldap/lib/User/DeletedUsersIndex.php
@@ -1,30 +1,14 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\User;
use OCA\User_LDAP\Mapping\UserMapping;
use OCP\IConfig;
+use OCP\PreConditionNotMetException;
use OCP\Share\IManager;
/**
@@ -32,19 +16,13 @@ use OCP\Share\IManager;
* @package OCA\User_LDAP
*/
class DeletedUsersIndex {
- protected IConfig $config;
- protected UserMapping $mapping;
protected ?array $deletedUsers = null;
- private IManager $shareManager;
public function __construct(
- IConfig $config,
- UserMapping $mapping,
- IManager $shareManager
+ protected IConfig $config,
+ protected UserMapping $mapping,
+ private IManager $shareManager,
) {
- $this->config = $config;
- $this->mapping = $mapping;
- $this->shareManager = $shareManager;
}
/**
@@ -56,7 +34,12 @@ class DeletedUsersIndex {
$userObjects = [];
foreach ($deletedUsers as $user) {
- $userObjects[] = new OfflineUser($user, $this->config, $this->mapping, $this->shareManager);
+ $userObject = new OfflineUser($user, $this->config, $this->mapping, $this->shareManager);
+ if ($userObject->getLastLogin() > $userObject->getDetectedOn()) {
+ $userObject->unmark();
+ } else {
+ $userObjects[] = $userObject;
+ }
}
$this->deletedUsers = $userObjects;
@@ -87,7 +70,7 @@ class DeletedUsersIndex {
/**
* marks a user as deleted
*
- * @throws \OCP\PreConditionNotMetException
+ * @throws PreConditionNotMetException
*/
public function markUser(string $ocName): void {
if ($this->isUserMarked($ocName)) {
diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index 9d3ba333e89..88a001dd965 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -1,36 +1,13 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Marc Hefter <marchefter@march42.net>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\User;
use OCA\User_LDAP\Access;
-use OCA\User_LDAP\FilesystemHelper;
use OCP\Cache\CappedMemoryCache;
use OCP\IAvatarManager;
use OCP\IConfig;
@@ -49,40 +26,23 @@ use Psr\Log\LoggerInterface;
*/
class Manager {
protected ?Access $access = null;
- protected IConfig $ocConfig;
protected IDBConnection $db;
- protected IUserManager $userManager;
- protected INotificationManager $notificationManager;
- protected FilesystemHelper $ocFilesystem;
- protected LoggerInterface $logger;
- protected Image $image;
- protected IAvatarManager $avatarManager;
/** @var CappedMemoryCache<User> $usersByDN */
protected CappedMemoryCache $usersByDN;
/** @var CappedMemoryCache<User> $usersByUid */
protected CappedMemoryCache $usersByUid;
- private IManager $shareManager;
public function __construct(
- IConfig $ocConfig,
- FilesystemHelper $ocFilesystem,
- LoggerInterface $logger,
- IAvatarManager $avatarManager,
- Image $image,
- IUserManager $userManager,
- INotificationManager $notificationManager,
- IManager $shareManager
+ protected IConfig $ocConfig,
+ protected LoggerInterface $logger,
+ protected IAvatarManager $avatarManager,
+ protected Image $image,
+ protected IUserManager $userManager,
+ protected INotificationManager $notificationManager,
+ private IManager $shareManager,
) {
- $this->ocConfig = $ocConfig;
- $this->ocFilesystem = $ocFilesystem;
- $this->logger = $logger;
- $this->avatarManager = $avatarManager;
- $this->image = $image;
- $this->userManager = $userManager;
- $this->notificationManager = $notificationManager;
$this->usersByDN = new CappedMemoryCache();
$this->usersByUid = new CappedMemoryCache();
- $this->shareManager = $shareManager;
}
/**
@@ -99,12 +59,12 @@ class Manager {
* property array
* @param string $dn the DN of the user
* @param string $uid the internal (owncloud) username
- * @return \OCA\User_LDAP\User\User
+ * @return User
*/
private function createAndCache($dn, $uid) {
$this->checkAccess();
$user = new User($uid, $dn, $this->access, $this->ocConfig,
- $this->ocFilesystem, clone $this->image, $this->logger,
+ clone $this->image, $this->logger,
$this->avatarManager, $this->userManager,
$this->notificationManager);
$this->usersByDN[$dn] = $user;
@@ -128,6 +88,7 @@ class Manager {
/**
* @brief checks whether the Access instance has been set
* @throws \Exception if Access has not been set
+ * @psalm-assert !null $this->access
* @return null
*/
private function checkAccess() {
@@ -141,13 +102,14 @@ class Manager {
* email, displayname, or others.
*
* @param bool $minimal - optional, set to true to skip attributes with big
- * payload
+ * payload
* @return string[]
*/
public function getAttributes($minimal = false) {
$baseAttributes = array_merge(Access::UUID_ATTRIBUTES, ['dn', 'uid', 'samaccountname', 'memberof']);
$attributes = [
$this->access->getConnection()->ldapExpertUUIDUserAttr,
+ $this->access->getConnection()->ldapExpertUsernameAttr,
$this->access->getConnection()->ldapQuotaAttribute,
$this->access->getConnection()->ldapEmailAttribute,
$this->access->getConnection()->ldapUserDisplayName,
@@ -162,6 +124,8 @@ class Manager {
$this->access->getConnection()->ldapAttributeRole,
$this->access->getConnection()->ldapAttributeHeadline,
$this->access->getConnection()->ldapAttributeBiography,
+ $this->access->getConnection()->ldapAttributeBirthDate,
+ $this->access->getConnection()->ldapAttributePronouns,
];
$homeRule = (string)$this->access->getConnection()->homeFolderNamingRule;
@@ -207,7 +171,7 @@ class Manager {
/**
* creates and returns an instance of OfflineUser for the specified user
* @param string $id
- * @return \OCA\User_LDAP\User\OfflineUser
+ * @return OfflineUser
*/
public function getDeletedUser($id) {
return new OfflineUser(
@@ -221,7 +185,7 @@ class Manager {
/**
* @brief returns a User object by its Nextcloud username
* @param string $id the DN or username of the user
- * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
+ * @return User|OfflineUser|null
*/
protected function createInstancyByUserName($id) {
//most likely a uid. Check whether it is a deleted user
@@ -238,7 +202,7 @@ class Manager {
/**
* @brief returns a User object by its DN or Nextcloud username
* @param string $id the DN or username of the user
- * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
+ * @return User|OfflineUser|null
* @throws \Exception when connection could not be established
*/
public function get($id) {
@@ -258,4 +222,37 @@ class Manager {
return $this->createInstancyByUserName($id);
}
+
+ /**
+ * @brief Checks whether a User object by its DN or Nextcloud username exists
+ * @param string $id the DN or username of the user
+ * @throws \Exception when connection could not be established
+ */
+ public function exists($id): bool {
+ $this->checkAccess();
+ $this->logger->debug('Checking if {id} exists', ['id' => $id]);
+ if (isset($this->usersByDN[$id])) {
+ return true;
+ } elseif (isset($this->usersByUid[$id])) {
+ return true;
+ }
+
+ if ($this->access->stringResemblesDN($id)) {
+ $this->logger->debug('{id} looks like a dn', ['id' => $id]);
+ $uid = $this->access->dn2username($id);
+ if ($uid !== false) {
+ return true;
+ }
+ }
+
+ // Most likely a uid. Check whether it is a deleted user
+ if ($this->isDeletedUser($id)) {
+ return true;
+ }
+ $dn = $this->access->username2dn($id);
+ if ($dn !== false) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/apps/user_ldap/lib/User/OfflineUser.php b/apps/user_ldap/lib/User/OfflineUser.php
index e39c4b0bb99..ecaab7188ba 100644
--- a/apps/user_ldap/lib/User/OfflineUser.php
+++ b/apps/user_ldap/lib/User/OfflineUser.php
@@ -1,27 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\User;
@@ -33,10 +15,6 @@ use OCP\Share\IShare;
class OfflineUser {
/**
- * @var string $ocName
- */
- protected $ocName;
- /**
* @var string $dn
*/
protected $dn;
@@ -70,30 +48,19 @@ class OfflineUser {
*/
protected $hasActiveShares;
/**
- * @var IConfig $config
- */
- protected $config;
- /**
* @var IDBConnection $db
*/
protected $db;
+
/**
- * @var \OCA\User_LDAP\Mapping\UserMapping
+ * @param string $ocName
*/
- protected $mapping;
- /** @var IManager */
- private $shareManager;
-
public function __construct(
- $ocName,
- IConfig $config,
- UserMapping $mapping,
- IManager $shareManager
+ protected $ocName,
+ protected IConfig $config,
+ protected UserMapping $mapping,
+ private IManager $shareManager,
) {
- $this->ocName = $ocName;
- $this->config = $config;
- $this->mapping = $mapping;
- $this->shareManager = $shareManager;
}
/**
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index c3e9895e043..8f97ec1701f 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -1,51 +1,30 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
- * @author Marc Hefter <marchefter@march42.net>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Philipp Staiger <philipp@staiger.it>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP\User;
+use InvalidArgumentException;
use OC\Accounts\AccountManager;
use OCA\User_LDAP\Access;
use OCA\User_LDAP\Connection;
use OCA\User_LDAP\Exceptions\AttributeNotSet;
-use OCA\User_LDAP\FilesystemHelper;
+use OCA\User_LDAP\Service\BirthdateParserService;
use OCP\Accounts\IAccountManager;
use OCP\Accounts\PropertyDoesNotExistException;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\Image;
+use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
+use OCP\PreConditionNotMetException;
use OCP\Server;
+use OCP\Util;
use Psr\Log\LoggerInterface;
/**
@@ -54,102 +33,51 @@ use Psr\Log\LoggerInterface;
* represents an LDAP user, gets and holds user-specific information from LDAP
*/
class User {
+ protected Connection $connection;
/**
- * @var Access
- */
- protected $access;
- /**
- * @var Connection
- */
- protected $connection;
- /**
- * @var IConfig
- */
- protected $config;
- /**
- * @var FilesystemHelper
- */
- protected $fs;
- /**
- * @var Image
- */
- protected $image;
- /**
- * @var LoggerInterface
- */
- protected $logger;
- /**
- * @var IAvatarManager
- */
- protected $avatarManager;
- /**
- * @var IUserManager
- */
- protected $userManager;
- /**
- * @var INotificationManager
- */
- protected $notificationManager;
- /**
- * @var string
- */
- protected $dn;
- /**
- * @var string
- */
- protected $uid;
- /**
- * @var string[]
- */
- protected $refreshedFeatures = [];
- /**
- * @var string
+ * @var array<string,1>
*/
- protected $avatarImage;
+ protected array $refreshedFeatures = [];
+ protected string|false|null $avatarImage = null;
+
+ protected BirthdateParserService $birthdateParser;
/**
* DB config keys for user preferences
+ * @var string
*/
public const USER_PREFKEY_FIRSTLOGIN = 'firstLoginAccomplished';
/**
* @brief constructor, make sure the subclasses call this one!
- * @param string $username the internal username
- * @param string $dn the LDAP DN
*/
- public function __construct($username, $dn, Access $access,
- IConfig $config, FilesystemHelper $fs, Image $image,
- LoggerInterface $logger, IAvatarManager $avatarManager, IUserManager $userManager,
- INotificationManager $notificationManager) {
- if ($username === null) {
- $logger->error("uid for '$dn' must not be null!", ['app' => 'user_ldap']);
- throw new \InvalidArgumentException('uid must not be null!');
- } elseif ($username === '') {
+ public function __construct(
+ protected string $uid,
+ protected string $dn,
+ protected Access $access,
+ protected IConfig $config,
+ protected Image $image,
+ protected LoggerInterface $logger,
+ protected IAvatarManager $avatarManager,
+ protected IUserManager $userManager,
+ protected INotificationManager $notificationManager,
+ ) {
+ if ($uid === '') {
$logger->error("uid for '$dn' must not be an empty string", ['app' => 'user_ldap']);
throw new \InvalidArgumentException('uid must not be an empty string!');
}
+ $this->connection = $this->access->getConnection();
+ $this->birthdateParser = new BirthdateParserService();
- $this->access = $access;
- $this->connection = $access->getConnection();
- $this->config = $config;
- $this->fs = $fs;
- $this->dn = $dn;
- $this->uid = $username;
- $this->image = $image;
- $this->logger = $logger;
- $this->avatarManager = $avatarManager;
- $this->userManager = $userManager;
- $this->notificationManager = $notificationManager;
-
- \OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
+ Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
}
/**
* marks a user as deleted
*
- * @throws \OCP\PreConditionNotMetException
+ * @throws PreConditionNotMetException
*/
- public function markUser() {
+ public function markUser(): void {
$curValue = $this->config->getUserValue($this->getUsername(), 'user_ldap', 'isDeleted', '0');
if ($curValue === '1') {
// the user is already marked, do not write to DB again
@@ -163,7 +91,7 @@ class User {
* processes results from LDAP for attributes as returned by getAttributesToRead()
* @param array $ldapEntry the user entry as retrieved from LDAP
*/
- public function processAttributes($ldapEntry) {
+ public function processAttributes(array $ldapEntry): void {
//Quota
$attr = strtolower($this->connection->ldapQuotaAttribute);
if (isset($ldapEntry[$attr])) {
@@ -200,7 +128,14 @@ class User {
//change event that will trigger fetching the display name again
$attr = strtolower($this->connection->ldapEmailAttribute);
if (isset($ldapEntry[$attr])) {
- $this->updateEmail($ldapEntry[$attr][0]);
+ $mailValue = 0;
+ for ($x = 0; $x < count($ldapEntry[$attr]); $x++) {
+ if (filter_var($ldapEntry[$attr][$x], FILTER_VALIDATE_EMAIL)) {
+ $mailValue = $x;
+ break;
+ }
+ }
+ $this->updateEmail($ldapEntry[$attr][$mailValue]);
}
unset($attr);
@@ -221,7 +156,7 @@ class User {
}
//memberOf groups
- $cacheKey = 'getMemberOf'.$this->getUsername();
+ $cacheKey = 'getMemberOf' . $this->getUsername();
$groups = false;
if (isset($ldapEntry['memberof'])) {
$groups = $ldapEntry['memberof'];
@@ -237,92 +172,114 @@ class User {
// check for cached profile data
$username = $this->getUsername(); // buffer variable, to save resource
- $cacheKey = 'getUserProfile-'.$username;
+ $cacheKey = 'getUserProfile-' . $username;
$profileCached = $this->connection->getFromCache($cacheKey);
// honoring profile disabled in config.php and check if user profile was refreshed
- if ($this->config->getSystemValueBool('profile.enabled', true) &&
- ($profileCached === null) && // no cache or TTL not expired
- !$this->wasRefreshed('profile')) {
+ if ($this->config->getSystemValueBool('profile.enabled', true)
+ && ($profileCached === null) // no cache or TTL not expired
+ && !$this->wasRefreshed('profile')) {
// check current data
$profileValues = [];
//User Profile Field - Phone number
$attr = strtolower($this->connection->ldapAttributePhone);
if (!empty($attr)) { // attribute configured
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_PHONE]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_PHONE]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - website
$attr = strtolower($this->connection->ldapAttributeWebsite);
if (isset($ldapEntry[$attr])) {
- $cutPosition = strpos($ldapEntry[$attr][0], " ");
+ $cutPosition = strpos($ldapEntry[$attr][0], ' ');
if ($cutPosition) {
// drop appended label
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_WEBSITE]
+ $profileValues[IAccountManager::PROPERTY_WEBSITE]
= substr($ldapEntry[$attr][0], 0, $cutPosition);
} else {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_WEBSITE]
+ $profileValues[IAccountManager::PROPERTY_WEBSITE]
= $ldapEntry[$attr][0];
}
} elseif (!empty($attr)) { // configured, but not defined
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_WEBSITE] = "";
+ $profileValues[IAccountManager::PROPERTY_WEBSITE] = '';
}
//User Profile Field - Address
$attr = strtolower($this->connection->ldapAttributeAddress);
if (isset($ldapEntry[$attr])) {
if (str_contains($ldapEntry[$attr][0], '$')) {
// basic format conversion from postalAddress syntax to commata delimited
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_ADDRESS]
- = str_replace('$', ", ", $ldapEntry[$attr][0]);
+ $profileValues[IAccountManager::PROPERTY_ADDRESS]
+ = str_replace('$', ', ', $ldapEntry[$attr][0]);
} else {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_ADDRESS]
+ $profileValues[IAccountManager::PROPERTY_ADDRESS]
= $ldapEntry[$attr][0];
}
} elseif (!empty($attr)) { // configured, but not defined
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_ADDRESS] = "";
+ $profileValues[IAccountManager::PROPERTY_ADDRESS] = '';
}
//User Profile Field - Twitter
$attr = strtolower($this->connection->ldapAttributeTwitter);
if (!empty($attr)) {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_TWITTER]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_TWITTER]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - fediverse
$attr = strtolower($this->connection->ldapAttributeFediverse);
if (!empty($attr)) {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_FEDIVERSE]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_FEDIVERSE]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - organisation
$attr = strtolower($this->connection->ldapAttributeOrganisation);
if (!empty($attr)) {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_ORGANISATION]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_ORGANISATION]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - role
$attr = strtolower($this->connection->ldapAttributeRole);
if (!empty($attr)) {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_ROLE]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_ROLE]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - headline
$attr = strtolower($this->connection->ldapAttributeHeadline);
if (!empty($attr)) {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_HEADLINE]
- = $ldapEntry[$attr][0] ?? "";
+ $profileValues[IAccountManager::PROPERTY_HEADLINE]
+ = $ldapEntry[$attr][0] ?? '';
}
//User Profile Field - biography
$attr = strtolower($this->connection->ldapAttributeBiography);
if (isset($ldapEntry[$attr])) {
if (str_contains($ldapEntry[$attr][0], '\r')) {
// convert line endings
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_BIOGRAPHY]
+ $profileValues[IAccountManager::PROPERTY_BIOGRAPHY]
= str_replace(["\r\n","\r"], "\n", $ldapEntry[$attr][0]);
} else {
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_BIOGRAPHY]
+ $profileValues[IAccountManager::PROPERTY_BIOGRAPHY]
= $ldapEntry[$attr][0];
}
} elseif (!empty($attr)) { // configured, but not defined
- $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_BIOGRAPHY] = "";
+ $profileValues[IAccountManager::PROPERTY_BIOGRAPHY] = '';
+ }
+ //User Profile Field - birthday
+ $attr = strtolower($this->connection->ldapAttributeBirthDate);
+ if (!empty($attr) && !empty($ldapEntry[$attr][0])) {
+ $value = $ldapEntry[$attr][0];
+ try {
+ $birthdate = $this->birthdateParser->parseBirthdate($value);
+ $profileValues[IAccountManager::PROPERTY_BIRTHDATE]
+ = $birthdate->format('Y-m-d');
+ } catch (InvalidArgumentException $e) {
+ // Invalid date -> just skip the property
+ $this->logger->info("Failed to parse user's birthdate from LDAP: $value", [
+ 'exception' => $e,
+ 'userId' => $username,
+ ]);
+ }
+ }
+ //User Profile Field - pronouns
+ $attr = strtolower($this->connection->ldapAttributePronouns);
+ if (!empty($attr)) {
+ $profileValues[IAccountManager::PROPERTY_PRONOUNS]
+ = $ldapEntry[$attr][0] ?? '';
}
// check for changed data and cache just for TTL checking
$checksum = hash('sha256', json_encode($profileValues));
@@ -334,11 +291,11 @@ class User {
$this->updateProfile($profileValues);
$this->logger->info("updated profile uid=$username", ['app' => 'user_ldap']);
} else {
- $this->logger->debug("profile data from LDAP unchanged", ['app' => 'user_ldap', 'uid' => $username]);
+ $this->logger->debug('profile data from LDAP unchanged', ['app' => 'user_ldap', 'uid' => $username]);
}
unset($attr);
} elseif ($profileCached !== null) { // message delayed, to declutter log
- $this->logger->debug("skipping profile check, while cached data exist", ['app' => 'user_ldap', 'uid' => $username]);
+ $this->logger->debug('skipping profile check, while cached data exist', ['app' => 'user_ldap', 'uid' => $username]);
}
//Avatar
@@ -348,11 +305,7 @@ class User {
foreach ($attributes as $attribute) {
if (isset($ldapEntry[$attribute])) {
$this->avatarImage = $ldapEntry[$attribute][0];
- // the call to the method that saves the avatar in the file
- // system must be postponed after the login. It is to ensure
- // external mounts are mounted properly (e.g. with login
- // credentials from the session).
- \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
+ $this->updateAvatar();
break;
}
}
@@ -376,11 +329,9 @@ class User {
/**
* returns the home directory of the user if specified by LDAP settings
- * @param ?string $valueFromLDAP
- * @return false|string
* @throws \Exception
*/
- public function getHomePath($valueFromLDAP = null) {
+ public function getHomePath(?string $valueFromLDAP = null): string|false {
$path = (string)$valueFromLDAP;
$attr = null;
@@ -388,8 +339,12 @@ class User {
&& str_starts_with($this->access->connection->homeFolderNamingRule, 'attr:')
&& $this->access->connection->homeFolderNamingRule !== 'attr:') {
$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
- $homedir = $this->access->readAttribute($this->access->username2dn($this->getUsername()), $attr);
- if ($homedir && isset($homedir[0])) {
+ $dn = $this->access->username2dn($this->getUsername());
+ if ($dn === false) {
+ return false;
+ }
+ $homedir = $this->access->readAttribute($dn, $attr);
+ if ($homedir !== false && isset($homedir[0])) {
$path = $homedir[0];
}
}
@@ -402,7 +357,7 @@ class User {
&& $path[1] === ':' && ($path[2] === '\\' || $path[2] === '/'))
) {
$path = $this->config->getSystemValue('datadirectory',
- \OC::$SERVERROOT.'/data') . '/' . $path;
+ \OC::$SERVERROOT . '/data') . '/' . $path;
}
//we need it to store it in the DB as well in case a user gets
//deleted so we can clean up afterwards
@@ -424,8 +379,8 @@ class User {
return false;
}
- public function getMemberOfGroups() {
- $cacheKey = 'getMemberOf'.$this->getUsername();
+ public function getMemberOfGroups(): array|false {
+ $cacheKey = 'getMemberOf' . $this->getUsername();
$memberOfGroups = $this->connection->getFromCache($cacheKey);
if (!is_null($memberOfGroups)) {
return $memberOfGroups;
@@ -437,9 +392,9 @@ class User {
/**
* @brief reads the image from LDAP that shall be used as Avatar
- * @return string data (provided by LDAP) | false
+ * @return string|false data (provided by LDAP)
*/
- public function getAvatarImage() {
+ public function getAvatarImage(): string|false {
if (!is_null($this->avatarImage)) {
return $this->avatarImage;
}
@@ -450,7 +405,7 @@ class User {
$attributes = $connection->resolveRule('avatar');
foreach ($attributes as $attribute) {
$result = $this->access->readAttribute($this->dn, $attribute);
- if ($result !== false && is_array($result) && isset($result[0])) {
+ if ($result !== false && isset($result[0])) {
$this->avatarImage = $result[0];
break;
}
@@ -461,20 +416,16 @@ class User {
/**
* @brief marks the user as having logged in at least once
- * @return null
*/
- public function markLogin() {
+ public function markLogin(): void {
$this->config->setUserValue(
$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, '1');
}
/**
* Stores a key-value pair in relation to this user
- *
- * @param string $key
- * @param string $value
*/
- private function store($key, $value) {
+ private function store(string $key, string $value): void {
$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
}
@@ -482,12 +433,9 @@ class User {
* Composes the display name and stores it in the database. The final
* display name is returned.
*
- * @param string $displayName
- * @param string $displayName2
* @return string the effective display name
*/
- public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
- $displayName2 = (string)$displayName2;
+ public function composeAndStoreDisplayName(string $displayName, string $displayName2 = ''): string {
if ($displayName2 !== '') {
$displayName .= ' (' . $displayName2 . ')';
}
@@ -506,9 +454,8 @@ class User {
/**
* Stores the LDAP Username in the Database
- * @param string $userName
*/
- public function storeLDAPUserName($userName) {
+ public function storeLDAPUserName(string $userName): void {
$this->store('uid', $userName);
}
@@ -517,9 +464,8 @@ class User {
* already. If not, it will marked like this, because it is expected that
* the method will be run, when false is returned.
* @param string $feature email | quota | avatar | profile (can be extended)
- * @return bool
*/
- private function wasRefreshed($feature) {
+ private function wasRefreshed(string $feature): bool {
if (isset($this->refreshedFeatures[$feature])) {
return true;
}
@@ -529,10 +475,9 @@ class User {
/**
* fetches the email from LDAP and stores it as Nextcloud user value
- * @param string $valueFromLDAP if known, to save an LDAP read request
- * @return null
+ * @param ?string $valueFromLDAP if known, to save an LDAP read request
*/
- public function updateEmail($valueFromLDAP = null) {
+ public function updateEmail(?string $valueFromLDAP = null): void {
if ($this->wasRefreshed('email')) {
return;
}
@@ -551,7 +496,7 @@ class User {
if (!is_null($user)) {
$currentEmail = (string)$user->getSystemEMailAddress();
if ($currentEmail !== $email) {
- $user->setEMailAddress($email);
+ $user->setSystemEMailAddress($email);
}
}
}
@@ -570,14 +515,13 @@ class User {
* fetch all the user's attributes in one call and use the fetched values in this function.
* The expected value for that parameter is a string describing the quota for the user. Valid
* values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
- * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
+ * bytes), '1234 MB' (quota in MB - check the \OCP\Util::computerFileSize method for more info)
*
* fetches the quota from LDAP and stores it as Nextcloud user value
* @param ?string $valueFromLDAP the quota attribute's value can be passed,
- * to save the readAttribute request
- * @return void
+ * to save the readAttribute request
*/
- public function updateQuota($valueFromLDAP = null) {
+ public function updateQuota(?string $valueFromLDAP = null): void {
if ($this->wasRefreshed('quota')) {
return;
}
@@ -591,7 +535,7 @@ class User {
$quota = false;
if (is_null($valueFromLDAP) && $quotaAttribute !== '') {
$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
- if ($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
+ if ($aQuota !== false && isset($aQuota[0]) && $this->verifyQuotaValue($aQuota[0])) {
$quota = $aQuota[0];
} elseif (is_array($aQuota) && isset($aQuota[0])) {
$this->logger->debug('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ['app' => 'user_ldap']);
@@ -599,7 +543,7 @@ class User {
} elseif (!is_null($valueFromLDAP) && $this->verifyQuotaValue($valueFromLDAP)) {
$quota = $valueFromLDAP;
} else {
- $this->logger->debug('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ['app' => 'user_ldap']);
+ $this->logger->debug('no suitable LDAP quota found for user ' . $this->uid . ': [' . ($valueFromLDAP ?? '') . ']', ['app' => 'user_ldap']);
}
if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
@@ -618,8 +562,8 @@ class User {
}
}
- private function verifyQuotaValue(string $quotaValue) {
- return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
+ private function verifyQuotaValue(string $quotaValue): bool {
+ return $quotaValue === 'none' || $quotaValue === 'default' || Util::computerFileSize($quotaValue) !== false;
}
/**
@@ -635,7 +579,7 @@ class User {
// fetch/prepare user
$user = $this->userManager->get($this->uid);
if (is_null($user)) {
- $this->logger->error('could not get user for uid='.$this->uid.'', ['app' => 'user_ldap']);
+ $this->logger->error('could not get user for uid=' . $this->uid . '', ['app' => 'user_ldap']);
return;
}
// prepare AccountManager and Account
@@ -650,41 +594,29 @@ class User {
try {
$accountProperty = $account->getProperty($property);
$currentValue = $accountProperty->getValue();
- $scope = ($accountProperty->getScope() ? $accountProperty->getScope()
- : $defaultScopes[$property]);
+ $scope = ($accountProperty->getScope() ?: $defaultScopes[$property]);
} catch (PropertyDoesNotExistException $e) { // thrown at getProperty
- $this->logger->error('property does not exist: '.$property
- .' for uid='.$this->uid.'', ['app' => 'user_ldap', 'exception' => $e]);
+ $this->logger->error('property does not exist: ' . $property
+ . ' for uid=' . $this->uid . '', ['app' => 'user_ldap', 'exception' => $e]);
$currentValue = '';
$scope = $defaultScopes[$property];
}
- $verified = IAccountManager::VERIFIED; // trust the LDAP admin knew what he put there
+ $verified = IAccountManager::VERIFIED; // trust the LDAP admin knew what they put there
if ($currentValue !== $value) {
$account->setProperty($property, $value, $scope, $verified);
- $this->logger->debug('update user profile: '.$property.'='.$value
- .' for uid='.$this->uid.'', ['app' => 'user_ldap']);
+ $this->logger->debug('update user profile: ' . $property . '=' . $value
+ . ' for uid=' . $this->uid . '', ['app' => 'user_ldap']);
}
}
try {
$accountManager->updateAccount($account); // may throw InvalidArgumentException
} catch (\InvalidArgumentException $e) {
- $this->logger->error('invalid data from LDAP: for uid='.$this->uid.'', ['app' => 'user_ldap', 'func' => 'updateProfile'
+ $this->logger->error('invalid data from LDAP: for uid=' . $this->uid . '', ['app' => 'user_ldap', 'func' => 'updateProfile'
, 'exception' => $e]);
}
}
/**
- * called by a post_login hook to save the avatar picture
- *
- * @param array $params
- */
- public function updateAvatarPostLogin($params) {
- if (isset($params['uid']) && $params['uid'] === $this->getUsername()) {
- $this->updateAvatar();
- }
- }
-
- /**
* @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
* @return bool true when the avatar was set successfully or is up to date
*/
@@ -709,7 +641,7 @@ class User {
return true;
}
- $isSet = $this->setOwnCloudAvatar();
+ $isSet = $this->setNextcloudAvatar();
if ($isSet) {
// save checksum only after successful setting
@@ -730,11 +662,10 @@ class User {
/**
* @brief sets an image as Nextcloud avatar
- * @return bool
*/
- private function setOwnCloudAvatar() {
+ private function setNextcloudAvatar(): bool {
if (!$this->image->valid()) {
- $this->logger->error('avatar image data from LDAP invalid for '.$this->dn, ['app' => 'user_ldap']);
+ $this->logger->error('avatar image data from LDAP invalid for ' . $this->dn, ['app' => 'user_ldap']);
return false;
}
@@ -742,14 +673,10 @@ class User {
//make sure it is a square and not bigger than 512x512
$size = min([$this->image->width(), $this->image->height(), 512]);
if (!$this->image->centerCrop($size)) {
- $this->logger->error('croping image for avatar failed for '.$this->dn, ['app' => 'user_ldap']);
+ $this->logger->error('croping image for avatar failed for ' . $this->dn, ['app' => 'user_ldap']);
return false;
}
- if (!$this->fs->isLoaded()) {
- $this->fs->setup($this->uid);
- }
-
try {
$avatar = $this->avatarManager->getAvatar($this->uid);
$avatar->set($this->image);
@@ -763,7 +690,7 @@ class User {
/**
* @throws AttributeNotSet
* @throws \OC\ServerNotAvailableException
- * @throws \OCP\PreConditionNotMetException
+ * @throws PreConditionNotMetException
*/
public function getExtStorageHome():string {
$value = $this->config->getUserValue($this->getUsername(), 'user_ldap', 'extStorageHome', '');
@@ -782,7 +709,7 @@ class User {
}
/**
- * @throws \OCP\PreConditionNotMetException
+ * @throws PreConditionNotMetException
* @throws \OC\ServerNotAvailableException
*/
public function updateExtStorageHome(?string $valueFromLDAP = null):string {
@@ -791,7 +718,7 @@ class User {
} else {
$extHomeValues = [$valueFromLDAP];
}
- if ($extHomeValues && isset($extHomeValues[0])) {
+ if ($extHomeValues !== false && isset($extHomeValues[0])) {
$extHome = $extHomeValues[0];
$this->config->setUserValue($this->getUsername(), 'user_ldap', 'extStorageHome', $extHome);
return $extHome;
@@ -803,29 +730,30 @@ class User {
/**
* called by a post_login hook to handle password expiry
- *
- * @param array $params
*/
- public function handlePasswordExpiry($params) {
+ public function handlePasswordExpiry(array $params): void {
$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
- return;//password expiry handling disabled
+ //password expiry handling disabled
+ return;
}
$uid = $params['uid'];
if (isset($uid) && $uid === $this->getUsername()) {
//retrieve relevant user attributes
$result = $this->access->search('objectclass=*', $this->dn, ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
- if (array_key_exists('pwdpolicysubentry', $result[0])) {
- $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
- if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
- $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
+ if (!empty($result)) {
+ if (array_key_exists('pwdpolicysubentry', $result[0])) {
+ $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
+ if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
+ $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
+ }
}
- }
- $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : [];
- $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : [];
- $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : [];
+ $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : [];
+ $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : [];
+ $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : [];
+ }
//retrieve relevant password policy attributes
$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
@@ -844,18 +772,18 @@ class User {
if (!empty($pwdGraceAuthNLimit)
&& count($pwdGraceUseTime) < (int)$pwdGraceAuthNLimit[0]) { //at least one more grace login available?
$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
- header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
+ header('Location: ' . Server::get(IURLGenerator::class)->linkToRouteAbsolute(
'user_ldap.renewPassword.showRenewPasswordForm', ['user' => $uid]));
} else { //no more grace login available
- header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
+ header('Location: ' . Server::get(IURLGenerator::class)->linkToRouteAbsolute(
'user_ldap.renewPassword.showLoginFormInvalidPassword', ['user' => $uid]));
}
exit();
}
//handle pwdReset attribute
- if (!empty($pwdReset) && $pwdReset[0] === 'TRUE') { //user must change his password
+ if (!empty($pwdReset) && $pwdReset[0] === 'TRUE') { //user must change their password
$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
- header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
+ header('Location: ' . Server::get(IURLGenerator::class)->linkToRouteAbsolute(
'user_ldap.renewPassword.showRenewPasswordForm', ['user' => $uid]));
exit();
}
@@ -867,7 +795,7 @@ class User {
$pwdExpireWarningInt = (int)$pwdExpireWarning[0];
if ($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0) {
$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
- $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
+ $pwdChangedTimeDt->add(new \DateInterval('PT' . $pwdMaxAgeInt . 'S'));
$currentDateTime = new \DateTime();
$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
if ($secondsToExpiry <= $pwdExpireWarningInt) {
@@ -884,7 +812,7 @@ class User {
->setUser($uid)
->setDateTime($currentDateTime)
->setObject('pwd_exp_warn', $uid)
- ->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
+ ->setSubject('pwd_exp_warn_days', [(int)ceil($secondsToExpiry / 60 / 60 / 24)])
;
$this->notificationManager->notify($notification);
}
diff --git a/apps/user_ldap/lib/UserPluginManager.php b/apps/user_ldap/lib/UserPluginManager.php
index 527c6684103..ed87fea6fde 100644
--- a/apps/user_ldap/lib/UserPluginManager.php
+++ b/apps/user_ldap/lib/UserPluginManager.php
@@ -1,31 +1,13 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 EITA Cooperative (eita.org.br)
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Filis Futsarov <filisko@users.noreply.github.com>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\User_LDAP;
use OC\User\Backend;
+use OCP\Server;
use Psr\Log\LoggerInterface;
class UserPluginManager {
@@ -63,12 +45,12 @@ class UserPluginManager {
foreach ($this->which as $action => $v) {
if (is_int($action) && (bool)($respondToActions & $action)) {
$this->which[$action] = $plugin;
- \OCP\Server::get(LoggerInterface::class)->debug("Registered action ".$action." to plugin ".get_class($plugin), ['app' => 'user_ldap']);
+ Server::get(LoggerInterface::class)->debug('Registered action ' . $action . ' to plugin ' . get_class($plugin), ['app' => 'user_ldap']);
}
}
if (method_exists($plugin, 'deleteUser')) {
$this->which['deleteUser'] = $plugin;
- \OCP\Server::get(LoggerInterface::class)->debug("Registered action deleteUser to plugin ".get_class($plugin), ['app' => 'user_ldap']);
+ Server::get(LoggerInterface::class)->debug('Registered action deleteUser to plugin ' . get_class($plugin), ['app' => 'user_ldap']);
}
}
@@ -115,7 +97,7 @@ class UserPluginManager {
}
/**
- * checks whether the user is allowed to change his avatar in Nextcloud
+ * checks whether the user is allowed to change their avatar in Nextcloud
* @param string $uid the Nextcloud user name
* @return boolean either the user can or cannot
* @throws \Exception
diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php
index 7d5562f0ee0..c3f56f5ff9b 100644
--- a/apps/user_ldap/lib/User_LDAP.php
+++ b/apps/user_ldap/lib/User_LDAP.php
@@ -1,40 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author Dominik Schmidt <dev@dominik-schmidt.de>
- * @author felixboehm <felix@webhippie.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author root <root@localhost.localdomain>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Tom Needham <tom@owncloud.com>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -45,42 +14,27 @@ use OCA\User_LDAP\Exceptions\NotOnLDAP;
use OCA\User_LDAP\User\DeletedUsersIndex;
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\User\Backend\ILimitAwareCountUsersBackend;
use OCP\User\Backend\IProvideEnabledStateBackend;
use OCP\UserInterface;
use Psr\Log\LoggerInterface;
-class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
- protected IConfig $ocConfig;
- protected INotificationManager $notificationManager;
- protected UserPluginManager $userPluginManager;
- protected LoggerInterface $logger;
- protected DeletedUsersIndex $deletedUsersIndex;
-
+class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ILimitAwareCountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
public function __construct(
Access $access,
- IConfig $ocConfig,
- INotificationManager $notificationManager,
- IUserSession $userSession,
- UserPluginManager $userPluginManager,
- LoggerInterface $logger,
- DeletedUsersIndex $deletedUsersIndex,
+ protected INotificationManager $notificationManager,
+ protected UserPluginManager $userPluginManager,
+ protected LoggerInterface $logger,
+ protected DeletedUsersIndex $deletedUsersIndex,
) {
parent::__construct($access);
- $this->ocConfig = $ocConfig;
- $this->notificationManager = $notificationManager;
- $this->userPluginManager = $userPluginManager;
- $this->logger = $logger;
- $this->deletedUsersIndex = $deletedUsersIndex;
}
/**
- * checks whether the user is allowed to change his avatar in Nextcloud
+ * checks whether the user is allowed to change their avatar in Nextcloud
*
* @param string $uid the Nextcloud user name
* @return boolean either the user can or cannot
@@ -113,11 +67,12 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* @return string|false
* @throws \Exception
*/
- public function loginName2UserName($loginName) {
+ public function loginName2UserName($loginName, bool $forceLdapRefetch = false) {
$cacheKey = 'loginName2UserName-' . $loginName;
$username = $this->access->connection->getFromCache($cacheKey);
- if ($username !== null) {
+ $ignoreCache = ($username === false && $forceLdapRefetch);
+ if ($username !== null && !$ignoreCache) {
return $username;
}
@@ -132,6 +87,9 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
}
$username = $user->getUsername();
$this->access->connection->writeToCache($cacheKey, $username);
+ if ($forceLdapRefetch) {
+ $user->processAttributes($ldapRecord);
+ }
return $username;
} catch (NotOnLDAP $e) {
$this->access->connection->writeToCache($cacheKey, false);
@@ -161,8 +119,8 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$attrs = $this->access->userManager->getAttributes();
$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
if (count($users) < 1) {
- throw new NotOnLDAP('No user available for the given login name on ' .
- $this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
+ throw new NotOnLDAP('No user available for the given login name on '
+ . $this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
}
return $users[0];
}
@@ -175,22 +133,17 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* @return false|string
*/
public function checkPassword($uid, $password) {
- try {
- $ldapRecord = $this->getLDAPUserByLoginName($uid);
- } catch (NotOnLDAP $e) {
- $this->logger->debug(
- $e->getMessage(),
- ['app' => 'user_ldap', 'exception' => $e]
- );
+ $username = $this->loginName2UserName($uid, true);
+ if ($username === false) {
return false;
}
- $dn = $ldapRecord['dn'][0];
+ $dn = $this->access->username2dn($username);
$user = $this->access->userManager->get($dn);
if (!$user instanceof User) {
$this->logger->warning(
- 'LDAP Login: Could not get user object for DN ' . $dn .
- '. Maybe the LDAP entry has no set display name attribute?',
+ 'LDAP Login: Could not get user object for DN ' . $dn
+ . '. Maybe the LDAP entry has no set display name attribute?',
['app' => 'user_ldap']
);
return false;
@@ -202,7 +155,6 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
}
$this->access->cacheUserExists($user->getUsername());
- $user->processAttributes($ldapRecord);
$user->markLogin();
return $user->getUsername();
@@ -225,8 +177,8 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$user = $this->access->userManager->get($uid);
if (!$user instanceof User) {
- throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
- '. Maybe the LDAP entry has no set display name attribute?');
+ throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid
+ . '. Maybe the LDAP entry has no set display name attribute?');
}
if ($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
@@ -256,7 +208,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
*/
public function getUsers($search = '', $limit = 10, $offset = 0) {
$search = $this->access->escapeFilterPart($search, true);
- $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
+ $cachekey = 'getUsers-' . $search . '-' . $limit . '-' . $offset;
//check if users are cached, if so return
$ldap_users = $this->access->connection->getFromCache($cachekey);
@@ -276,7 +228,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
]);
$this->logger->debug(
- 'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
+ 'getUsers: Options: search ' . $search . ' limit ' . $limit . ' offset ' . $offset . ' Filter: ' . $filter,
['app' => 'user_ldap']
);
//do the search and translate results to Nextcloud names
@@ -286,7 +238,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$limit, $offset);
$ldap_users = $this->access->nextcloudUserNames($ldap_users);
$this->logger->debug(
- 'getUsers: '.count($ldap_users). ' Users found',
+ 'getUsers: ' . count($ldap_users) . ' Users found',
['app' => 'user_ldap']
);
@@ -297,8 +249,8 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
/**
* checks whether a user is still available on LDAP
*
- * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
- * name or an instance of that user
+ * @param string|User $user either the Nextcloud user
+ * name or an instance of that user
* @throws \Exception
* @throws \OC\ServerNotAvailableException
*/
@@ -357,23 +309,22 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* @throws \Exception when connection could not be established
*/
public function userExists($uid) {
- $userExists = $this->access->connection->getFromCache('userExists'.$uid);
+ $userExists = $this->access->connection->getFromCache('userExists' . $uid);
if (!is_null($userExists)) {
return (bool)$userExists;
}
- //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
- $user = $this->access->userManager->get($uid);
+ $userExists = $this->access->userManager->exists($uid);
- if (is_null($user)) {
+ if (!$userExists) {
$this->logger->debug(
- 'No DN found for '.$uid.' on '.$this->access->connection->ldapHost,
+ 'No DN found for ' . $uid . ' on ' . $this->access->connection->ldapHost,
['app' => 'user_ldap']
);
- $this->access->connection->writeToCache('userExists'.$uid, false);
+ $this->access->connection->writeToCache('userExists' . $uid, false);
return false;
}
- $this->access->connection->writeToCache('userExists'.$uid, true);
+ $this->access->connection->writeToCache('userExists' . $uid, true);
return true;
}
@@ -407,7 +358,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
}
if (!$marked) {
$this->logger->notice(
- 'User '.$uid . ' is not marked as deleted, not cleaning up.',
+ 'User ' . $uid . ' is not marked as deleted, not cleaning up.',
['app' => 'user_ldap']
);
return false;
@@ -440,7 +391,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
return $this->userPluginManager->getHome($uid);
}
- $cacheKey = 'getHome'.$uid;
+ $cacheKey = 'getHome' . $uid;
$path = $this->access->connection->getFromCache($cacheKey);
if (!is_null($path)) {
return $path;
@@ -472,7 +423,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
return false;
}
- $cacheKey = 'getDisplayName'.$uid;
+ $cacheKey = 'getDisplayName' . $uid;
if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
return $displayName;
}
@@ -499,11 +450,10 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$user = $this->access->userManager->get($uid);
if ($user instanceof User) {
- $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
+ $displayName = $user->composeAndStoreDisplayName($displayName, (string)$displayName2);
$this->access->connection->writeToCache($cacheKey, $displayName);
}
if ($user instanceof OfflineUser) {
- /** @var OfflineUser $user*/
$displayName = $user->getDisplayName();
}
return $displayName;
@@ -536,7 +486,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* @return array an array of all displayNames (value) and the corresponding uids (key)
*/
public function getDisplayNames($search = '', $limit = null, $offset = null) {
- $cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
+ $cacheKey = 'getDisplayNames-' . $search . '-' . $limit . '-' . $offset;
if (!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
return $displayNames;
}
@@ -578,20 +528,18 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
/**
* counts the users in LDAP
- *
- * @return int|false
*/
- public function countUsers() {
+ public function countUsers(int $limit = 0): int|false {
if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
return $this->userPluginManager->countUsers();
}
$filter = $this->access->getFilterForUserCount();
- $cacheKey = 'countUsers-'.$filter;
+ $cacheKey = 'countUsers-' . $filter . '-' . $limit;
if (!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
return $entries;
}
- $entries = $this->access->countUsers($filter);
+ $entries = $this->access->countUsers($filter, limit:$limit);
$this->access->connection->writeToCache($cacheKey, $entries);
return $entries;
}
@@ -650,7 +598,6 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$uuid,
true
);
- $this->access->cacheUserExists($username);
} else {
$this->logger->warning(
'Failed to map created LDAP user with userid {userid}, because UUID could not be determined',
@@ -661,10 +608,10 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
);
}
} else {
- throw new \UnexpectedValueException("LDAP Plugin: Method createUser changed to return the user DN instead of boolean.");
+ throw new \UnexpectedValueException('LDAP Plugin: Method createUser changed to return the user DN instead of boolean.');
}
}
- return (bool) $dn;
+ return (bool)$dn;
}
return false;
}
@@ -682,7 +629,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
return $enabled;
}
- public function getDisabledUserList(?int $limit = null, int $offset = 0): array {
+ public function getDisabledUserList(?int $limit = null, int $offset = 0, string $search = ''): array {
throw new \Exception('This is implemented directly in User_Proxy');
}
}
diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php
index 96415491e41..0d41f495ce9 100644
--- a/apps/user_ldap/lib/User_Proxy.php
+++ b/apps/user_ldap/lib/User_Proxy.php
@@ -1,107 +1,47 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roger Szabo <roger.szabo@web.de>
- * @author root <root@localhost.localdomain>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vinicius Cubas Brand <vinicius@eita.org.br>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
use OCA\User_LDAP\User\DeletedUsersIndex;
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\User\Backend\ILimitAwareCountUsersBackend;
use OCP\User\Backend\IProvideEnabledStateBackend;
use OCP\UserInterface;
use Psr\Log\LoggerInterface;
-class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
- /** @var User_LDAP[] */
- private array $backends = [];
- private ?User_LDAP $refBackend = null;
-
- private bool $isSetUp = false;
- private Helper $helper;
- private IConfig $ocConfig;
- private INotificationManager $notificationManager;
- private IUserSession $userSession;
- private UserPluginManager $userPluginManager;
- private LoggerInterface $logger;
- private DeletedUsersIndex $deletedUsersIndex;
-
+/**
+ * @template-extends Proxy<User_LDAP>
+ */
+class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP, ILimitAwareCountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
public function __construct(
- Helper $helper,
+ private Helper $helper,
ILDAPWrapper $ldap,
AccessFactory $accessFactory,
- IConfig $ocConfig,
- INotificationManager $notificationManager,
- IUserSession $userSession,
- UserPluginManager $userPluginManager,
- LoggerInterface $logger,
- DeletedUsersIndex $deletedUsersIndex,
+ private INotificationManager $notificationManager,
+ private UserPluginManager $userPluginManager,
+ private LoggerInterface $logger,
+ private DeletedUsersIndex $deletedUsersIndex,
) {
- parent::__construct($ldap, $accessFactory);
- $this->helper = $helper;
- $this->ocConfig = $ocConfig;
- $this->notificationManager = $notificationManager;
- $this->userSession = $userSession;
- $this->userPluginManager = $userPluginManager;
- $this->logger = $logger;
- $this->deletedUsersIndex = $deletedUsersIndex;
+ parent::__construct($helper, $ldap, $accessFactory);
}
- 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),
- $this->ocConfig,
- $this->notificationManager,
- $this->userSession,
- $this->userPluginManager,
- $this->logger,
- $this->deletedUsersIndex,
- );
-
- if (is_null($this->refBackend)) {
- $this->refBackend = &$this->backends[$configPrefix];
- }
- }
-
- $this->isSetUp = true;
+ protected function newInstance(string $configPrefix): User_LDAP {
+ return new User_LDAP(
+ $this->getAccess($configPrefix),
+ $this->notificationManager,
+ $this->userPluginManager,
+ $this->logger,
+ $this->deletedUsersIndex,
+ );
}
/**
@@ -254,8 +194,8 @@ class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP
/**
* check if a user exists on LDAP
*
- * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
- * name or an instance of that user
+ * @param string|User $user either the Nextcloud user
+ * name or an instance of that user
*/
public function userExistsOnLDAP($user, bool $ignoreCache = false): bool {
$id = ($user instanceof User) ? $user->getUsername() : $user;
@@ -329,7 +269,7 @@ class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP
}
/**
- * checks whether the user is allowed to change his avatar in Nextcloud
+ * checks whether the user is allowed to change their avatar in Nextcloud
*
* @param string $uid the Nextcloud user name
* @return boolean either the user can or cannot
@@ -394,17 +334,21 @@ class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP
/**
* Count the number of users
- *
- * @return int|false
*/
- public function countUsers() {
+ public function countUsers(int $limit = 0): int|false {
$this->setup();
$users = false;
foreach ($this->backends as $backend) {
- $backendUsers = $backend->countUsers();
+ $backendUsers = $backend->countUsers($limit);
if ($backendUsers !== false) {
$users = (int)$users + $backendUsers;
+ if ($limit > 0) {
+ if ($users >= $limit) {
+ break;
+ }
+ $limit -= $users;
+ }
}
}
return $users;
@@ -463,11 +407,25 @@ class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP
return $this->handleRequest($uid, 'setUserEnabled', [$uid, $enabled, $queryDatabaseValue, $setDatabaseValue]);
}
- public function getDisabledUserList(?int $limit = null, int $offset = 0): array {
+ public function getDisabledUserList(?int $limit = null, int $offset = 0, string $search = ''): array {
+ if ((int)$this->getAccess(array_key_first($this->backends) ?? '')->connection->markRemnantsAsDisabled !== 1) {
+ return [];
+ }
+ $disabledUsers = $this->deletedUsersIndex->getUsers();
+ if ($search !== '') {
+ $disabledUsers = array_filter(
+ $disabledUsers,
+ fn (OfflineUser $user): bool
+ => mb_stripos($user->getOCName(), $search) !== false
+ || mb_stripos($user->getUID(), $search) !== false
+ || mb_stripos($user->getDisplayName(), $search) !== false
+ || mb_stripos($user->getEmail(), $search) !== false,
+ );
+ }
return array_map(
fn (OfflineUser $user) => $user->getOCName(),
array_slice(
- $this->deletedUsersIndex->getUsers(),
+ $disabledUsers,
$offset,
$limit
)
diff --git a/apps/user_ldap/lib/Wizard.php b/apps/user_ldap/lib/Wizard.php
index 1b4c9162b71..15a9f9cb212 100644
--- a/apps/user_ldap/lib/Wizard.php
+++ b/apps/user_ldap/lib/Wizard.php
@@ -1,41 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Alexander Bergolth <leo@strike.wu.ac.at>
- * @author Allan Nordhøy <epost@anotheragency.no>
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Jean-Louis Dupond <jean-louis@dupond.be>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Nicolas Grekas <nicolas.grekas@gmail.com>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Stefan Weil <sw@weilnetz.de>
- * @author Tobias Perschon <tobias@perschon.at>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- * @author Xuanwo <xuanwo@yunify.com>
- * @author Vincent Van Houtte <vvh@aplusv.be>
- * @author Côme Chilliet <come.chilliet@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -43,13 +11,13 @@ namespace OCA\User_LDAP;
use OC\ServerNotAvailableException;
use OCP\IL10N;
use OCP\L10N\IFactory as IL10NFactory;
+use OCP\Server;
+use OCP\Util;
use Psr\Log\LoggerInterface;
class Wizard extends LDAPUtility {
protected static ?IL10N $l = null;
- protected Access $access;
protected ?\LDAP\Connection $cr = null;
- protected Configuration $configuration;
protected WizardResult $result;
protected LoggerInterface $logger;
@@ -67,18 +35,16 @@ class Wizard extends LDAPUtility {
public const LDAP_NW_TIMEOUT = 4;
public function __construct(
- Configuration $configuration,
+ protected Configuration $configuration,
ILDAPWrapper $ldap,
- Access $access
+ protected Access $access,
) {
parent::__construct($ldap);
- $this->configuration = $configuration;
if (is_null(static::$l)) {
- static::$l = \OC::$server->get(IL10NFactory::class)->get('user_ldap');
+ static::$l = Server::get(IL10NFactory::class)->get('user_ldap');
}
- $this->access = $access;
$this->result = new WizardResult();
- $this->logger = \OC::$server->get(LoggerInterface::class);
+ $this->logger = Server::get(LoggerInterface::class);
}
public function __destruct() {
@@ -294,8 +260,8 @@ class Wizard extends LDAPUtility {
$this->applyFind('ldap_email_attr', $winner);
if ($writeLog) {
$this->logger->info(
- 'The mail attribute has automatically been reset, '.
- 'because the original value did not return any results.',
+ 'The mail attribute has automatically been reset, '
+ . 'because the original value did not return any results.',
['app' => 'user_ldap']
);
}
@@ -414,7 +380,7 @@ class Wizard extends LDAPUtility {
$this->fetchGroups($dbKey, $confKey);
if ($testMemberOf) {
- $this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
+ $this->configuration->hasMemberOfFilterSupport = (string)$this->testMemberOf();
$this->result->markChange();
if (!$this->configuration->hasMemberOfFilterSupport) {
throw new \Exception('memberOf is not supported by the server');
@@ -434,7 +400,7 @@ class Wizard extends LDAPUtility {
$filterParts = [];
foreach ($obclasses as $obclass) {
- $filterParts[] = 'objectclass='.$obclass;
+ $filterParts[] = 'objectclass=' . $obclass;
}
//we filter for everything
//- that looks like a group and
@@ -679,7 +645,7 @@ class Wizard extends LDAPUtility {
$p = $setting['port'];
$t = $setting['tls'];
$this->logger->debug(
- 'Wiz: trying port '. $p . ', TLS '. $t,
+ 'Wiz: trying port ' . $p . ', TLS ' . $t,
['app' => 'user_ldap']
);
//connectAndBind may throw Exception, it needs to be caught by the
@@ -700,8 +666,8 @@ class Wizard extends LDAPUtility {
if ($settingsFound === true) {
$config = [
- 'ldapPort' => $p,
- 'ldapTLS' => (int)$t
+ 'ldapPort' => (string)$p,
+ 'ldapTLS' => (string)$t,
];
$this->configuration->setConfiguration($config);
$this->logger->debug(
@@ -744,7 +710,7 @@ class Wizard extends LDAPUtility {
//this did not help :(
//Let's see whether we can parse the Host URL and convert the domain to
//a base DN
- $helper = \OC::$server->get(Helper::class);
+ $helper = Server::get(Helper::class);
$domain = $helper->getDomainFromURL($this->configuration->ldapHost);
if (!$domain) {
return false;
@@ -787,7 +753,7 @@ class Wizard extends LDAPUtility {
//removes Port from Host
if (is_array($hostInfo) && isset($hostInfo['port'])) {
$port = $hostInfo['port'];
- $host = str_replace(':'.$port, '', $host);
+ $host = str_replace(':' . $port, '', $host);
$this->applyFind('ldap_host', $host);
$this->applyFind('ldap_port', (string)$port);
}
@@ -856,7 +822,7 @@ class Wizard extends LDAPUtility {
$errorNo = $this->ldap->errno($cr);
$errorMsg = $this->ldap->error($cr);
$this->logger->info(
- 'Wiz: Could not search base '.$base.' Error '.$errorNo.': '.$errorMsg,
+ 'Wiz: Could not search base ' . $base . ' Error ' . $errorNo . ': ' . $errorMsg,
['app' => 'user_ldap']
);
return false;
@@ -890,8 +856,8 @@ class Wizard extends LDAPUtility {
/**
* creates an LDAP Filter from given configuration
* @param int $filterType int, for which use case the filter shall be created
- * can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or
- * self::LFILTER_GROUP_LIST
+ * can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or
+ * self::LFILTER_GROUP_LIST
* @throws \Exception
*/
private function composeLdapFilter(int $filterType): string {
@@ -934,7 +900,7 @@ class Wizard extends LDAPUtility {
$filterPart = '(memberof=' . ldap_escape($dn, '', LDAP_ESCAPE_FILTER) . ')';
if (isset($attrs['primaryGroupToken'])) {
$pgt = $attrs['primaryGroupToken'][0];
- $primaryFilterPart = '(primaryGroupID=' . ldap_escape($pgt, '', LDAP_ESCAPE_FILTER) .')';
+ $primaryFilterPart = '(primaryGroupID=' . ldap_escape($pgt, '', LDAP_ESCAPE_FILTER) . ')';
$filterPart = '(|' . $filterPart . $primaryFilterPart . ')';
}
$filter .= $filterPart;
@@ -1034,12 +1000,12 @@ class Wizard extends LDAPUtility {
$filterLogin .= ')';
}
- $filter = '(&'.$ulf.$filterLogin.')';
+ $filter = '(&' . $ulf . $filterLogin . ')';
break;
}
$this->logger->debug(
- 'Wiz: Final filter '.$filter,
+ 'Wiz: Final filter ' . $filter,
['app' => 'user_ldap']
);
@@ -1101,7 +1067,7 @@ class Wizard extends LDAPUtility {
if ($login === true) {
$this->logger->debug(
- 'Wiz: Bind successful to Port '. $port . ' TLS ' . (int)$tls,
+ 'Wiz: Bind successful to Port ' . $port . ' TLS ' . (int)$tls,
['app' => 'user_ldap']
);
return true;
@@ -1146,9 +1112,9 @@ class Wizard extends LDAPUtility {
* @param string[] $filters array, the filters that shall be used in the search
* @param string $attr the attribute of which a list of values shall be returned
* @param int $dnReadLimit the amount of how many DNs should be analyzed.
- * The lower, the faster
+ * The lower, the faster
* @param string $maxF string. if not null, this variable will have the filter that
- * yields most result entries
+ * yields most result entries
* @return array|false an array with the values on success, false otherwise
*/
public function cumulativeSearchOnAttribute(array $filters, string $attr, int $dnReadLimit = 3, ?string &$maxF = null) {
@@ -1222,9 +1188,9 @@ class Wizard extends LDAPUtility {
* @param string $attr the attribute to look for
* @param string $dbkey the dbkey of the setting the feature is connected to
* @param string $confkey the confkey counterpart for the $dbkey as used in the
- * Configuration class
+ * Configuration class
* @param bool $po whether the objectClass with most result entries
- * shall be pre-selected via the result
+ * shall be pre-selected via the result
* @return array list of found items.
* @throws \Exception
*/
@@ -1235,7 +1201,7 @@ class Wizard extends LDAPUtility {
}
$p = 'objectclass=';
foreach ($objectclasses as $key => $value) {
- $objectclasses[$key] = $p.$value;
+ $objectclasses[$key] = $p . $value;
}
$maxEntryObjC = '';
@@ -1243,8 +1209,8 @@ class Wizard extends LDAPUtility {
//When looking for objectclasses, testing few entries is sufficient,
$dig = 3;
- $availableFeatures =
- $this->cumulativeSearchOnAttribute($objectclasses, $attr,
+ $availableFeatures
+ = $this->cumulativeSearchOnAttribute($objectclasses, $attr,
$dig, $maxEntryObjC);
if (is_array($availableFeatures)
&& count($availableFeatures) > 0) {
@@ -1276,7 +1242,7 @@ class Wizard extends LDAPUtility {
* @param string $attribute the attribute values to look for
* @param array &$known new values will be appended here
* @return int state on of the class constants LRESULT_PROCESSED_OK,
- * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
+ * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
*/
private function getAttributeValuesFromEntry(array $result, string $attribute, array &$known): int {
if (!isset($result['count'])
@@ -1285,7 +1251,7 @@ class Wizard extends LDAPUtility {
}
// strtolower on all keys for proper comparison
- $result = \OCP\Util::mb_array_change_key_case($result);
+ $result = Util::mb_array_change_key_case($result);
$attribute = strtolower($attribute);
if (isset($result[$attribute])) {
foreach ($result[$attribute] as $key => $val) {
@@ -1322,7 +1288,7 @@ class Wizard extends LDAPUtility {
$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
- if ($this->configuration->ldapTLS === 1) {
+ if ($this->configuration->ldapTLS) {
$this->ldap->startTls($cr);
}
@@ -1337,6 +1303,9 @@ class Wizard extends LDAPUtility {
return false;
}
+ /**
+ * @return array<array{port:int,tls:bool}>
+ */
private function getDefaultLdapPortSettings(): array {
static $settings = [
['port' => 7636, 'tls' => false],
@@ -1349,6 +1318,9 @@ class Wizard extends LDAPUtility {
return $settings;
}
+ /**
+ * @return array<array{port:int,tls:bool}>
+ */
private function getPortSettingsToTry(): array {
//389 ← LDAP / Unencrypted or StartTLS
//636 ← LDAPS / SSL
@@ -1367,7 +1339,7 @@ class Wizard extends LDAPUtility {
}
$portSettings[] = ['port' => $port, 'tls' => false];
} elseif ($this->configuration->usesLdapi()) {
- $portSettings[] = ['port' => '', 'tls' => false];
+ $portSettings[] = ['port' => 0, 'tls' => false];
}
//default ports
diff --git a/apps/user_ldap/lib/WizardResult.php b/apps/user_ldap/lib/WizardResult.php
index 0f8d9f46fdd..d6fd67d4204 100644
--- a/apps/user_ldap/lib/WizardResult.php
+++ b/apps/user_ldap/lib/WizardResult.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\User_LDAP;
@@ -40,7 +20,7 @@ class WizardResult {
$this->changes[$key] = $value;
}
-
+
public function markChange() {
$this->markedChange = true;
}