Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.

Commit

Permalink
Resolve issue #845
Browse files Browse the repository at this point in the history
This issue resolves issue #845 by updating `@ldapjs/messages` to the
latest version and adding a test that shows how the module should be
used to evaluate search request scopes.
  • Loading branch information
jsumners committed Mar 8, 2023
1 parent 0dfe40e commit 824dd2c
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@ldapjs/controls": "2.0.0",
"@ldapjs/dn": "1.0.0",
"@ldapjs/filter": "2.0.0",
"@ldapjs/messages": "1.0.0",
"@ldapjs/messages": "1.0.1",
"@ldapjs/protocol": "^1.2.1",
"abstract-logging": "^2.0.1",
"assert-plus": "^1.0.0",
Expand Down
116 changes: 116 additions & 0 deletions test/issue-845.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use strict'

const tap = require('tap')
const { SearchResultEntry, SearchRequest } = require('@ldapjs/messages')
const ldapjs = require('../')

const server = ldapjs.createServer()

const SUFFIX = ''
const directory = {
'dc=example,dc=com': {
objectclass: 'example',
dc: 'example',
cn: 'example'
}
}

server.bind(SUFFIX, (req, res, done) => {
res.end()
return done()
})

server.search(SUFFIX, (req, res, done) => {
const dn = req.dn.toString().toLowerCase()

if (Object.hasOwn(directory, dn) === false) {
return done(Error('not in directory'))
}

switch (req.scope) {
case SearchRequest.SCOPE_BASE:
case SearchRequest.SCOPE_SUBTREE: {
res.send(new SearchResultEntry({ objectName: `dc=${req.scopeName}` }))
break
}
}

res.end()
done()
})

tap.beforeEach(t => {
return new Promise((resolve, reject) => {
server.listen(0, '127.0.0.1', (err) => {
if (err) return reject(err)
t.context.url = server.url

t.context.client = ldapjs.createClient({ url: [server.url] })
t.context.searchOpts = {
filter: '(&(objectClass=*))',
scope: 'sub',
attributes: ['dn', 'cn']
}

resolve()
})
})
})

tap.afterEach(t => {
return new Promise((resolve, reject) => {
t.context.client.destroy()
server.close((err) => {
if (err) return reject(err)
resolve()
})
})
})

tap.test('rejects if search not in directory', t => {
const { client, searchOpts } = t.context

client.search('dc=nope', searchOpts, (err, res) => {
t.error(err)
res.on('error', err => {
// TODO: plain error messages should not be lost
// This should be fixed in a revamp of the server code.
// ~ jsumners 2023-03-08
t.equal(err.lde_message, 'Operations Error')
t.end()
})
})
})

tap.test('base scope matches', t => {
const { client, searchOpts } = t.context
searchOpts.scope = 'base'

client.search('dc=example,dc=com', searchOpts, (err, res) => {
t.error(err)
res.on('error', (err) => {
t.error(err)
t.end()
})
res.on('searchEntry', entry => {
t.equal(entry.objectName.toString(), 'dc=base')
t.end()
})
})
})

tap.test('sub scope matches', t => {
const { client, searchOpts } = t.context

client.search('dc=example,dc=com', searchOpts, (err, res) => {
t.error(err)
res.on('error', (err) => {
t.error(err)
t.end()
})
res.on('searchEntry', entry => {
t.equal(entry.objectName.toString(), 'dc=subtree')
t.end()
})
})
})

0 comments on commit 824dd2c

Please sign in to comment.