mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
Merge pull request #31421 from nextcloud/fix/user_ldap-fix-ldap-connection-resets
user_ldap fix ldap connection resets
This commit is contained in:
commit
475a859aae
12 changed files with 189 additions and 247 deletions
|
|
@ -180,7 +180,7 @@ class Access extends LDAPUtility {
|
|||
* array if $attr is empty, false otherwise
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function readAttribute($dn, $attr, $filter = 'objectClass=*') {
|
||||
public function readAttribute(string $dn, string $attr, string $filter = 'objectClass=*') {
|
||||
if (!$this->checkConnection()) {
|
||||
$this->logger->warning(
|
||||
'No LDAP Connector assigned, access impossible for readAttribute.',
|
||||
|
|
@ -211,7 +211,7 @@ class Access extends LDAPUtility {
|
|||
$values = [];
|
||||
$isRangeRequest = false;
|
||||
do {
|
||||
$result = $this->executeRead($cr, $dn, $attrToRead, $filter, $maxResults);
|
||||
$result = $this->executeRead($dn, $attrToRead, $filter, $maxResults);
|
||||
if (is_bool($result)) {
|
||||
// when an exists request was run and it was successful, an empty
|
||||
// array must be returned
|
||||
|
|
@ -253,17 +253,12 @@ class Access extends LDAPUtility {
|
|||
/**
|
||||
* Runs an read operation against LDAP
|
||||
*
|
||||
* @param resource|\LDAP\Connection $cr the LDAP connection
|
||||
* @param string $dn
|
||||
* @param string $attribute
|
||||
* @param string $filter
|
||||
* @param int $maxResults
|
||||
* @return array|bool false if there was any error, true if an exists check
|
||||
* was performed and the requested DN found, array with the
|
||||
* returned data on a successful usual operation
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function executeRead($cr, $dn, $attribute, $filter, $maxResults) {
|
||||
public function executeRead(string $dn, string $attribute, string $filter, int $maxResults) {
|
||||
try {
|
||||
$this->initPagedSearch($filter, $dn, [$attribute], $maxResults, 0);
|
||||
} catch (NoMoreResults $e) {
|
||||
|
|
@ -273,7 +268,7 @@ class Access extends LDAPUtility {
|
|||
return false;
|
||||
}
|
||||
$dn = $this->helper->DNasBaseParameter($dn);
|
||||
$rr = @$this->invokeLDAPMethod('read', $cr, $dn, $filter, [$attribute]);
|
||||
$rr = @$this->invokeLDAPMethod('read', $dn, $filter, [$attribute]);
|
||||
if (!$this->ldap->isResource($rr)) {
|
||||
if ($attribute !== '') {
|
||||
//do not throw this message on userExists check, irritates
|
||||
|
|
@ -282,18 +277,18 @@ class Access extends LDAPUtility {
|
|||
//in case an error occurs , e.g. object does not exist
|
||||
return false;
|
||||
}
|
||||
if ($attribute === '' && ($filter === 'objectclass=*' || $this->invokeLDAPMethod('countEntries', $cr, $rr) === 1)) {
|
||||
if ($attribute === '' && ($filter === 'objectclass=*' || $this->invokeLDAPMethod('countEntries', $rr) === 1)) {
|
||||
$this->logger->debug('readAttribute: ' . $dn . ' found', ['app' => 'user_ldap']);
|
||||
return true;
|
||||
}
|
||||
$er = $this->invokeLDAPMethod('firstEntry', $cr, $rr);
|
||||
$er = $this->invokeLDAPMethod('firstEntry', $rr);
|
||||
if (!$this->ldap->isResource($er)) {
|
||||
//did not match the filter, return false
|
||||
return false;
|
||||
}
|
||||
//LDAP attributes are not case sensitive
|
||||
$result = \OCP\Util::mb_array_change_key_case(
|
||||
$this->invokeLDAPMethod('getAttributes', $cr, $er), MB_CASE_LOWER, 'UTF-8');
|
||||
$this->invokeLDAPMethod('getAttributes', $er), MB_CASE_LOWER, 'UTF-8');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -374,10 +369,10 @@ class Access extends LDAPUtility {
|
|||
}
|
||||
try {
|
||||
// try PASSWD extended operation first
|
||||
return @$this->invokeLDAPMethod('exopPasswd', $cr, $userDN, '', $password) ||
|
||||
@$this->invokeLDAPMethod('modReplace', $cr, $userDN, $password);
|
||||
return @$this->invokeLDAPMethod('exopPasswd', $userDN, '', $password) ||
|
||||
@$this->invokeLDAPMethod('modReplace', $userDN, $password);
|
||||
} catch (ConstraintViolationException $e) {
|
||||
throw new HintException('Password change rejected.', \OC::$server->getL10N('user_ldap')->t('Password change rejected. Hint: ') . $e->getMessage(), $e->getCode());
|
||||
throw new HintException('Password change rejected.', \OC::$server->getL10N('user_ldap')->t('Password change rejected. Hint: ') . $e->getMessage(), (int)$e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +440,7 @@ class Access extends LDAPUtility {
|
|||
* @return string|false LDAP DN on success, otherwise false
|
||||
*/
|
||||
public function groupname2dn($name) {
|
||||
return $this->groupMapper->getDNByName($name);
|
||||
return $this->getGroupMapper()->getDNByName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -455,7 +450,7 @@ class Access extends LDAPUtility {
|
|||
* @return string|false with the LDAP DN on success, otherwise false
|
||||
*/
|
||||
public function username2dn($name) {
|
||||
$fdn = $this->userMapper->getDNByName($name);
|
||||
$fdn = $this->getUserMapper()->getDNByName($name);
|
||||
|
||||
//Check whether the DN belongs to the Base, to avoid issues on multi-
|
||||
//server setups
|
||||
|
|
@ -671,18 +666,12 @@ class Access extends LDAPUtility {
|
|||
$sndAttribute = $this->connection->ldapUserDisplayName2;
|
||||
} else {
|
||||
$nameAttribute = $this->connection->ldapGroupDisplayName;
|
||||
$sndAttribute = null;
|
||||
}
|
||||
$nextcloudNames = [];
|
||||
|
||||
foreach ($ldapObjects as $ldapObject) {
|
||||
$nameByLDAP = null;
|
||||
if (isset($ldapObject[$nameAttribute])
|
||||
&& is_array($ldapObject[$nameAttribute])
|
||||
&& isset($ldapObject[$nameAttribute][0])
|
||||
) {
|
||||
// might be set, but not necessarily. if so, we use it.
|
||||
$nameByLDAP = $ldapObject[$nameAttribute][0];
|
||||
}
|
||||
$nameByLDAP = $ldapObject[$nameAttribute][0] ?? null;
|
||||
|
||||
$ncName = $this->dn2ocname($ldapObject['dn'][0], $nameByLDAP, $isUsers);
|
||||
if ($ncName) {
|
||||
|
|
@ -694,8 +683,7 @@ class Access extends LDAPUtility {
|
|||
if (is_null($nameByLDAP)) {
|
||||
continue;
|
||||
}
|
||||
$sndName = isset($ldapObject[$sndAttribute][0])
|
||||
? $ldapObject[$sndAttribute][0] : '';
|
||||
$sndName = $ldapObject[$sndAttribute][0] ?? '';
|
||||
$this->cacheUserDisplayName($ncName, $nameByLDAP, $sndName);
|
||||
} elseif ($nameByLDAP !== null) {
|
||||
$this->cacheGroupDisplayName($ncName, $nameByLDAP);
|
||||
|
|
@ -711,7 +699,7 @@ class Access extends LDAPUtility {
|
|||
* @param string $ncname
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function updateUserState($ncname) {
|
||||
public function updateUserState($ncname): void {
|
||||
$user = $this->userManager->get($ncname);
|
||||
if ($user instanceof OfflineUser) {
|
||||
$user->unmark();
|
||||
|
|
@ -724,17 +712,15 @@ class Access extends LDAPUtility {
|
|||
* @param string $ocName the internal Nextcloud username
|
||||
* @param string|false $home the home directory path
|
||||
*/
|
||||
public function cacheUserHome($ocName, $home) {
|
||||
public function cacheUserHome(string $ocName, $home): void {
|
||||
$cacheKey = 'getHome' . $ocName;
|
||||
$this->connection->writeToCache($cacheKey, $home);
|
||||
}
|
||||
|
||||
/**
|
||||
* caches a user as existing
|
||||
*
|
||||
* @param string $ocName the internal Nextcloud username
|
||||
*/
|
||||
public function cacheUserExists($ocName) {
|
||||
public function cacheUserExists(string $ocName): void {
|
||||
$this->connection->writeToCache('userExists' . $ocName, true);
|
||||
}
|
||||
|
||||
|
|
@ -753,7 +739,7 @@ class Access extends LDAPUtility {
|
|||
* @param string $displayName2 the second display name
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function cacheUserDisplayName($ocName, $displayName, $displayName2 = '') {
|
||||
public function cacheUserDisplayName(string $ocName, string $displayName, string $displayName2 = ''): void {
|
||||
$user = $this->userManager->get($ocName);
|
||||
if ($user === null) {
|
||||
return;
|
||||
|
|
@ -806,7 +792,7 @@ class Access extends LDAPUtility {
|
|||
*/
|
||||
private function _createAltInternalOwnCloudNameForGroups(string $name) {
|
||||
$usedNames = $this->getGroupMapper()->getNamesBySearch($name, "", '_%');
|
||||
if (!$usedNames || count($usedNames) === 0) {
|
||||
if (count($usedNames) === 0) {
|
||||
$lastNo = 1; //will become name_2
|
||||
} else {
|
||||
natsort($usedNames);
|
||||
|
|
@ -891,7 +877,7 @@ class Access extends LDAPUtility {
|
|||
$listOfDNs[] = $entry['dn'][0];
|
||||
return $listOfDNs;
|
||||
}, []);
|
||||
$idsByDn = $this->userMapper->getListOfIdsByDn($listOfDNs);
|
||||
$idsByDn = $this->getUserMapper()->getListOfIdsByDn($listOfDNs);
|
||||
$recordsToUpdate = array_filter($ldapRecords, function ($record) use ($isBackgroundJobModeAjax, $idsByDn) {
|
||||
$newlyMapped = false;
|
||||
$uid = $idsByDn[$record['dn'][0]] ?? null;
|
||||
|
|
@ -913,10 +899,9 @@ class Access extends LDAPUtility {
|
|||
* user object and requests it to process the freshly fetched attributes and
|
||||
* and their values
|
||||
*
|
||||
* @param array $ldapRecords
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function batchApplyUserAttributes(array $ldapRecords) {
|
||||
public function batchApplyUserAttributes(array $ldapRecords): void {
|
||||
$displayNameAttribute = strtolower((string)$this->connection->ldapUserDisplayName);
|
||||
foreach ($ldapRecords as $userRecord) {
|
||||
if (!isset($userRecord[$displayNameAttribute])) {
|
||||
|
|
@ -941,20 +926,16 @@ class Access extends LDAPUtility {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $filter
|
||||
* @param string|string[] $attr
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return array[]
|
||||
*/
|
||||
public function fetchListOfGroups($filter, $attr, $limit = null, $offset = null) {
|
||||
public function fetchListOfGroups(string $filter, array $attr, int $limit = null, int $offset = null): array {
|
||||
$groupRecords = $this->searchGroups($filter, $attr, $limit, $offset);
|
||||
|
||||
$listOfDNs = array_reduce($groupRecords, function ($listOfDNs, $entry) {
|
||||
$listOfDNs[] = $entry['dn'][0];
|
||||
return $listOfDNs;
|
||||
}, []);
|
||||
$idsByDn = $this->groupMapper->getListOfIdsByDn($listOfDNs);
|
||||
$idsByDn = $this->getGroupMapper()->getListOfIdsByDn($listOfDNs);
|
||||
|
||||
array_walk($groupRecords, function (array $record) use ($idsByDn) {
|
||||
$newlyMapped = false;
|
||||
|
|
@ -994,17 +975,14 @@ class Access extends LDAPUtility {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $filter
|
||||
* @param string|string[] $attr
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @param string[] $attr
|
||||
* @return false|int
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function countUsers($filter, $attr = ['dn'], $limit = null, $offset = null) {
|
||||
public function countUsers(string $filter, array $attr = ['dn'], int $limit = null, int $offset = null) {
|
||||
$result = false;
|
||||
foreach ($this->connection->ldapBaseUsers as $base) {
|
||||
$count = $this->count($filter, [$base], $attr, $limit, $offset);
|
||||
$count = $this->count($filter, [$base], $attr, $limit ?? 0, $offset ?? 0);
|
||||
$result = is_int($count) ? (int)$result + $count : $result;
|
||||
}
|
||||
return $result;
|
||||
|
|
@ -1013,16 +991,12 @@ class Access extends LDAPUtility {
|
|||
/**
|
||||
* executes an LDAP search, optimized for Groups
|
||||
*
|
||||
* @param string $filter the LDAP filter for the search
|
||||
* @param string|string[] $attr optional, when a certain attribute shall be filtered out
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
* @return array with the search result
|
||||
* @param ?string[] $attr optional, when certain attributes shall be filtered out
|
||||
*
|
||||
* Executes an LDAP search
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function searchGroups($filter, $attr = null, $limit = null, $offset = null) {
|
||||
public function searchGroups(string $filter, array $attr = null, int $limit = null, int $offset = null): array {
|
||||
$result = [];
|
||||
foreach ($this->connection->ldapBaseGroups as $base) {
|
||||
$result = array_merge($result, $this->search($filter, $base, $attr, $limit, $offset));
|
||||
|
|
@ -1033,17 +1007,13 @@ class Access extends LDAPUtility {
|
|||
/**
|
||||
* returns the number of available groups
|
||||
*
|
||||
* @param string $filter the LDAP search filter
|
||||
* @param string[] $attr optional
|
||||
* @param int|null $limit
|
||||
* @param int|null $offset
|
||||
* @return int|bool
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function countGroups($filter, $attr = ['dn'], $limit = null, $offset = null) {
|
||||
public function countGroups(string $filter, array $attr = ['dn'], int $limit = null, int $offset = null) {
|
||||
$result = false;
|
||||
foreach ($this->connection->ldapBaseGroups as $base) {
|
||||
$count = $this->count($filter, [$base], $attr, $limit, $offset);
|
||||
$count = $this->count($filter, [$base], $attr, $limit ?? 0, $offset ?? 0);
|
||||
$result = is_int($count) ? (int)$result + $count : $result;
|
||||
}
|
||||
return $result;
|
||||
|
|
@ -1052,15 +1022,13 @@ class Access extends LDAPUtility {
|
|||
/**
|
||||
* returns the number of available objects on the base DN
|
||||
*
|
||||
* @param int|null $limit
|
||||
* @param int|null $offset
|
||||
* @return int|bool
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function countObjects($limit = null, $offset = null) {
|
||||
public function countObjects(int $limit = null, int $offset = null) {
|
||||
$result = false;
|
||||
foreach ($this->connection->ldapBase as $base) {
|
||||
$count = $this->count('objectclass=*', [$base], ['dn'], $limit, $offset);
|
||||
$count = $this->count('objectclass=*', [$base], ['dn'], $limit ?? 0, $offset ?? 0);
|
||||
$result = is_int($count) ? (int)$result + $count : $result;
|
||||
}
|
||||
return $result;
|
||||
|
|
@ -1073,26 +1041,23 @@ class Access extends LDAPUtility {
|
|||
*/
|
||||
|
||||
/**
|
||||
* @param mixed[] $arguments
|
||||
* @return mixed
|
||||
* @throws \OC\ServerNotAvailableException
|
||||
*/
|
||||
private function invokeLDAPMethod() {
|
||||
$arguments = func_get_args();
|
||||
$command = array_shift($arguments);
|
||||
$cr = array_shift($arguments);
|
||||
private function invokeLDAPMethod(string $command, ...$arguments) {
|
||||
if ($command == 'controlPagedResultResponse') {
|
||||
// php no longer supports call-time pass-by-reference
|
||||
// thus cannot support controlPagedResultResponse as the third argument
|
||||
// is a reference
|
||||
throw new \InvalidArgumentException('Invoker does not support controlPagedResultResponse, call LDAP Wrapper directly instead.');
|
||||
}
|
||||
if (!method_exists($this->ldap, $command)) {
|
||||
return null;
|
||||
}
|
||||
array_unshift($arguments, $cr);
|
||||
// php no longer supports call-time pass-by-reference
|
||||
// thus cannot support controlPagedResultResponse as the third argument
|
||||
// is a reference
|
||||
array_unshift($arguments, $this->connection->getConnectionResource());
|
||||
$doMethod = function () use ($command, &$arguments) {
|
||||
if ($command == 'controlPagedResultResponse') {
|
||||
throw new \InvalidArgumentException('Invoker does not support controlPagedResultResponse, call LDAP Wrapper directly instead.');
|
||||
} else {
|
||||
return call_user_func_array([$this->ldap, $command], $arguments);
|
||||
}
|
||||
return call_user_func_array([$this->ldap, $command], $arguments);
|
||||
};
|
||||
try {
|
||||
$ret = $doMethod();
|
||||
|
|
@ -1153,8 +1118,7 @@ class Access extends LDAPUtility {
|
|||
return false;
|
||||
}
|
||||
|
||||
$sr = $this->invokeLDAPMethod('search', $cr, $base, $filter, $attr);
|
||||
// cannot use $cr anymore, might have changed in the previous call!
|
||||
$sr = $this->invokeLDAPMethod('search', $base, $filter, $attr);
|
||||
$error = $this->ldap->errno($this->connection->getConnectionResource());
|
||||
if (!$this->ldap->isResource($sr) || $error !== 0) {
|
||||
$this->logger->error('Attempt for Paging? ' . print_r($pagedSearchOK, true), ['app' => 'user_ldap']);
|
||||
|
|
@ -1183,7 +1147,7 @@ class Access extends LDAPUtility {
|
|||
bool $pagedSearchOK,
|
||||
bool $skipHandling
|
||||
): bool {
|
||||
$cookie = null;
|
||||
$cookie = '';
|
||||
if ($pagedSearchOK) {
|
||||
$cr = $this->connection->getConnectionResource();
|
||||
if ($this->ldap->controlPagedResultResponse($cr, $sr, $cookie)) {
|
||||
|
|
@ -1201,7 +1165,7 @@ class Access extends LDAPUtility {
|
|||
$this->pagedSearchedSuccessful = true;
|
||||
}
|
||||
} else {
|
||||
if (!is_null($limit) && (int)$this->connection->ldapPagingSize !== 0) {
|
||||
if ((int)$this->connection->ldapPagingSize !== 0) {
|
||||
$this->logger->debug(
|
||||
'Paged search was not available',
|
||||
['app' => 'user_ldap']
|
||||
|
|
@ -1221,10 +1185,10 @@ 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|string[] $attr optional, array, one or more attributes that shall be
|
||||
* @param ?string[] $attr optional, array, one or more attributes that shall be
|
||||
* retrieved. Results will according to the order in the array.
|
||||
* @param int $limit optional, maximum results to be counted
|
||||
* @param int $offset optional, a starting point
|
||||
* @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
|
||||
* @return int|false Integer or false if the search could not be initialized
|
||||
|
|
@ -1233,9 +1197,9 @@ class Access extends LDAPUtility {
|
|||
private function count(
|
||||
string $filter,
|
||||
array $bases,
|
||||
$attr = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null,
|
||||
array $attr = null,
|
||||
int $limit = 0,
|
||||
int $offset = 0,
|
||||
bool $skipHandling = false
|
||||
) {
|
||||
$this->logger->debug('Count filter: {filter}', [
|
||||
|
|
@ -1243,12 +1207,8 @@ class Access extends LDAPUtility {
|
|||
'filter' => $filter
|
||||
]);
|
||||
|
||||
if (!is_null($attr) && !is_array($attr)) {
|
||||
$attr = [mb_strtolower($attr, 'UTF-8')];
|
||||
}
|
||||
|
||||
$limitPerPage = (int)$this->connection->ldapPagingSize;
|
||||
if (!is_null($limit) && $limit < $limitPerPage && $limit > 0) {
|
||||
if ($limit < $limitPerPage && $limit > 0) {
|
||||
$limitPerPage = $limit;
|
||||
}
|
||||
|
||||
|
|
@ -1277,7 +1237,7 @@ class Access extends LDAPUtility {
|
|||
* Continue now depends on $hasMorePages value
|
||||
*/
|
||||
$continue = $pagedSearchOK && $hasMorePages;
|
||||
} while ($continue && (is_null($limit) || $limit <= 0 || $limit > $counter));
|
||||
} while ($continue && ($limit <= 0 || $limit > $counter));
|
||||
}
|
||||
|
||||
return $counter;
|
||||
|
|
@ -1289,7 +1249,7 @@ class Access extends LDAPUtility {
|
|||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
private function countEntriesInSearchResults($sr): int {
|
||||
return (int)$this->invokeLDAPMethod('countEntries', $this->connection->getConnectionResource(), $sr);
|
||||
return (int)$this->invokeLDAPMethod('countEntries', $sr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1310,10 +1270,6 @@ class Access extends LDAPUtility {
|
|||
$limitPerPage = $limit;
|
||||
}
|
||||
|
||||
if (!is_null($attr) && !is_array($attr)) {
|
||||
$attr = [mb_strtolower($attr, 'UTF-8')];
|
||||
}
|
||||
|
||||
/* ++ Fixing RHDS searches with pages with zero results ++
|
||||
* As we can have pages with zero results and/or pages with less
|
||||
* than $limit results but with a still valid server 'cookie',
|
||||
|
|
@ -1321,6 +1277,7 @@ class Access extends LDAPUtility {
|
|||
* $findings['count'] < $limit
|
||||
*/
|
||||
$findings = [];
|
||||
$offset = $offset ?? 0;
|
||||
$savedoffset = $offset;
|
||||
$iFoundItems = 0;
|
||||
|
||||
|
|
@ -1330,7 +1287,6 @@ class Access extends LDAPUtility {
|
|||
return [];
|
||||
}
|
||||
[$sr, $pagedSearchOK] = $search;
|
||||
$cr = $this->connection->getConnectionResource();
|
||||
|
||||
if ($skipHandling) {
|
||||
//i.e. result do not need to be fetched, we just need the cookie
|
||||
|
|
@ -1340,7 +1296,7 @@ class Access extends LDAPUtility {
|
|||
return [];
|
||||
}
|
||||
|
||||
$findings = array_merge($findings, $this->invokeLDAPMethod('getEntries', $cr, $sr));
|
||||
$findings = array_merge($findings, $this->invokeLDAPMethod('getEntries', $sr));
|
||||
$iFoundItems = max($iFoundItems, $findings['count']);
|
||||
unset($findings['count']);
|
||||
|
||||
|
|
@ -1351,12 +1307,6 @@ class Access extends LDAPUtility {
|
|||
// resetting offset
|
||||
$offset = $savedoffset;
|
||||
|
||||
// if we're here, probably no connection resource is returned.
|
||||
// to make Nextcloud behave nicely, we simply give back an empty array.
|
||||
if (is_null($findings)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!is_null($attr)) {
|
||||
$selection = [];
|
||||
$i = 0;
|
||||
|
|
@ -1397,7 +1347,7 @@ class Access extends LDAPUtility {
|
|||
&& !is_null($limit)
|
||||
)
|
||||
) {
|
||||
$findings = array_slice($findings, (int)$offset, $limit);
|
||||
$findings = array_slice($findings, $offset, $limit);
|
||||
}
|
||||
return $findings;
|
||||
}
|
||||
|
|
@ -1517,7 +1467,7 @@ class Access extends LDAPUtility {
|
|||
* @param string $search the search term
|
||||
* @return string the final filter part to use in LDAP searches
|
||||
*/
|
||||
public function getFilterPartForUserSearch($search) {
|
||||
public function getFilterPartForUserSearch($search): string {
|
||||
return $this->getFilterPartForSearch($search,
|
||||
$this->connection->ldapAttributesForUserSearch,
|
||||
$this->connection->ldapUserDisplayName);
|
||||
|
|
@ -1529,7 +1479,7 @@ class Access extends LDAPUtility {
|
|||
* @param string $search the search term
|
||||
* @return string the final filter part to use in LDAP searches
|
||||
*/
|
||||
public function getFilterPartForGroupSearch($search) {
|
||||
public function getFilterPartForGroupSearch($search): string {
|
||||
return $this->getFilterPartForSearch($search,
|
||||
$this->connection->ldapAttributesForGroupSearch,
|
||||
$this->connection->ldapGroupDisplayName);
|
||||
|
|
@ -1621,10 +1571,8 @@ class Access extends LDAPUtility {
|
|||
|
||||
/**
|
||||
* returns the filter used for counting users
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilterForUserCount() {
|
||||
public function getFilterForUserCount(): string {
|
||||
$filter = $this->combineFilterWithAnd([
|
||||
$this->connection->ldapUserFilter,
|
||||
$this->connection->ldapUserDisplayName . '=*'
|
||||
|
|
@ -1695,7 +1643,7 @@ class Access extends LDAPUtility {
|
|||
|
||||
$filter = $uuidAttr . '=' . $uuid;
|
||||
$result = $this->searchUsers($filter, ['dn'], 2);
|
||||
if (is_array($result) && isset($result[0]) && isset($result[0]['dn']) && count($result) === 1) {
|
||||
if (isset($result[0]['dn']) && count($result) === 1) {
|
||||
// we put the count into account to make sure that this is
|
||||
// really unique
|
||||
return $result[0]['dn'][0];
|
||||
|
|
@ -1768,13 +1716,11 @@ class Access extends LDAPUtility {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $dn
|
||||
* @param bool $isUser
|
||||
* @param array|null $ldapRecord
|
||||
* @return false|string
|
||||
* @throws ServerNotAvailableException
|
||||
*/
|
||||
public function getUUID($dn, $isUser = true, $ldapRecord = null) {
|
||||
public function getUUID(string $dn, bool $isUser = true, array $ldapRecord = null) {
|
||||
if ($isUser) {
|
||||
$uuidAttr = 'ldapUuidUserAttribute';
|
||||
$uuidOverride = $this->connection->ldapExpertUUIDUserAttr;
|
||||
|
|
@ -1794,7 +1740,7 @@ class Access extends LDAPUtility {
|
|||
? $ldapRecord[$this->connection->$uuidAttr]
|
||||
: $this->readAttribute($dn, $this->connection->$uuidAttr);
|
||||
}
|
||||
if (is_array($uuid) && isset($uuid[0]) && !empty($uuid[0])) {
|
||||
if (is_array($uuid) && !empty($uuid[0])) {
|
||||
$uuid = $uuid[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -1835,14 +1781,8 @@ class Access extends LDAPUtility {
|
|||
* to every two hax figures.
|
||||
*
|
||||
* If an invalid string is passed, it will be returned without change.
|
||||
*
|
||||
* @param string $guid
|
||||
* @return string
|
||||
*/
|
||||
public function formatGuid2ForFilterUser($guid) {
|
||||
if (!is_string($guid)) {
|
||||
throw new \InvalidArgumentException('String expected');
|
||||
}
|
||||
public function formatGuid2ForFilterUser(string $guid): string {
|
||||
$blocks = explode('-', $guid);
|
||||
if (count($blocks) !== 5) {
|
||||
/*
|
||||
|
|
@ -1943,11 +1883,9 @@ class Access extends LDAPUtility {
|
|||
/**
|
||||
* checks if the given DN is part of the given base DN(s)
|
||||
*
|
||||
* @param string $dn the DN
|
||||
* @param string[] $bases array containing the allowed base DN or DNs
|
||||
* @return bool
|
||||
*/
|
||||
public function isDNPartOfBase($dn, $bases) {
|
||||
public function isDNPartOfBase(string $dn, array $bases): bool {
|
||||
$belongsToBase = false;
|
||||
$bases = $this->helper->sanitizeDN($bases);
|
||||
|
||||
|
|
@ -1972,8 +1910,7 @@ class Access extends LDAPUtility {
|
|||
if ($this->lastCookie === '') {
|
||||
return;
|
||||
}
|
||||
$cr = $this->connection->getConnectionResource();
|
||||
$this->invokeLDAPMethod('controlPagedResult', $cr, 0, false);
|
||||
$this->invokeLDAPMethod('controlPagedResult', 0, false);
|
||||
$this->getPagedSearchResultState();
|
||||
$this->lastCookie = '';
|
||||
}
|
||||
|
|
@ -2060,7 +1997,7 @@ class Access extends LDAPUtility {
|
|||
$this->abandonPagedSearch();
|
||||
}
|
||||
$pagedSearchOK = true === $this->invokeLDAPMethod(
|
||||
'controlPagedResult', $this->connection->getConnectionResource(), $limit, false
|
||||
'controlPagedResult', $limit, false
|
||||
);
|
||||
if ($pagedSearchOK) {
|
||||
$this->logger->debug('Ready for a paged search', ['app' => 'user_ldap']);
|
||||
|
|
@ -2071,7 +2008,7 @@ class Access extends LDAPUtility {
|
|||
* So we added "&& !empty($this->lastCookie)" to this test to ignore pagination
|
||||
* if we don't have a previous paged search.
|
||||
*/
|
||||
} elseif ($limit === 0 && !empty($this->lastCookie)) {
|
||||
} elseif (!empty($this->lastCookie)) {
|
||||
// a search without limit was requested. However, if we do use
|
||||
// Paged Search once, we always must do it. This requires us to
|
||||
// initialize it with the configured page size.
|
||||
|
|
@ -2080,7 +2017,6 @@ class Access extends LDAPUtility {
|
|||
// be returned.
|
||||
$pageSize = (int)$this->connection->ldapPagingSize > 0 ? (int)$this->connection->ldapPagingSize : 500;
|
||||
$pagedSearchOK = $this->invokeLDAPMethod('controlPagedResult',
|
||||
$this->connection->getConnectionResource(),
|
||||
$pageSize, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,13 @@ class Configuration {
|
|||
public const LDAP_SERVER_FEATURE_AVAILABLE = 'available';
|
||||
public const LDAP_SERVER_FEATURE_UNAVAILABLE = 'unavailable';
|
||||
|
||||
protected $configPrefix = null;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $configPrefix;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $configRead = false;
|
||||
/**
|
||||
* @var string[] pre-filled with one reference key so that at least one entry is written on save request and
|
||||
|
|
@ -55,7 +61,9 @@ class Configuration {
|
|||
*/
|
||||
protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
|
||||
|
||||
//settings
|
||||
/**
|
||||
* @var array<string, mixed> settings
|
||||
*/
|
||||
protected $config = [
|
||||
'ldapHost' => null,
|
||||
'ldapPort' => null,
|
||||
|
|
@ -115,11 +123,7 @@ class Configuration {
|
|||
'ldapMatchingRuleInChainState' => self::LDAP_SERVER_FEATURE_UNKNOWN,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $configPrefix
|
||||
* @param bool $autoRead
|
||||
*/
|
||||
public function __construct($configPrefix, $autoRead = true) {
|
||||
public function __construct(string $configPrefix, bool $autoRead = true) {
|
||||
$this->configPrefix = $configPrefix;
|
||||
if ($autoRead) {
|
||||
$this->readConfiguration();
|
||||
|
|
@ -145,10 +149,7 @@ class Configuration {
|
|||
$this->setConfiguration([$name => $value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
public function getConfiguration(): array {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
|
|
@ -159,13 +160,8 @@ class Configuration {
|
|||
* @param array $config array that holds the config parameters in an associated
|
||||
* array
|
||||
* @param array &$applied optional; array where the set fields will be given to
|
||||
* @return false|null
|
||||
*/
|
||||
public function setConfiguration($config, &$applied = null) {
|
||||
if (!is_array($config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setConfiguration(array $config, array &$applied = null): void {
|
||||
$cta = $this->getConfigTranslationArray();
|
||||
foreach ($config as $inputKey => $val) {
|
||||
if (strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
|
||||
|
|
@ -207,11 +203,10 @@ class Configuration {
|
|||
}
|
||||
$this->unsavedChanges[$key] = $key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function readConfiguration() {
|
||||
if (!$this->configRead && !is_null($this->configPrefix)) {
|
||||
public function readConfiguration(): void {
|
||||
if (!$this->configRead) {
|
||||
$cta = array_flip($this->getConfigTranslationArray());
|
||||
foreach ($this->config as $key => $val) {
|
||||
if (!isset($cta[$key])) {
|
||||
|
|
@ -260,7 +255,7 @@ class Configuration {
|
|||
/**
|
||||
* saves the current config changes in the database
|
||||
*/
|
||||
public function saveConfiguration() {
|
||||
public function saveConfiguration(): void {
|
||||
$cta = array_flip($this->getConfigTranslationArray());
|
||||
foreach ($this->unsavedChanges as $key) {
|
||||
$value = $this->config[$key];
|
||||
|
|
@ -293,7 +288,7 @@ class Configuration {
|
|||
}
|
||||
$this->saveValue($cta[$key], $value);
|
||||
}
|
||||
$this->saveValue('_lastChange', time());
|
||||
$this->saveValue('_lastChange', (string)time());
|
||||
$this->unsavedChanges = [];
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +313,7 @@ class Configuration {
|
|||
* @param string $varName name of config-key
|
||||
* @param array|string $value to set
|
||||
*/
|
||||
protected function setMultiLine($varName, $value) {
|
||||
protected function setMultiLine(string $varName, $value): void {
|
||||
if (empty($value)) {
|
||||
$value = '';
|
||||
} elseif (!is_array($value)) {
|
||||
|
|
@ -349,36 +344,20 @@ class Configuration {
|
|||
$this->setRawValue($varName, $finalValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $varName
|
||||
* @return string
|
||||
*/
|
||||
protected function getPwd($varName) {
|
||||
protected function getPwd(string $varName): string {
|
||||
return base64_decode($this->getValue($varName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $varName
|
||||
* @return string
|
||||
*/
|
||||
protected function getLcValue($varName) {
|
||||
protected function getLcValue(string $varName): string {
|
||||
return mb_strtolower($this->getValue($varName), 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $varName
|
||||
* @return string
|
||||
*/
|
||||
protected function getSystemValue($varName) {
|
||||
protected function getSystemValue(string $varName): string {
|
||||
//FIXME: if another system value is added, softcode the default value
|
||||
return \OC::$server->getConfig()->getSystemValue($varName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $varName
|
||||
* @return string
|
||||
*/
|
||||
protected function getValue($varName) {
|
||||
protected function getValue(string $varName): string {
|
||||
static $defaults;
|
||||
if (is_null($defaults)) {
|
||||
$defaults = $this->getDefaults();
|
||||
|
|
@ -394,7 +373,7 @@ class Configuration {
|
|||
* @param string $varName name of config key
|
||||
* @param mixed $value to set
|
||||
*/
|
||||
protected function setValue($varName, $value) {
|
||||
protected function setValue(string $varName, $value): void {
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
|
@ -407,16 +386,11 @@ class Configuration {
|
|||
* @param string $varName name of config key
|
||||
* @param mixed $value to set
|
||||
*/
|
||||
protected function setRawValue($varName, $value) {
|
||||
protected function setRawValue(string $varName, $value): void {
|
||||
$this->config[$varName] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $varName
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function saveValue($varName, $value) {
|
||||
protected function saveValue(string $varName, string $value): bool {
|
||||
\OC::$server->getConfig()->setAppValue(
|
||||
'user_ldap',
|
||||
$this->configPrefix.$varName,
|
||||
|
|
@ -429,7 +403,7 @@ class Configuration {
|
|||
* @return array an associative array with the default values. Keys are correspond
|
||||
* to config-value entries in the database table
|
||||
*/
|
||||
public function getDefaults() {
|
||||
public function getDefaults(): array {
|
||||
return [
|
||||
'ldap_host' => '',
|
||||
'ldap_port' => '',
|
||||
|
|
@ -492,7 +466,7 @@ class Configuration {
|
|||
/**
|
||||
* @return array that maps internal variable names to database fields
|
||||
*/
|
||||
public function getConfigTranslationArray() {
|
||||
public function getConfigTranslationArray(): array {
|
||||
//TODO: merge them into one representation
|
||||
static $array = [
|
||||
'ldap_host' => 'ldapHost',
|
||||
|
|
@ -554,18 +528,16 @@ class Configuration {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $rule
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function resolveRule($rule) {
|
||||
public function resolveRule(string $rule): array {
|
||||
if ($rule === 'avatar') {
|
||||
return $this->getAvatarAttributes();
|
||||
}
|
||||
throw new \RuntimeException('Invalid rule');
|
||||
}
|
||||
|
||||
public function getAvatarAttributes() {
|
||||
public function getAvatarAttributes(): array {
|
||||
$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
|
||||
$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,25 @@ class Connection extends LDAPUtility {
|
|||
* @var resource|\LDAP\Connection|null
|
||||
*/
|
||||
private $ldapConnectionRes = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $configPrefix;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
private $configID;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $configured = false;
|
||||
//whether connection should be kept on __destruct
|
||||
|
||||
/**
|
||||
* @var bool whether connection should be kept on __destruct
|
||||
*/
|
||||
private $dontDestruct = false;
|
||||
|
||||
/**
|
||||
|
|
@ -94,16 +109,27 @@ class Connection extends LDAPUtility {
|
|||
*/
|
||||
public $hasGidNumber = true;
|
||||
|
||||
//cache handler
|
||||
protected $cache;
|
||||
/**
|
||||
* @var \OCP\ICache|null
|
||||
*/
|
||||
protected $cache = null;
|
||||
|
||||
/** @var Configuration settings handler **/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $doNotValidate = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $ignoreValidation = false;
|
||||
|
||||
/**
|
||||
* @var array{dn?: mixed, hash?: string, result?: bool}
|
||||
*/
|
||||
protected $bindResult = [];
|
||||
|
||||
/** @var LoggerInterface */
|
||||
|
|
@ -111,16 +137,14 @@ class Connection extends LDAPUtility {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param ILDAPWrapper $ldap
|
||||
* @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, $configPrefix = '', $configID = 'user_ldap') {
|
||||
public function __construct(ILDAPWrapper $ldap, string $configPrefix = '', ?string $configID = 'user_ldap') {
|
||||
parent::__construct($ldap);
|
||||
$this->configPrefix = $configPrefix;
|
||||
$this->configID = $configID;
|
||||
$this->configuration = new Configuration($configPrefix,
|
||||
!is_null($configID));
|
||||
$this->configuration = new Configuration($configPrefix, !is_null($configID));
|
||||
$memcache = \OC::$server->getMemCacheFactory();
|
||||
if ($memcache->isAvailable()) {
|
||||
$this->cache = $memcache->createDistributed();
|
||||
|
|
@ -304,9 +328,9 @@ 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
|
||||
* @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
|
||||
* @return bool true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
|
||||
*/
|
||||
public function setConfiguration($config, &$setParameters = null) {
|
||||
public function setConfiguration($config, &$setParameters = null): bool {
|
||||
if (is_null($setParameters)) {
|
||||
$setParameters = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -863,20 +863,18 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I
|
|||
|
||||
$groups = $this->access->fetchListOfGroups($filter,
|
||||
[strtolower($this->access->connection->ldapGroupMemberAssocAttr), $this->access->connection->ldapGroupDisplayName, 'dn']);
|
||||
if (is_array($groups)) {
|
||||
$fetcher = function ($dn) use (&$seen) {
|
||||
if (is_array($dn) && isset($dn['dn'][0])) {
|
||||
$dn = $dn['dn'][0];
|
||||
}
|
||||
return $this->getGroupsByMember($dn, $seen);
|
||||
};
|
||||
|
||||
if (empty($dn)) {
|
||||
$dn = "";
|
||||
$fetcher = function ($dn) use (&$seen) {
|
||||
if (is_array($dn) && isset($dn['dn'][0])) {
|
||||
$dn = $dn['dn'][0];
|
||||
}
|
||||
return $this->getGroupsByMember($dn, $seen);
|
||||
};
|
||||
|
||||
$allGroups = $this->walkNestedGroups($dn, $fetcher, $groups, $seen);
|
||||
if (empty($dn)) {
|
||||
$dn = "";
|
||||
}
|
||||
|
||||
$allGroups = $this->walkNestedGroups($dn, $fetcher, $groups, $seen);
|
||||
$visibleGroups = $this->filterValidGroups($allGroups);
|
||||
return array_intersect_key($allGroups, $visibleGroups);
|
||||
}
|
||||
|
|
@ -1349,7 +1347,7 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I
|
|||
$this->access->groupname2dn($gid),
|
||||
$this->access->connection->ldapGroupDisplayName);
|
||||
|
||||
if ($displayName && (count($displayName) > 0)) {
|
||||
if (($displayName !== false) && (count($displayName) > 0)) {
|
||||
$displayName = $displayName[0];
|
||||
$this->access->connection->writeToCache($cacheKey, $displayName);
|
||||
return $displayName;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ interface ILDAPWrapper {
|
|||
* Retrieve the LDAP pagination cookie
|
||||
* @param resource|\LDAP\Connection $link LDAP link resource
|
||||
* @param resource|\LDAP\Result $result LDAP result resource
|
||||
* @param string $cookie structure sent by LDAP server
|
||||
* @param string &$cookie structure sent by LDAP server
|
||||
* @return bool true on success, false otherwise
|
||||
*
|
||||
* Corresponds to ldap_control_paged_result_response
|
||||
|
|
@ -178,8 +178,8 @@ interface ILDAPWrapper {
|
|||
/**
|
||||
* Sets the value of the specified option to be $value
|
||||
* @param resource|\LDAP\Connection $link LDAP link resource
|
||||
* @param string $option a defined LDAP Server option
|
||||
* @param int $value the new value for the option
|
||||
* @param int $option a defined LDAP Server option
|
||||
* @param mixed $value the new value for the option
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function setOption($link, $option, $value);
|
||||
|
|
|
|||
|
|
@ -280,12 +280,9 @@ abstract class AbstractMapping {
|
|||
/**
|
||||
* Searches mapped names by the giving string in the name column
|
||||
*
|
||||
* @param string $search
|
||||
* @param string $prefixMatch
|
||||
* @param string $postfixMatch
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNamesBySearch($search, $prefixMatch = "", $postfixMatch = "") {
|
||||
public function getNamesBySearch(string $search, string $prefixMatch = "", string $postfixMatch = ""): array {
|
||||
$statement = $this->dbc->prepare('
|
||||
SELECT `owncloud_name`
|
||||
FROM `' . $this->getTableName() . '`
|
||||
|
|
|
|||
|
|
@ -266,8 +266,8 @@ class User {
|
|||
|
||||
/**
|
||||
* returns the home directory of the user if specified by LDAP settings
|
||||
* @param string $valueFromLDAP
|
||||
* @return bool|string
|
||||
* @param ?string $valueFromLDAP
|
||||
* @return false|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getHomePath($valueFromLDAP = null) {
|
||||
|
|
@ -278,8 +278,7 @@ class User {
|
|||
&& strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
|
||||
&& $this->access->connection->homeFolderNamingRule !== 'attr:') {
|
||||
$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
|
||||
$homedir = $this->access->readAttribute(
|
||||
$this->access->username2dn($this->getUsername()), $attr);
|
||||
$homedir = $this->access->readAttribute($this->access->username2dn($this->getUsername()), $attr);
|
||||
if ($homedir && isset($homedir[0])) {
|
||||
$path = $homedir[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class AccessTest extends TestCase {
|
|||
private function getConnectorAndLdapMock() {
|
||||
$lw = $this->createMock(ILDAPWrapper::class);
|
||||
$connector = $this->getMockBuilder(Connection::class)
|
||||
->setConstructorArgs([$lw, null, null])
|
||||
->setConstructorArgs([$lw, '', null])
|
||||
->getMock();
|
||||
$um = $this->getMockBuilder(Manager::class)
|
||||
->setConstructorArgs([
|
||||
|
|
@ -494,7 +494,7 @@ class AccessTest extends TestCase {
|
|||
->willReturn(true);
|
||||
$connection = $this->createMock(LDAP::class);
|
||||
$this->connection
|
||||
->expects($this->once())
|
||||
->expects($this->any())
|
||||
->method('getConnectionResource')
|
||||
->willReturn($connection);
|
||||
$this->ldap
|
||||
|
|
@ -518,7 +518,7 @@ class AccessTest extends TestCase {
|
|||
->willReturn(true);
|
||||
$connection = $this->createMock(LDAP::class);
|
||||
$this->connection
|
||||
->expects($this->once())
|
||||
->expects($this->any())
|
||||
->method('getConnectionResource')
|
||||
->willReturn($connection);
|
||||
$this->ldap
|
||||
|
|
|
|||
|
|
@ -104,14 +104,12 @@ class Group_LDAPTest extends TestCase {
|
|||
$lw = $this->createMock(ILDAPWrapper::class);
|
||||
$connector = $this->getMockBuilder(Connection::class)
|
||||
->setMethods($conMethods)
|
||||
->setConstructorArgs([$lw, null, null])
|
||||
->setConstructorArgs([$lw, '', null])
|
||||
->getMock();
|
||||
|
||||
$access = $this->createMock(Access::class);
|
||||
|
||||
$access->expects($this->any())
|
||||
->method('getConnection')
|
||||
->willReturn($connector);
|
||||
$access->connection = $connector;
|
||||
|
||||
$access->userManager = $this->createMock(Manager::class);
|
||||
|
||||
|
|
@ -133,6 +131,8 @@ class Group_LDAPTest extends TestCase {
|
|||
->willReturnCallback(function ($name) {
|
||||
if ($name === 'ldapDynamicGroupMemberURL') {
|
||||
return '';
|
||||
} elseif ($name === 'ldapBaseGroups') {
|
||||
return [];
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
|
@ -953,6 +953,8 @@ class Group_LDAPTest extends TestCase {
|
|||
return 'member';
|
||||
case 'ldapGroupFilter':
|
||||
return $groupFilter;
|
||||
case 'ldapBaseGroups':
|
||||
return [];
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
|
@ -1321,16 +1323,16 @@ class Group_LDAPTest extends TestCase {
|
|||
});
|
||||
|
||||
$access->connection = $this->createMock(Connection::class);
|
||||
if (count($groupsInfo) > 1) {
|
||||
$access->connection->expects($this->any())
|
||||
->method('__get')
|
||||
->willReturnCallback(function ($name) {
|
||||
if ($name === 'ldapNestedGroups') {
|
||||
return 1;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
$access->connection->expects($this->any())
|
||||
->method('__get')
|
||||
->willReturnCallback(function ($name) {
|
||||
if ($name === 'ldapNestedGroups') {
|
||||
return 1;
|
||||
} elseif ($name === 'ldapGroupMemberAssocAttr') {
|
||||
return 'attr';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
/** @var GroupPluginManager $pluginManager */
|
||||
$pluginManager = $this->createMock(GroupPluginManager::class);
|
||||
|
|
@ -1373,6 +1375,10 @@ class Group_LDAPTest extends TestCase {
|
|||
return null;
|
||||
});
|
||||
|
||||
$access->expects($this->any())
|
||||
->method('groupname2dn')
|
||||
->willReturn('fakedn');
|
||||
|
||||
/** @var GroupPluginManager $pluginManager */
|
||||
$pluginManager = $this->createMock(GroupPluginManager::class);
|
||||
|
||||
|
|
|
|||
|
|
@ -1016,6 +1016,10 @@ class UserTest extends \Test\TestCase {
|
|||
->method('readAttribute')
|
||||
->willReturn(false);
|
||||
|
||||
$this->access->expects($this->once())
|
||||
->method('username2dn')
|
||||
->willReturn($this->dn);
|
||||
|
||||
// asks for "enforce_home_folder_naming_rule"
|
||||
$this->config->expects($this->once())
|
||||
->method('getAppValue')
|
||||
|
|
@ -1038,6 +1042,10 @@ class UserTest extends \Test\TestCase {
|
|||
->method('readAttribute')
|
||||
->willReturn(false);
|
||||
|
||||
$this->access->expects($this->once())
|
||||
->method('username2dn')
|
||||
->willReturn($this->dn);
|
||||
|
||||
// asks for "enforce_home_folder_naming_rule"
|
||||
$this->config->expects($this->once())
|
||||
->method('getAppValue')
|
||||
|
|
|
|||
|
|
@ -815,13 +815,15 @@ class User_LDAPTest extends TestCase {
|
|||
|
||||
private function prepareAccessForGetDisplayName() {
|
||||
$this->connection->expects($this->any())
|
||||
->method('__get')
|
||||
->willReturnCallback(function ($name) {
|
||||
if ($name === 'ldapUserDisplayName') {
|
||||
return 'displayname';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
->method('__get')
|
||||
->willReturnCallback(function ($name) {
|
||||
if ($name === 'ldapUserDisplayName') {
|
||||
return 'displayname';
|
||||
} elseif ($name === 'ldapUserDisplayName2') {
|
||||
return 'displayname2';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
$this->access->expects($this->any())
|
||||
->method('readAttribute')
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class WizardTest extends TestCase {
|
|||
/** @var Configuration|\PHPUnit\Framework\MockObject\MockObject $conf */
|
||||
$conf = $this->getMockBuilder(Configuration::class)
|
||||
->setMethods($confMethods)
|
||||
->setConstructorArgs([$lw, null, null])
|
||||
->setConstructorArgs(['', true])
|
||||
->getMock();
|
||||
|
||||
/** @var Access|\PHPUnit\Framework\MockObject\MockObject $access */
|
||||
|
|
|
|||
Loading…
Reference in a new issue