node-ldapjs/examples/inmemory.js

178 lines
4.1 KiB
JavaScript
Raw Normal View History

2020-10-31 21:07:32 +00:00
const ldap = require('../lib/index')
2011-11-19 00:39:37 +00:00
/// --- Shared handlers
2011-11-19 00:39:37 +00:00
function authorize (req, res, next) {
/* Any user may search after bind, only cn=root has full power */
2020-10-31 21:07:32 +00:00
const isSearch = (req instanceof ldap.SearchRequest)
if (!req.connection.ldap.bindDN.equals('cn=root') && !isSearch) { return next(new ldap.InsufficientAccessRightsError()) }
2011-11-19 00:39:37 +00:00
return next()
2011-11-19 00:39:37 +00:00
}
/// --- Globals
2011-11-19 00:39:37 +00:00
2020-10-31 21:07:32 +00:00
const SUFFIX = 'o=smartdc'
const db = {}
const server = ldap.createServer()
2011-11-19 00:39:37 +00:00
server.bind('cn=root', function (req, res, next) {
if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') { return next(new ldap.InvalidCredentialsError()) }
2011-11-19 00:39:37 +00:00
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
server.add(SUFFIX, authorize, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
2011-11-19 00:39:37 +00:00
if (db[dn]) { return next(new ldap.EntryAlreadyExistsError(dn)) }
2011-11-19 00:39:37 +00:00
db[dn] = req.toObject().attributes
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
server.bind(SUFFIX, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) }
2011-11-19 00:39:37 +00:00
if (!db[dn].userpassword) { return next(new ldap.NoSuchAttributeError('userPassword')) }
2011-11-19 00:39:37 +00:00
if (db[dn].userpassword.indexOf(req.credentials) === -1) { return next(new ldap.InvalidCredentialsError()) }
2011-11-19 00:39:37 +00:00
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
server.compare(SUFFIX, authorize, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) }
2011-11-19 00:39:37 +00:00
if (!db[dn][req.attribute]) { return next(new ldap.NoSuchAttributeError(req.attribute)) }
2011-11-19 00:39:37 +00:00
2020-10-31 21:07:32 +00:00
let matches = false
const vals = db[dn][req.attribute]
for (let i = 0; i < vals.length; i++) {
2011-11-19 00:39:37 +00:00
if (vals[i] === req.value) {
matches = true
break
2011-11-19 00:39:37 +00:00
}
}
res.end(matches)
return next()
})
2011-11-19 00:39:37 +00:00
server.del(SUFFIX, authorize, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) }
2011-11-19 00:39:37 +00:00
delete db[dn]
2011-11-19 00:39:37 +00:00
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
server.modify(SUFFIX, authorize, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
if (!req.changes.length) { return next(new ldap.ProtocolError('changes required')) }
if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) }
2011-11-19 00:39:37 +00:00
2020-10-31 21:07:32 +00:00
const entry = db[dn]
2011-11-19 00:39:37 +00:00
let mod
2020-10-31 21:07:32 +00:00
for (let i = 0; i < req.changes.length; i++) {
mod = req.changes[i].modification
2011-11-19 00:39:37 +00:00
switch (req.changes[i].operation) {
case 'replace':
if (!entry[mod.type]) { return next(new ldap.NoSuchAttributeError(mod.type)) }
2011-11-19 00:39:37 +00:00
if (!mod.vals || !mod.vals.length) {
delete entry[mod.type]
} else {
entry[mod.type] = mod.vals
}
2011-11-19 00:39:37 +00:00
break
case 'add':
if (!entry[mod.type]) {
entry[mod.type] = mod.vals
} else {
mod.vals.forEach(function (v) {
if (entry[mod.type].indexOf(v) === -1) { entry[mod.type].push(v) }
})
}
2011-11-19 00:39:37 +00:00
break
2011-11-19 00:39:37 +00:00
case 'delete':
if (!entry[mod.type]) { return next(new ldap.NoSuchAttributeError(mod.type)) }
2011-11-19 00:39:37 +00:00
delete entry[mod.type]
2011-11-19 00:39:37 +00:00
break
2011-11-19 00:39:37 +00:00
}
}
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
server.search(SUFFIX, authorize, function (req, res, next) {
2020-10-31 21:07:32 +00:00
const dn = req.dn.toString()
if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) }
2011-11-19 00:39:37 +00:00
2020-10-31 21:07:32 +00:00
let scopeCheck
2011-11-19 00:39:37 +00:00
switch (req.scope) {
case 'base':
if (req.filter.matches(db[dn])) {
res.send({
dn: dn,
attributes: db[dn]
})
}
2011-11-19 00:39:37 +00:00
res.end()
return next()
2011-11-19 00:39:37 +00:00
case 'one':
scopeCheck = function (k) {
if (req.dn.equals(k)) { return true }
2011-11-19 00:39:37 +00:00
2020-10-31 21:07:32 +00:00
const parent = ldap.parseDN(k).parent()
return (parent ? parent.equals(req.dn) : false)
}
break
2011-11-19 00:39:37 +00:00
case 'sub':
scopeCheck = function (k) {
return (req.dn.equals(k) || req.dn.parentOf(k))
}
2011-11-19 00:39:37 +00:00
break
2011-11-19 00:39:37 +00:00
}
Object.keys(db).forEach(function (key) {
if (!scopeCheck(key)) { return }
2011-11-19 00:39:37 +00:00
if (req.filter.matches(db[key])) {
res.send({
dn: key,
attributes: db[key]
})
2011-11-19 00:39:37 +00:00
}
})
2011-11-19 00:39:37 +00:00
res.end()
return next()
})
2011-11-19 00:39:37 +00:00
/// --- Fire it up
2011-11-19 00:39:37 +00:00
server.listen(1389, function () {
console.log('LDAP server up at: %s', server.url)
})