ldap: automatically detect if server supports pagination

This commit is contained in:
Girish Ramakrishnan
2025-02-26 12:18:09 +01:00
parent 28eee609de
commit f78f6634fa
2 changed files with 36 additions and 9 deletions

View File

@@ -170,33 +170,60 @@ async function clientSearch(client, dn, searchOptions) {
});
}
async function supportsPagination(client) {
assert.strictEqual(typeof client, 'object');
const searchOptions = {
scope: 'base',
filter: '(objectClass=*)',
attributes: ['supportedControl', 'supportedExtension', 'supportedFeature']
};
const result = await clientSearch(client, '', searchOptions);
client.unbind();
const controls = result.supportedControl;
if (!controls || !Array.isArray(controls)) {
debug('supportsPagination: no supportedControl attribute returned');
return false;
}
if (!controls.includes(ldap.PagedResultsControl.OID)) {
debug('supportsPagination: server does not support pagination. Available controls:', controls);
return false;
}
debug('supportsPagination: server supports pagination');
return true;
}
async function ldapGetByDN(config, dn) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof dn, 'string');
const searchOptions = {
paged: true,
scope: 'sub' // We may have to make this configurable
};
debug(`ldapGetByDN: Get object at ${dn}`);
const client = await getClient(config, { bind: true });
const paged = await supportsPagination(client);
const searchOptions = {
paged,
scope: 'sub'
};
const result = await clientSearch(client, dn, searchOptions);
client.unbind();
if (result.length === 0) throw new BoxError(BoxError.NOT_FOUND, `dn ${dn} not found`);
return result[0];
}
// TODO support search by email
async function ldapUserSearch(config, options) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof options, 'object');
const client = await getClient(config, { bind: true });
const paged = await supportsPagination(client);
const searchOptions = {
paged: true,
paged,
filter: ldap.parseFilter(config.filter),
scope: 'sub' // We may have to make this configurable
scope: 'sub'
};
if (options.filter) { // https://github.com/ldapjs/node-ldapjs/blob/master/docs/filters.md
@@ -204,7 +231,6 @@ async function ldapUserSearch(config, options) {
searchOptions.filter = new ldap.AndFilter({ filters: [ extraFilter, searchOptions.filter ] });
}
const client = await getClient(config, { bind: true });
const result = await clientSearch(client, config.baseDn, searchOptions);
client.unbind();
return result;