GH-49 Allow options.attributes = "dn" in client.search
This commit is contained in:
parent
87d7ef977e
commit
44a9d87863
|
@ -621,6 +621,15 @@ Client.prototype.search = function(base, options, controls, callback) {
|
||||||
if (typeof(callback) !== 'function')
|
if (typeof(callback) !== 'function')
|
||||||
throw new TypeError('callback (function) required');
|
throw new TypeError('callback (function) required');
|
||||||
|
|
||||||
|
if (options.attributes) {
|
||||||
|
if (Array.isArray(options.attributes)) {
|
||||||
|
// noop
|
||||||
|
} else if (typeof(options.attributes) === 'string') {
|
||||||
|
options.attributes = [options.attributes];
|
||||||
|
} else {
|
||||||
|
throw new TypeError('options.attributes must be an Array of Strings');
|
||||||
|
}
|
||||||
|
}
|
||||||
var req = new SearchRequest({
|
var req = new SearchRequest({
|
||||||
baseObject: typeof(base) === 'string' ? dn.parse(base) : base,
|
baseObject: typeof(base) === 'string' ? dn.parse(base) : base,
|
||||||
scope: options.scope || 'base',
|
scope: options.scope || 'base',
|
||||||
|
@ -633,6 +642,8 @@ Client.prototype.search = function(base, options, controls, callback) {
|
||||||
controls: controls
|
controls: controls
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!this.connection)
|
if (!this.connection)
|
||||||
return callback(new ConnectionError('no connection'));
|
return callback(new ConnectionError('no connection'));
|
||||||
|
|
||||||
|
@ -698,18 +709,24 @@ Client.prototype._send = function(message, expect, callback, connection) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
function closedConn() {
|
function closeConn(err) {
|
||||||
if (conn)
|
var err = err || new ConnectionError('no connection');
|
||||||
conn.destroy();
|
|
||||||
|
// This is lame, but we want to send the original error back, whereas
|
||||||
|
// this will trigger a connection event
|
||||||
|
process.nextTick(function() {
|
||||||
|
if (conn)
|
||||||
|
conn.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
if (typeof(callback) === 'function')
|
if (typeof(callback) === 'function')
|
||||||
return callback(new ConnectionError('no connection'));
|
return callback(err);
|
||||||
|
|
||||||
return callback.emit('error', new ConnectionError('no connection'));
|
return callback.emit('error', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn)
|
if (!conn)
|
||||||
return closedConn();
|
return closeConn();
|
||||||
|
|
||||||
// Now set up the callback in the messages table
|
// Now set up the callback in the messages table
|
||||||
message.messageID = conn.ldap.nextMessageID;
|
message.messageID = conn.ldap.nextMessageID;
|
||||||
|
@ -784,8 +801,7 @@ Client.prototype._send = function(message, expect, callback, connection) {
|
||||||
try {
|
try {
|
||||||
return conn.write(message.toBer(), _writeCb);
|
return conn.write(message.toBer(), _writeCb);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
conn.end();
|
return closeConn(e);
|
||||||
return closedConn();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,36 @@ var ldap = require('../lib/index');
|
||||||
///--- Globals
|
///--- Globals
|
||||||
|
|
||||||
var SOCKET = '/tmp/.' + uuid();
|
var SOCKET = '/tmp/.' + uuid();
|
||||||
|
var SUFFIX = 'dc=' + uuid();
|
||||||
|
|
||||||
var client;
|
var client;
|
||||||
var server;
|
var server;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///--- Helper
|
||||||
|
|
||||||
|
function search(t, options, callback) {
|
||||||
|
client.search(SUFFIX, options, function(err, res) {
|
||||||
|
t.ifError(err);
|
||||||
|
t.ok(res);
|
||||||
|
var found = false;
|
||||||
|
res.on('searchEntry', function(entry) {
|
||||||
|
t.ok(entry);
|
||||||
|
found = true;
|
||||||
|
});
|
||||||
|
res.on('end', function() {
|
||||||
|
t.ok(found);
|
||||||
|
if (callback)
|
||||||
|
return callback();
|
||||||
|
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///--- Tests
|
///--- Tests
|
||||||
|
|
||||||
test('setup', function(t) {
|
test('setup', function(t) {
|
||||||
|
@ -24,32 +49,30 @@ test('setup', function(t) {
|
||||||
socketPath: SOCKET
|
socketPath: SOCKET
|
||||||
});
|
});
|
||||||
t.ok(client);
|
t.ok(client);
|
||||||
// client.log4js.setLevel('Debug');
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.search(SUFFIX, function(req, res, next) {
|
||||||
|
var entry = {
|
||||||
|
dn: 'cn=foo, ' + SUFFIX,
|
||||||
|
attributes: {
|
||||||
|
objectclass: ['person', 'top'],
|
||||||
|
cn: 'Pogo Stick',
|
||||||
|
sn: 'Stick',
|
||||||
|
givenname: 'ogo',
|
||||||
|
mail: uuid() + '@pogostick.org'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req.filter.matches(entry.attributes))
|
||||||
|
res.send(entry);
|
||||||
|
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('Evolution search filter (GH-3)', function(t) {
|
test('Evolution search filter (GH-3)', function(t) {
|
||||||
var suffix = 'dc=' + uuid();
|
|
||||||
var entry = {
|
|
||||||
dn: 'cn=foo, ' + suffix,
|
|
||||||
attributes: {
|
|
||||||
objectclass: ['person', 'top'],
|
|
||||||
cn: 'Pogo Stick',
|
|
||||||
sn: 'Stick',
|
|
||||||
givenname: 'ogo',
|
|
||||||
mail: uuid() + '@pogostick.org'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
server.search(suffix, function(req, res, next) {
|
|
||||||
console.log(req.filter.filters[0].type);
|
|
||||||
if (req.filter.matches(entry.attributes))
|
|
||||||
res.send(entry);
|
|
||||||
res.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
// This is what Evolution sends, when searching for a contact 'ogo'. Wow.
|
// This is what Evolution sends, when searching for a contact 'ogo'. Wow.
|
||||||
var filter =
|
var filter =
|
||||||
'(|(cn=ogo*)(givenname=ogo*)(sn=ogo*)(mail=ogo*)(member=ogo*)' +
|
'(|(cn=ogo*)(givenname=ogo*)(sn=ogo*)(mail=ogo*)(member=ogo*)' +
|
||||||
|
@ -69,19 +92,17 @@ test('Evolution search filter (GH-3)', function(t) {
|
||||||
'(anniversary=ogo*)(birthdate=ogo*)(mailer=ogo*)(fileas=ogo*)' +
|
'(anniversary=ogo*)(birthdate=ogo*)(mailer=ogo*)(fileas=ogo*)' +
|
||||||
'(category=ogo*)(calcaluri=ogo*)(calfburl=ogo*)(icscalendar=ogo*))';
|
'(category=ogo*)(calcaluri=ogo*)(calfburl=ogo*)(icscalendar=ogo*))';
|
||||||
|
|
||||||
client.search(suffix, filter, function(err, res) {
|
return search(t, filter);
|
||||||
t.ifError(err);
|
});
|
||||||
t.ok(res);
|
|
||||||
var found = false;
|
|
||||||
res.on('searchEntry', function(entry) {
|
test('GH-49 Client errors on bad attributes', function(t) {
|
||||||
t.ok(entry);
|
var searchOpts = {
|
||||||
found = true;
|
filter: 'cn=*ogo*',
|
||||||
});
|
scope: 'one',
|
||||||
res.on('end', function() {
|
attributes: 'dn'
|
||||||
t.ok(found);
|
};
|
||||||
t.end();
|
return search(t, searchOpts);
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue