mirror of
https://github.com/nextcloud/server.git
synced 2025-03-15 00:43:23 +00:00
Unfold call to ldap_parse_result. Handle cookie outside of adapter.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
parent
3c9b1c5296
commit
d10dfa84db
4 changed files with 33 additions and 112 deletions
apps/user_ldap/lib
|
@ -95,8 +95,7 @@ class Access extends LDAPUtility {
|
|||
private $ncUserManager;
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
/** @var string */
|
||||
private $lastCookie = '';
|
||||
private string $lastCookie = '';
|
||||
|
||||
public function __construct(
|
||||
Connection $connection,
|
||||
|
@ -1910,7 +1909,7 @@ class Access extends LDAPUtility {
|
|||
* @return bool
|
||||
*/
|
||||
public function hasMoreResults() {
|
||||
if (empty($this->lastCookie) && $this->lastCookie !== '0') {
|
||||
if ($this->lastCookie === '') {
|
||||
// as in RFC 2696, when all results are returned, the cookie will
|
||||
// be empty.
|
||||
return false;
|
||||
|
@ -1962,8 +1961,8 @@ class Access extends LDAPUtility {
|
|||
'offset' => $offset
|
||||
]
|
||||
);
|
||||
//get the cookie from the search for the previous search, required by LDAP
|
||||
if (empty($this->lastCookie) && $this->lastCookie !== "0" && ($offset > 0)) {
|
||||
// Get the cookie from the search for the previous search, required by LDAP
|
||||
if (($this->lastCookie === '') && ($offset > 0)) {
|
||||
// no cookie known from a potential previous search. We need
|
||||
// to start from 0 to come to the desired page. cookie value
|
||||
// of '0' is valid, because 389ds
|
||||
|
@ -1980,15 +1979,15 @@ class Access extends LDAPUtility {
|
|||
$this->abandonPagedSearch();
|
||||
}
|
||||
$pagedSearchOK = true;
|
||||
$this->invokeLDAPMethod('controlPagedResult', $limit, false);
|
||||
$this->invokeLDAPMethod('controlPagedResult', $limit, false, $this->lastCookie);
|
||||
$this->logger->debug('Ready for a paged search', ['app' => 'user_ldap']);
|
||||
/* ++ Fixing RHDS searches with pages with zero results ++
|
||||
* We couldn't get paged searches working with our RHDS for login ($limit = 0),
|
||||
* due to pages with zero results.
|
||||
* So we added "&& !empty($this->lastCookie)" to this test to ignore pagination
|
||||
* if we don't have a previous paged search.
|
||||
*/
|
||||
} elseif (!empty($this->lastCookie)) {
|
||||
/* ++ Fixing RHDS searches with pages with zero results ++
|
||||
* We couldn't get paged searches working with our RHDS for login ($limit = 0),
|
||||
* due to pages with zero results.
|
||||
* So we added "&& !empty($this->lastCookie)" to this test to ignore pagination
|
||||
* if we don't have a previous paged search.
|
||||
*/
|
||||
} elseif ($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.
|
||||
|
@ -1997,7 +1996,7 @@ class Access extends LDAPUtility {
|
|||
// be returned.
|
||||
$pageSize = (int)$this->connection->ldapPagingSize > 0 ? (int)$this->connection->ldapPagingSize : 500;
|
||||
$pagedSearchOK = true;
|
||||
$this->invokeLDAPMethod('controlPagedResult', $pageSize, false);
|
||||
$this->invokeLDAPMethod('controlPagedResult', $pageSize, false, $this->lastCookie);
|
||||
}
|
||||
|
||||
return $pagedSearchOK;
|
||||
|
|
|
@ -87,19 +87,23 @@ class LDAP implements ILDAPWrapper {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public function controlPagedResultResponse($link, $result, &$cookie): bool {
|
||||
$this->preFunctionCall(
|
||||
$this->pagedResultsAdapter->getResponseCallFunc(),
|
||||
$this->pagedResultsAdapter->getResponseCallArgs([$link, $result, &$cookie])
|
||||
);
|
||||
$errorCode = 0;
|
||||
$errorMessage = '';
|
||||
$controls = [];
|
||||
$matchedDn = null;
|
||||
$referrals = [];
|
||||
$success = $this->invokeLDAPMethod('parse_result', $link, $result,
|
||||
$errorCode,
|
||||
$matchedDn,
|
||||
$errorMessage,
|
||||
$referrals,
|
||||
$controls);
|
||||
|
||||
$result = $this->pagedResultsAdapter->responseCall($link);
|
||||
$cookie = $this->pagedResultsAdapter->getCookie($link);
|
||||
$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
|
||||
|
||||
if ($this->isResultFalse($result)) {
|
||||
$this->postFunctionCall();
|
||||
}
|
||||
// TODO do not ignore error code and message
|
||||
|
||||
return $result;
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,31 +35,7 @@ interface IAdapter {
|
|||
* The adapter receives paged result parameters from the client. It may
|
||||
* store the parameters for later use.
|
||||
*/
|
||||
public function setRequestParameters($link, int $pageSize, bool $isCritical): void;
|
||||
|
||||
/**
|
||||
* The adapter shall report which PHP function will be called to process
|
||||
* the paged results call
|
||||
*
|
||||
* It will used by the callee for diagnosis and error handling.
|
||||
*/
|
||||
public function getResponseCallFunc(): string;
|
||||
|
||||
/**
|
||||
* The adapter shall report with arguments will be provided to the LDAP
|
||||
* function it will call
|
||||
*
|
||||
* It will used by the callee for diagnosis and error handling.
|
||||
*/
|
||||
public function getResponseCallArgs(array $originalArgs): array;
|
||||
|
||||
/**
|
||||
* the adapter should do its LDAP function call and return success state
|
||||
*
|
||||
* @param resource|\LDAP\Connection $link LDAP resource
|
||||
* @return bool
|
||||
*/
|
||||
public function responseCall($link): bool;
|
||||
public function setRequestParameters($link, int $pageSize, bool $isCritical, string $cookie = ''): void;
|
||||
|
||||
/**
|
||||
* The adapter receives the parameters that were passed to a search
|
||||
|
@ -80,12 +56,4 @@ interface IAdapter {
|
|||
* ldap_search function.
|
||||
*/
|
||||
public function getSearchArgs($link): array;
|
||||
|
||||
/**
|
||||
* Returns the current paged results cookie
|
||||
*
|
||||
* @param resource|\LDAP\Connection $link LDAP resource
|
||||
* @return string
|
||||
*/
|
||||
public function getCookie($link): string;
|
||||
}
|
||||
|
|
|
@ -39,55 +39,7 @@ class Php73 implements IAdapter {
|
|||
/** @var array */
|
||||
protected $linkData = [];
|
||||
|
||||
public function getResponseCallFunc(): string {
|
||||
return 'ldap_parse_result';
|
||||
}
|
||||
|
||||
public function responseCall($link): bool {
|
||||
$linkId = $this->getLinkId($link);
|
||||
return ldap_parse_result(...$this->linkData[$linkId]['responseArgs']);
|
||||
}
|
||||
|
||||
public function getResponseCallArgs(array $originalArgs): array {
|
||||
$link = array_shift($originalArgs);
|
||||
$linkId = $this->getLinkId($link);
|
||||
|
||||
if (!isset($this->linkData[$linkId])) {
|
||||
$this->linkData[$linkId] = [];
|
||||
}
|
||||
|
||||
$this->linkData[$linkId]['responseErrorCode'] = 0;
|
||||
$this->linkData[$linkId]['responseErrorMessage'] = '';
|
||||
$this->linkData[$linkId]['serverControls'] = [];
|
||||
$matchedDn = null;
|
||||
$referrals = [];
|
||||
|
||||
$this->linkData[$linkId]['responseArgs'] = [
|
||||
$link,
|
||||
array_shift($originalArgs),
|
||||
&$this->linkData[$linkId]['responseErrorCode'],
|
||||
$matchedDn,
|
||||
&$this->linkData[$linkId]['responseErrorMessage'],
|
||||
$referrals,
|
||||
&$this->linkData[$linkId]['serverControls']
|
||||
];
|
||||
|
||||
|
||||
return $this->linkData[$linkId]['responseArgs'];
|
||||
}
|
||||
|
||||
public function getCookie($link): string {
|
||||
$linkId = $this->getLinkId($link);
|
||||
return $this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
|
||||
}
|
||||
|
||||
private function resetCookie(int $linkId): void {
|
||||
if (isset($this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
|
||||
$this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
public function setRequestParameters($link, int $pageSize, bool $isCritical): void {
|
||||
public function setRequestParameters($link, int $pageSize, bool $isCritical, string $cookie = ''): void {
|
||||
$linkId = $this->getLinkId($link);
|
||||
if (!isset($this->linkData[$linkId])) {
|
||||
$this->linkData[$linkId] = [];
|
||||
|
@ -95,10 +47,7 @@ class Php73 implements IAdapter {
|
|||
$this->linkData[$linkId]['requestArgs'] = [];
|
||||
$this->linkData[$linkId]['requestArgs']['pageSize'] = $pageSize;
|
||||
$this->linkData[$linkId]['requestArgs']['isCritical'] = $isCritical;
|
||||
|
||||
if ($pageSize === 0) {
|
||||
$this->resetCookie($linkId);
|
||||
}
|
||||
$this->linkData[$linkId]['requestArgs']['cookie'] = $cookie;
|
||||
}
|
||||
|
||||
public function setSearchArgs(
|
||||
|
@ -132,8 +81,9 @@ class Php73 implements IAdapter {
|
|||
'oid' => LDAP_CONTROL_PAGEDRESULTS,
|
||||
'value' => [
|
||||
'size' => $this->linkData[$linkId]['requestArgs']['pageSize'],
|
||||
'cookie' => $this->linkData[$linkId]['serverControls'][LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '',
|
||||
]
|
||||
'cookie' => $this->linkData[$linkId]['requestArgs']['cookie'],
|
||||
],
|
||||
'iscritical' => $this->linkData[$linkId]['requestArgs']['isCritical'],
|
||||
]];
|
||||
|
||||
$this->linkData[$linkId][$methodKey][] = -1; // timelimit
|
||||
|
|
Loading…
Reference in a new issue