2011-08-04 20:32:01 +00:00
|
|
|
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
|
|
|
|
|
|
|
var assert = require('assert');
|
|
|
|
var util = require('util');
|
|
|
|
|
|
|
|
var LDAPResult = require('./result');
|
|
|
|
var SearchEntry = require('./search_entry');
|
2011-09-27 18:49:33 +00:00
|
|
|
var SearchReference = require('./search_reference');
|
2011-08-04 20:32:01 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
var parseDN = require('../dn').parse;
|
2011-09-27 18:49:33 +00:00
|
|
|
var parseURL = require('../url').parse;
|
2011-08-04 20:32:01 +00:00
|
|
|
var Protocol = require('../protocol');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///--- API
|
|
|
|
|
|
|
|
function SearchResponse(options) {
|
|
|
|
if (!options)
|
|
|
|
options = {};
|
|
|
|
if (typeof(options) !== 'object')
|
|
|
|
throw new TypeError('options must be an object');
|
|
|
|
|
|
|
|
options.protocolOp = Protocol.LDAP_REP_SEARCH;
|
|
|
|
LDAPResult.call(this, options);
|
2011-08-12 23:37:47 +00:00
|
|
|
|
|
|
|
this.attributes = options.attributes ? options.attributes.slice() : [];
|
|
|
|
this.notAttributes = [];
|
2011-09-13 21:49:21 +00:00
|
|
|
this.sentEntries = 0;
|
2011-08-04 20:32:01 +00:00
|
|
|
}
|
|
|
|
util.inherits(SearchResponse, LDAPResult);
|
|
|
|
module.exports = SearchResponse;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Allows you to send a SearchEntry back to the client.
|
|
|
|
*
|
|
|
|
* @param {Object} entry an instance of SearchEntry.
|
2011-09-16 16:06:35 +00:00
|
|
|
* @param {Boolean} nofiltering skip filtering notAttributes and '_' attributes.
|
|
|
|
* Defaults to 'false'.
|
2011-08-04 20:32:01 +00:00
|
|
|
*/
|
2011-09-16 16:06:35 +00:00
|
|
|
SearchResponse.prototype.send = function(entry, nofiltering) {
|
2011-08-12 23:37:47 +00:00
|
|
|
if (!entry || typeof(entry) !== 'object')
|
2011-08-04 20:32:01 +00:00
|
|
|
throw new TypeError('entry (SearchEntry) required');
|
2011-09-16 16:06:35 +00:00
|
|
|
if (nofiltering === undefined)
|
|
|
|
nofiltering = false;
|
2011-10-17 23:37:09 +00:00
|
|
|
if (typeof(nofiltering) !== 'boolean')
|
|
|
|
throw new TypeError('noFiltering must be a boolean');
|
2011-08-04 20:32:01 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
var self = this;
|
|
|
|
|
2011-09-27 18:49:33 +00:00
|
|
|
if (entry instanceof SearchEntry || entry instanceof SearchReference) {
|
|
|
|
if (!entry.messageID)
|
|
|
|
entry.messageID = this.messageID;
|
|
|
|
if (entry.messageID !== this.messageID)
|
|
|
|
throw new Error('SearchEntry messageID mismatch');
|
|
|
|
} else {
|
2011-08-12 23:37:47 +00:00
|
|
|
if (!entry.attributes)
|
|
|
|
throw new Error('entry.attributes required');
|
|
|
|
|
2011-10-17 23:37:09 +00:00
|
|
|
var all = (self.attributes.indexOf('*') !== -1);
|
|
|
|
Object.keys(entry.attributes).forEach(function(a) {
|
|
|
|
var _a = a.toLowerCase();
|
|
|
|
if (!nofiltering && _a.length && _a[0] === '_') {
|
|
|
|
delete entry.attributes[a];
|
|
|
|
} else if (self.notAttributes.indexOf(_a) !== -1) {
|
|
|
|
delete entry.attributes[a];
|
|
|
|
} else if (all) {
|
|
|
|
// noop
|
|
|
|
} else if (self.attributes.length && self.attributes.indexOf(_a) === -1) {
|
|
|
|
delete entry.attributes[a];
|
|
|
|
}
|
|
|
|
});
|
2011-10-11 17:43:27 +00:00
|
|
|
|
2011-10-17 23:37:09 +00:00
|
|
|
var save = entry;
|
2011-08-12 23:37:47 +00:00
|
|
|
entry = new SearchEntry({
|
|
|
|
objectName: typeof(save.dn) === 'string' ? parseDN(save.dn) : save.dn,
|
|
|
|
messageID: self.messageID,
|
|
|
|
log4js: self.log4js
|
|
|
|
});
|
|
|
|
entry.fromObject(save);
|
|
|
|
}
|
2011-08-04 20:32:01 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
try {
|
|
|
|
if (this.log.isDebugEnabled())
|
|
|
|
this.log.debug('%s: sending: %j', this.connection.ldap.id, entry.json);
|
|
|
|
|
|
|
|
this.connection.write(entry.toBer());
|
2011-09-13 21:49:21 +00:00
|
|
|
this.sentEntries++;
|
2011-08-12 23:37:47 +00:00
|
|
|
} catch (e) {
|
|
|
|
this.log.warn('%s failure to write message %j: %s',
|
|
|
|
this.connection.ldap.id, this.json, e.toString());
|
|
|
|
}
|
2011-08-04 20:32:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-10-17 23:37:09 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
SearchResponse.prototype.createSearchEntry = function(object) {
|
|
|
|
if (!object || typeof(object) !== 'object')
|
|
|
|
throw new TypeError('object required');
|
|
|
|
|
|
|
|
var self = this;
|
2011-08-04 20:32:01 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
var entry = new SearchEntry({
|
|
|
|
messageID: self.messageID,
|
|
|
|
log4js: self.log4js,
|
|
|
|
objectName: object.objectName || object.dn
|
|
|
|
});
|
|
|
|
entry.fromObject((object.attributes || object));
|
2011-08-04 20:32:01 +00:00
|
|
|
|
2011-08-12 23:37:47 +00:00
|
|
|
return entry;
|
2011-08-04 20:32:01 +00:00
|
|
|
};
|
2011-09-27 18:49:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
SearchResponse.prototype.createSearchReference = function(uris) {
|
|
|
|
if (!uris)
|
|
|
|
throw new TypeError('uris ([string]) required');
|
|
|
|
|
|
|
|
if (!Array.isArray(uris))
|
|
|
|
uris = [uris];
|
|
|
|
|
|
|
|
for (var i = 0; i < uris.length; i++) {
|
|
|
|
if (typeof(uris[i]) == 'string')
|
|
|
|
uris[i] = parseURL(uris[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
return new SearchReference({
|
|
|
|
messageID: self.messageID,
|
|
|
|
log4js: self.log4js,
|
|
|
|
uris: uris
|
|
|
|
});
|
|
|
|
};
|