123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- '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()
- })
- })
- })
|