lots of fixes. committing the last few days of work. (my commit messages are useless right now)
This commit is contained in:
parent
add3e1a0d6
commit
dda17ef190
|
@ -22,10 +22,11 @@ function Change(options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.__defineGetter__('operation', function() {
|
this.__defineGetter__('operation', function() {
|
||||||
switch (self._operation) {
|
switch (self._operation) {
|
||||||
case 0x00: return 'Add';
|
case 0x00: return 'add';
|
||||||
case 0x01: return 'Delete';
|
case 0x01: return 'delete';
|
||||||
case 0x02: return 'Replace';
|
case 0x02: return 'replace';
|
||||||
default: return 'Invalid';
|
default:
|
||||||
|
throw new Error('0x' + self._operation.toString(16) + ' is invalid');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.__defineSetter__('operation', function(val) {
|
this.__defineSetter__('operation', function(val) {
|
||||||
|
|
|
@ -593,8 +593,14 @@ Client.prototype.search = function(base, options, controls, callback) {
|
||||||
} else if (typeof(options) !== 'object') {
|
} else if (typeof(options) !== 'object') {
|
||||||
throw new TypeError('options (object) required');
|
throw new TypeError('options (object) required');
|
||||||
}
|
}
|
||||||
if (!(options.filter instanceof Filter))
|
if (typeof(options.filter) === 'string') {
|
||||||
|
options.filter = filters.parseString(options.filter);
|
||||||
|
} else if (!options.filter) {
|
||||||
|
options.filter = new PresenceFilter({attribute: 'objectclass'});
|
||||||
|
} else if (!(options.filter instanceof Filter)) {
|
||||||
throw new TypeError('options.filter (Filter) required');
|
throw new TypeError('options.filter (Filter) required');
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(controls) === 'function') {
|
if (typeof(controls) === 'function') {
|
||||||
callback = controls;
|
callback = controls;
|
||||||
controls = [];
|
controls = [];
|
||||||
|
|
|
@ -78,7 +78,7 @@ SubstringFilter.prototype.matches = function(target) {
|
||||||
return matcher.test(target[this.attribute]);
|
return matcher.test(target[this.attribute]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ AddRequest.prototype.indexOf = function(attr) {
|
||||||
throw new TypeError('attr (string) required');
|
throw new TypeError('attr (string) required');
|
||||||
|
|
||||||
for (var i = 0; i < this.attributes.length; i++)
|
for (var i = 0; i < this.attributes.length; i++)
|
||||||
if (req.attributes[i].type === attr)
|
if (this.attributes[i].type === attr)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -133,3 +133,51 @@ AddRequest.prototype.getAttribute = function(name) {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
AddRequest.prototype.addAttribute = function(attr) {
|
||||||
|
if (!(attr instanceof Attribute))
|
||||||
|
throw new TypeEroror('attribute (Attribute) required');
|
||||||
|
|
||||||
|
return this.attributes.push(attr);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a "pure" JS representation of this object.
|
||||||
|
*
|
||||||
|
* An example object would look like:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* "dn": "cn=unit, dc=test",
|
||||||
|
* "attributes": {
|
||||||
|
* "cn": ["unit", "foo"],
|
||||||
|
* "objectclass": ["top", "person"]
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @return {Object} that looks like the above.
|
||||||
|
*/
|
||||||
|
AddRequest.prototype.toObject = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
dn: self.entry ? self.entry.toString() : '',
|
||||||
|
attributes: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!this.attributes || !this.attributes.length)
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
this.attributes.forEach(function(a) {
|
||||||
|
if (!obj.attributes[a.type])
|
||||||
|
obj.attributes[a.type] = [];
|
||||||
|
|
||||||
|
a.vals.forEach(function(v) {
|
||||||
|
if (obj.attributes[a.type].indexOf(v) === -1)
|
||||||
|
obj.attributes[a.type].push(v);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
|
@ -16,8 +16,8 @@ var Protocol = require('../protocol');
|
||||||
|
|
||||||
var Ber = asn1.Ber;
|
var Ber = asn1.Ber;
|
||||||
|
|
||||||
var LDAP_BIND_SIMPLE = 'Simple';
|
var LDAP_BIND_SIMPLE = 'simple';
|
||||||
var LDAP_BIND_SASL = 'Sasl';
|
var LDAP_BIND_SASL = 'sasl';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ CompareRequest.prototype._parse = function(ber) {
|
||||||
this.entry = dn.parse(ber.readString());
|
this.entry = dn.parse(ber.readString());
|
||||||
|
|
||||||
ber.readSequence();
|
ber.readSequence();
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -37,9 +37,7 @@ function DeleteRequest(options) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.__defineGetter__('type', function() { return 'DeleteRequest'; });
|
this.__defineGetter__('type', function() { return 'DeleteRequest'; });
|
||||||
this.__defineGetter__('_dn', function() {
|
this.__defineGetter__('_dn', function() { return self.entry; });
|
||||||
return self.entry ? self.entry.toString() : '';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
util.inherits(DeleteRequest, LDAPMessage);
|
util.inherits(DeleteRequest, LDAPMessage);
|
||||||
module.exports = DeleteRequest;
|
module.exports = DeleteRequest;
|
||||||
|
@ -48,11 +46,8 @@ module.exports = DeleteRequest;
|
||||||
DeleteRequest.prototype._parse = function(ber, length) {
|
DeleteRequest.prototype._parse = function(ber, length) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
// What a hack; LDAP is so annoying with its decisions of what to
|
this.entry = dn.parse(ber.buffer.slice(0, length).toString('utf8'));
|
||||||
// shortcut, so this is totally a hack to work around the way the delete
|
ber._offset += ber.length;
|
||||||
// message is structured
|
|
||||||
this.entry = dn.parse(ber.buffer.slice(0, length).toString());
|
|
||||||
ber._offset += length;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,9 +40,7 @@ function ModifyRequest(options) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.__defineGetter__('type', function() { return 'ModifyRequest'; });
|
this.__defineGetter__('type', function() { return 'ModifyRequest'; });
|
||||||
this.__defineGetter__('_dn', function() {
|
this.__defineGetter__('_dn', function() { return self.object; });
|
||||||
return self.object ? self.object.toString() : '';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
util.inherits(ModifyRequest, LDAPMessage);
|
util.inherits(ModifyRequest, LDAPMessage);
|
||||||
module.exports = ModifyRequest;
|
module.exports = ModifyRequest;
|
||||||
|
|
|
@ -63,6 +63,38 @@ SearchEntry.prototype.addAttribute = function(attr) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SearchEntry.prototype.fromObject = function(obj) {
|
||||||
|
if (typeof(obj) !== 'object')
|
||||||
|
throw new TypeError('object required');
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (obj.attributes)
|
||||||
|
obj = obj.attributes;
|
||||||
|
this.attributes = [];
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(function(k) {
|
||||||
|
var attr = new Attribute({type: k, vals: []});
|
||||||
|
|
||||||
|
if (Array.isArray(obj[k])) {
|
||||||
|
obj[k].forEach(function(v) {
|
||||||
|
if (typeof(v) !== 'string')
|
||||||
|
throw new TypeError(k + ' -> ' + v + ' is not a string');
|
||||||
|
attr.vals.push(v);
|
||||||
|
});
|
||||||
|
} else if (typeof(obj[k]) === 'string') {
|
||||||
|
attr.vals.push(obj[k]);
|
||||||
|
} else {
|
||||||
|
throw new TypeError(k + ' -> ' + obj[k] + ' is not a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
self.attributes.push(attr);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
SearchEntry.prototype.setAttributes = function(obj) {
|
SearchEntry.prototype.setAttributes = function(obj) {
|
||||||
if (typeof(obj) !== 'object')
|
if (typeof(obj) !== 'object')
|
||||||
throw new TypeError('object required');
|
throw new TypeError('object required');
|
||||||
|
|
|
@ -6,6 +6,7 @@ var util = require('util');
|
||||||
var LDAPResult = require('./result');
|
var LDAPResult = require('./result');
|
||||||
var SearchEntry = require('./search_entry');
|
var SearchEntry = require('./search_entry');
|
||||||
|
|
||||||
|
var parseDN = require('../dn').parse;
|
||||||
var Protocol = require('../protocol');
|
var Protocol = require('../protocol');
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +21,9 @@ function SearchResponse(options) {
|
||||||
|
|
||||||
options.protocolOp = Protocol.LDAP_REP_SEARCH;
|
options.protocolOp = Protocol.LDAP_REP_SEARCH;
|
||||||
LDAPResult.call(this, options);
|
LDAPResult.call(this, options);
|
||||||
|
|
||||||
|
this.attributes = options.attributes ? options.attributes.slice() : [];
|
||||||
|
this.notAttributes = [];
|
||||||
}
|
}
|
||||||
util.inherits(SearchResponse, LDAPResult);
|
util.inherits(SearchResponse, LDAPResult);
|
||||||
module.exports = SearchResponse;
|
module.exports = SearchResponse;
|
||||||
|
@ -31,30 +35,67 @@ module.exports = SearchResponse;
|
||||||
* @param {Object} entry an instance of SearchEntry.
|
* @param {Object} entry an instance of SearchEntry.
|
||||||
*/
|
*/
|
||||||
SearchResponse.prototype.send = function(entry) {
|
SearchResponse.prototype.send = function(entry) {
|
||||||
if (!entry || !(entry instanceof SearchEntry))
|
if (!entry || typeof(entry) !== 'object')
|
||||||
throw new TypeError('entry (SearchEntry) required');
|
throw new TypeError('entry (SearchEntry) required');
|
||||||
if (entry.messageID !== this.messageID)
|
|
||||||
throw new Error('SearchEntry messageID mismatch');
|
|
||||||
|
|
||||||
assert.ok(this.connection);
|
var self = this;
|
||||||
|
|
||||||
if (this.log.isDebugEnabled())
|
if (!(entry instanceof SearchEntry)) {
|
||||||
this.log.debug('%s: sending: %j', this.connection.ldap.id, entry.json);
|
if (!entry.dn)
|
||||||
|
throw new Error('entry.dn required');
|
||||||
|
if (!entry.attributes)
|
||||||
|
throw new Error('entry.attributes required');
|
||||||
|
|
||||||
this.connection.write(entry.toBer());
|
var save = entry;
|
||||||
};
|
|
||||||
|
|
||||||
|
// Rip out anything that either the client didn't ask for, the server
|
||||||
|
// wants to strip, or 'private' vars that are prefixed with '_'
|
||||||
|
Object.keys(entry.attributes).forEach(function(a) {
|
||||||
|
if ((self.attributes.length && self.attributes.indexOf(a) === -1) ||
|
||||||
|
(self.notAttributes.length && self.notAttributes.indexOf(a) !== -1) ||
|
||||||
|
(a.length && a.charAt(0) === '_')) {
|
||||||
|
delete entry.attributes[a];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
SearchResponse.prototype.createSearchEntry = function(options) {
|
entry = new SearchEntry({
|
||||||
if (options) {
|
objectName: typeof(save.dn) === 'string' ? parseDN(save.dn) : save.dn,
|
||||||
if (typeof(options) !== 'object')
|
messageID: self.messageID,
|
||||||
throw new TypeError('options must be an object');
|
log4js: self.log4js
|
||||||
|
});
|
||||||
|
entry.fromObject(save);
|
||||||
} else {
|
} else {
|
||||||
options = {};
|
if (!entry.messageID)
|
||||||
|
entry.messageID = this.messageID;
|
||||||
|
if (entry.messageID !== this.messageID)
|
||||||
|
throw new Error('SearchEntry messageID mismatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.messageID = this.messageID;
|
try {
|
||||||
options.log4js = this.log4js;
|
if (this.log.isDebugEnabled())
|
||||||
|
this.log.debug('%s: sending: %j', this.connection.ldap.id, entry.json);
|
||||||
|
|
||||||
|
this.connection.write(entry.toBer());
|
||||||
|
} catch (e) {
|
||||||
|
this.log.warn('%s failure to write message %j: %s',
|
||||||
|
this.connection.ldap.id, this.json, e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
return new SearchEntry(options);
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SearchResponse.prototype.createSearchEntry = function(object) {
|
||||||
|
if (!object || typeof(object) !== 'object')
|
||||||
|
throw new TypeError('object required');
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var entry = new SearchEntry({
|
||||||
|
messageID: self.messageID,
|
||||||
|
log4js: self.log4js,
|
||||||
|
objectName: object.objectName || object.dn
|
||||||
|
});
|
||||||
|
entry.fromObject((object.attributes || object));
|
||||||
|
|
||||||
|
return entry;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,7 @@ var DeleteResponse = require('./messages/del_response');
|
||||||
var ExtendedResponse = require('./messages/ext_response');
|
var ExtendedResponse = require('./messages/ext_response');
|
||||||
var ModifyResponse = require('./messages/modify_response');
|
var ModifyResponse = require('./messages/modify_response');
|
||||||
var ModifyDNResponse = require('./messages/moddn_response');
|
var ModifyDNResponse = require('./messages/moddn_response');
|
||||||
|
var SearchRequest = require('./messages/search_request');
|
||||||
var SearchResponse = require('./messages/search_response');
|
var SearchResponse = require('./messages/search_response');
|
||||||
var UnbindResponse = require('./messages/unbind_response');
|
var UnbindResponse = require('./messages/unbind_response');
|
||||||
|
|
||||||
|
@ -108,7 +109,8 @@ function getResponse(req) {
|
||||||
|
|
||||||
var res = new Response({
|
var res = new Response({
|
||||||
messageID: req.messageID,
|
messageID: req.messageID,
|
||||||
log4js: req.log4js
|
log4js: req.log4js,
|
||||||
|
attributes: ((req instanceof SearchRequest) ? req.attributes : undefined)
|
||||||
});
|
});
|
||||||
res.connection = req.connection;
|
res.connection = req.connection;
|
||||||
res.logId = req.logId;
|
res.logId = req.logId;
|
||||||
|
@ -203,11 +205,17 @@ function Server(options) {
|
||||||
|
|
||||||
EventEmitter.call(this, options);
|
EventEmitter.call(this, options);
|
||||||
|
|
||||||
var log = this.log = options.log4js.getLogger('LDAPServer');
|
this.log = options.log4js.getLogger('LDAPServer');
|
||||||
|
var log = this.log;
|
||||||
|
|
||||||
function setupConnection(c) {
|
function setupConnection(c) {
|
||||||
assert.ok(c);
|
assert.ok(c);
|
||||||
|
|
||||||
|
if (c.type === 'unix') {
|
||||||
|
c.remoteAddress = self.server.path;
|
||||||
|
c.remotePort = c.fd;
|
||||||
|
}
|
||||||
|
|
||||||
c.ldap = {
|
c.ldap = {
|
||||||
id: c.remoteAddress + ':' + c.remotePort,
|
id: c.remoteAddress + ':' + c.remotePort,
|
||||||
config: options
|
config: options
|
||||||
|
@ -242,11 +250,6 @@ function Server(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function newConnection(c) {
|
function newConnection(c) {
|
||||||
if (c.type === 'unix') {
|
|
||||||
c.remoteAddress = self.server.path;
|
|
||||||
c.remotePort = c.fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
setupConnection(c);
|
setupConnection(c);
|
||||||
if (log.isTraceEnabled())
|
if (log.isTraceEnabled())
|
||||||
log.trace('new connection from %s', c.ldap.id);
|
log.trace('new connection from %s', c.ldap.id);
|
||||||
|
@ -256,7 +259,7 @@ function Server(options) {
|
||||||
});
|
});
|
||||||
c.parser.on('message', function(req) {
|
c.parser.on('message', function(req) {
|
||||||
req.connection = c;
|
req.connection = c;
|
||||||
req.logId = c.remoteAddress + '::' + req.messageID;
|
req.logId = c.ldap.id + '::' + req.messageID;
|
||||||
|
|
||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
log.debug('%s: message received: req=%j', c.ldap.id, req.json);
|
log.debug('%s: message received: req=%j', c.ldap.id, req.json);
|
||||||
|
@ -713,11 +716,17 @@ Server.prototype._getHandlerChain = function(req) {
|
||||||
handlers: route[op] || [defaultExopHandler]
|
handlers: route[op] || [defaultExopHandler]
|
||||||
};
|
};
|
||||||
} else if (req.protocolOp === Protocol.LDAP_REQ_UNBIND) {
|
} else if (req.protocolOp === Protocol.LDAP_REQ_UNBIND) {
|
||||||
|
function getUnbindChain() {
|
||||||
|
if (routes['unbind'] && routes['unbind'][op])
|
||||||
|
return routes['unbind'][op];
|
||||||
|
|
||||||
|
self.log.debug('%s unbind request %j', req.logId, req.json);
|
||||||
|
return [defaultUnbindHandler];
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
backend: routes['unbind'] ? routes['unbind'].backend : self,
|
backend: routes['unbind'] ? routes['unbind'].backend : self,
|
||||||
handlers: (routes['unbind'] && routes['unbind'][op] ?
|
handlers: getUnbindChain()
|
||||||
routes['unbind'][op] :
|
|
||||||
[defaultUnbindHandler])
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ test('new with args', function(t) {
|
||||||
});
|
});
|
||||||
t.ok(change);
|
t.ok(change);
|
||||||
|
|
||||||
t.equal(change.operation, 'Add');
|
t.equal(change.operation, 'add');
|
||||||
t.equal(change.modification.type, 'cn');
|
t.equal(change.modification.type, 'cn');
|
||||||
t.equal(change.modification.vals.length, 2);
|
t.equal(change.modification.vals.length, 2);
|
||||||
t.equal(change.modification.vals[0], 'foo');
|
t.equal(change.modification.vals[0], 'foo');
|
||||||
|
@ -90,7 +90,7 @@ test('parse', function(t) {
|
||||||
t.ok(change);
|
t.ok(change);
|
||||||
t.ok(change.parse(new BerReader(ber.buffer)));
|
t.ok(change.parse(new BerReader(ber.buffer)));
|
||||||
|
|
||||||
t.equal(change.operation, 'Add');
|
t.equal(change.operation, 'add');
|
||||||
t.equal(change.modification.type, 'cn');
|
t.equal(change.modification.type, 'cn');
|
||||||
t.equal(change.modification.vals.length, 2);
|
t.equal(change.modification.vals.length, 2);
|
||||||
t.equal(change.modification.vals[0], 'foo');
|
t.equal(change.modification.vals[0], 'foo');
|
||||||
|
|
|
@ -113,3 +113,32 @@ test('toBer', function(t) {
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('toObject', function(t) {
|
||||||
|
var req = new AddRequest({
|
||||||
|
entry: dn.parse('cn=foo, o=test'),
|
||||||
|
attributes: [new Attribute({type: 'cn', vals: ['foo', 'bar']}),
|
||||||
|
new Attribute({type: 'objectclass', vals: ['person']})]
|
||||||
|
});
|
||||||
|
|
||||||
|
t.ok(req);
|
||||||
|
|
||||||
|
var obj = req.toObject();
|
||||||
|
t.ok(obj);
|
||||||
|
|
||||||
|
t.ok(obj.dn);
|
||||||
|
t.equal(obj.dn, 'cn=foo, o=test');
|
||||||
|
t.ok(obj.attributes);
|
||||||
|
t.ok(obj.attributes.cn);
|
||||||
|
t.ok(Array.isArray(obj.attributes.cn));
|
||||||
|
t.equal(obj.attributes.cn.length, 2);
|
||||||
|
t.equal(obj.attributes.cn[0], 'foo');
|
||||||
|
t.equal(obj.attributes.cn[1], 'bar');
|
||||||
|
t.ok(obj.attributes.objectclass);
|
||||||
|
t.ok(Array.isArray(obj.attributes.objectclass));
|
||||||
|
t.equal(obj.attributes.objectclass.length, 1);
|
||||||
|
t.equal(obj.attributes.objectclass[0], 'person');
|
||||||
|
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
|
@ -34,7 +34,7 @@ test('new with args', function(t) {
|
||||||
entry: dn.parse('cn=test')
|
entry: dn.parse('cn=test')
|
||||||
});
|
});
|
||||||
t.ok(req);
|
t.ok(req);
|
||||||
t.equal(req.dn, 'cn=test');
|
t.equal(req.dn.toString(), 'cn=test');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ test('parse', function(t) {
|
||||||
var reader = new BerReader(ber.buffer);
|
var reader = new BerReader(ber.buffer);
|
||||||
reader.readSequence(0x4a);
|
reader.readSequence(0x4a);
|
||||||
t.ok(req.parse(reader.buffer, reader.length));
|
t.ok(req.parse(reader.buffer, reader.length));
|
||||||
t.equal(req.dn, 'cn=test');
|
t.equal(req.dn.toString(), 'cn=test');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ test('new with args', function(t) {
|
||||||
t.ok(req);
|
t.ok(req);
|
||||||
t.equal(req.dn.toString(), 'cn=foo, o=test');
|
t.equal(req.dn.toString(), 'cn=foo, o=test');
|
||||||
t.equal(req.changes.length, 1);
|
t.equal(req.changes.length, 1);
|
||||||
t.equal(req.changes[0].operation, 'Replace');
|
t.equal(req.changes[0].operation, 'replace');
|
||||||
t.equal(req.changes[0].modification.type, 'objectclass');
|
t.equal(req.changes[0].modification.type, 'objectclass');
|
||||||
t.equal(req.changes[0].modification.vals[0], 'person');
|
t.equal(req.changes[0].modification.vals[0], 'person');
|
||||||
t.end();
|
t.end();
|
||||||
|
@ -74,9 +74,9 @@ test('parse', function(t) {
|
||||||
|
|
||||||
var req = new ModifyRequest();
|
var req = new ModifyRequest();
|
||||||
t.ok(req._parse(new BerReader(ber.buffer)));
|
t.ok(req._parse(new BerReader(ber.buffer)));
|
||||||
t.equal(req.dn, 'cn=foo, o=test');
|
t.equal(req.dn.toString(), 'cn=foo, o=test');
|
||||||
t.equal(req.changes.length, 1);
|
t.equal(req.changes.length, 1);
|
||||||
t.equal(req.changes[0].operation, 'Replace');
|
t.equal(req.changes[0].operation, 'replace');
|
||||||
t.equal(req.changes[0].modification.type, 'objectclass');
|
t.equal(req.changes[0].modification.type, 'objectclass');
|
||||||
t.equal(req.changes[0].modification.vals[0], 'person');
|
t.equal(req.changes[0].modification.vals[0], 'person');
|
||||||
t.end();
|
t.end();
|
||||||
|
|
Loading…
Reference in New Issue