2019-08-27 21:11:49 +00:00
|
|
|
/// --- Globals
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
// var parseDN = require('./dn').parse
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2020-10-31 21:07:32 +00:00
|
|
|
const EntryChangeNotificationControl =
|
2019-08-27 21:11:49 +00:00
|
|
|
require('./controls').EntryChangeNotificationControl
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
/// --- API
|
2012-02-21 01:21:53 +00:00
|
|
|
|
|
|
|
// Cache used to store connected persistent search clients
|
2019-08-27 21:11:49 +00:00
|
|
|
function PersistentSearch () {
|
|
|
|
this.clientList = []
|
2012-02-21 01:21:53 +00:00
|
|
|
}
|
2012-02-23 23:21:17 +00:00
|
|
|
|
2012-02-24 00:02:52 +00:00
|
|
|
PersistentSearch.prototype.addClient = function (req, res, callback) {
|
2019-08-27 21:11:49 +00:00
|
|
|
if (typeof (req) !== 'object') { throw new TypeError('req must be an object') }
|
|
|
|
if (typeof (res) !== 'object') { throw new TypeError('res must be an object') }
|
|
|
|
if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') }
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2020-10-31 21:07:32 +00:00
|
|
|
const log = req.log
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2020-10-31 21:07:32 +00:00
|
|
|
const client = {}
|
2019-08-27 21:11:49 +00:00
|
|
|
client.req = req
|
|
|
|
client.res = res
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
log.debug('%s storing client', req.logId)
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
this.clientList.push(client)
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
log.debug('%s stored client', req.logId)
|
2012-02-21 01:21:53 +00:00
|
|
|
log.debug('%s total number of clients %s',
|
2019-08-27 21:11:49 +00:00
|
|
|
req.logId, this.clientList.length)
|
|
|
|
if (callback) { callback(client) }
|
|
|
|
}
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2012-02-24 00:02:52 +00:00
|
|
|
PersistentSearch.prototype.removeClient = function (req, res, callback) {
|
2019-08-27 21:11:49 +00:00
|
|
|
if (typeof (req) !== 'object') { throw new TypeError('req must be an object') }
|
|
|
|
if (typeof (res) !== 'object') { throw new TypeError('res must be an object') }
|
|
|
|
if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') }
|
|
|
|
|
2020-10-31 21:07:32 +00:00
|
|
|
const log = req.log
|
2019-08-27 21:11:49 +00:00
|
|
|
log.debug('%s removing client', req.logId)
|
2020-10-31 21:07:32 +00:00
|
|
|
const client = {}
|
2019-08-27 21:11:49 +00:00
|
|
|
client.req = req
|
|
|
|
client.res = res
|
2012-02-21 01:21:53 +00:00
|
|
|
|
|
|
|
// remove the client if it exists
|
2012-02-24 00:02:52 +00:00
|
|
|
this.clientList.forEach(function (element, index, array) {
|
2012-02-21 01:21:53 +00:00
|
|
|
if (element.req === client.req) {
|
2019-08-27 21:11:49 +00:00
|
|
|
log.debug('%s removing client from list', req.logId)
|
|
|
|
array.splice(index, 1)
|
2012-02-21 01:21:53 +00:00
|
|
|
}
|
2019-08-27 21:11:49 +00:00
|
|
|
})
|
2012-02-21 01:21:53 +00:00
|
|
|
|
|
|
|
log.debug('%s number of persistent search clients %s',
|
2019-08-27 21:11:49 +00:00
|
|
|
req.logId, this.clientList.length)
|
|
|
|
if (callback) { callback(client) }
|
|
|
|
}
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
function getOperationType (requestType) {
|
2012-02-24 00:02:52 +00:00
|
|
|
switch (requestType) {
|
2012-02-21 01:21:53 +00:00
|
|
|
case 'AddRequest':
|
|
|
|
case 'add':
|
2019-08-27 21:11:49 +00:00
|
|
|
return 1
|
2012-02-21 01:21:53 +00:00
|
|
|
case 'DeleteRequest':
|
|
|
|
case 'delete':
|
2019-08-27 21:11:49 +00:00
|
|
|
return 2
|
2012-02-21 01:21:53 +00:00
|
|
|
case 'ModifyRequest':
|
|
|
|
case 'modify':
|
2019-08-27 21:11:49 +00:00
|
|
|
return 4
|
2012-02-21 01:21:53 +00:00
|
|
|
case 'ModifyDNRequest':
|
|
|
|
case 'modrdn':
|
2019-08-27 21:11:49 +00:00
|
|
|
return 8
|
2012-02-21 01:21:53 +00:00
|
|
|
default:
|
|
|
|
throw new TypeError('requestType %s, is an invalid request type',
|
2019-08-27 21:11:49 +00:00
|
|
|
requestType)
|
2012-02-21 01:21:53 +00:00
|
|
|
}
|
2012-02-23 23:21:17 +00:00
|
|
|
}
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2020-12-07 01:26:27 +00:00
|
|
|
function getEntryChangeNotificationControl (req, obj) {
|
2012-02-21 01:21:53 +00:00
|
|
|
// if we want to return a ECNC
|
|
|
|
if (req.persistentSearch.value.returnECs) {
|
2020-10-31 21:07:32 +00:00
|
|
|
const attrs = obj.attributes
|
|
|
|
const value = {}
|
2019-08-27 21:11:49 +00:00
|
|
|
value.changeType = getOperationType(attrs.changetype)
|
2012-02-21 01:21:53 +00:00
|
|
|
// if it's a modDN request, fill in the previous DN
|
|
|
|
if (value.changeType === 8 && attrs.previousDN) {
|
2019-08-27 21:11:49 +00:00
|
|
|
value.previousDN = attrs.previousDN
|
2012-02-21 01:21:53 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
value.changeNumber = attrs.changenumber
|
|
|
|
return new EntryChangeNotificationControl({ value: value })
|
2012-02-21 01:21:53 +00:00
|
|
|
} else {
|
2019-08-27 21:11:49 +00:00
|
|
|
return false
|
2012-02-21 01:21:53 +00:00
|
|
|
}
|
2012-02-23 23:21:17 +00:00
|
|
|
}
|
2012-02-21 01:21:53 +00:00
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
function checkChangeType (req, requestType) {
|
2012-02-21 01:21:53 +00:00
|
|
|
return (req.persistentSearch.value.changeTypes &
|
2019-08-27 21:11:49 +00:00
|
|
|
getOperationType(requestType))
|
2012-02-23 23:21:17 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 21:11:49 +00:00
|
|
|
/// --- Exports
|
2012-02-23 23:21:17 +00:00
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
PersistentSearchCache: PersistentSearch,
|
|
|
|
checkChangeType: checkChangeType,
|
|
|
|
getEntryChangeNotificationControl: getEntryChangeNotificationControl
|
2019-08-27 21:11:49 +00:00
|
|
|
}
|