diff --git a/lib/change.js b/lib/change.js index 23caaa3..b765e35 100644 --- a/lib/change.js +++ b/lib/change.js @@ -55,7 +55,11 @@ function Change(options) { self._modification = attr; return; } - Object.keys(attr).forEach(function(k) { + var keys = Object.keys(attr); + if (keys.length > 1) + throw new Error('Only one attribute per Change allowed'); + + keys.forEach(function(k) { var _attr = new Attribute({type: k}); if (Array.isArray(attr[k])) { attr[k].forEach(function(v) { diff --git a/lib/client.js b/lib/client.js index 68ba548..0bc370c 100644 --- a/lib/client.js +++ b/lib/client.js @@ -435,17 +435,41 @@ Client.prototype.exop = function(name, value, controls, callback) { Client.prototype.modify = function(name, change, controls, callback) { if (typeof(name) !== 'string') throw new TypeError('name (string) required'); - if (!Array.isArray(change) && !(change instanceof Change)) + if (typeof(change) !== 'object') throw new TypeError('change (Change) required'); - if (!Array.isArray(change)) { - var save = change; - change = []; - change.push(save); + + var changes = []; + + function changeFromObject(change) { + if (!change.operation && !change.type) + throw new Error('change.operation required'); + if (typeof(change.modification) !== 'object') + throw new Error('change.modification (object) required'); + + Object.keys(change.modification).forEach(function(k) { + var mod = {}; + mod[k] = change.modification[k]; + changes.push(new Change({ + operation: change.operation || change.type, + modification: mod + })); + }); } - change.forEach(function(c) { - if (!(c instanceof Change)) - throw new TypeError('change ([Change]) required'); - }); + + if (change instanceof Change) { + changes.push(change); + } else if (Array.isArray(change)) { + change.forEach(function(c) { + if (c instanceof Change) { + changes.push(c); + } else { + changeFromObject(c); + } + }); + } else { + changeFromObject(change); + } + if (typeof(controls) === 'function') { callback = controls; controls = []; @@ -457,7 +481,7 @@ Client.prototype.modify = function(name, change, controls, callback) { var req = new ModifyRequest({ object: dn.parse(name), - changes: change, + changes: changes, controls: controls }); diff --git a/tst/change.test.js b/tst/change.test.js index 144339c..83af510 100644 --- a/tst/change.test.js +++ b/tst/change.test.js @@ -50,6 +50,23 @@ test('new with args', function(t) { }); +test('GH-31 (multiple attributes per Change)', function(t) { + try { + var change = new Change({ + operation: 'replace', + modification: { + cn: 'foo', + sn: 'bar' + } + }); + t.fail('should have thrown'); + } catch (e) { + t.ok(e); + t.end(); + } +}); + + test('toBer', function(t) { var change = new Change({ operation: 'Add', diff --git a/tst/client.test.js b/tst/client.test.js index 38ee284..164f9c9 100644 --- a/tst/client.test.js +++ b/tst/client.test.js @@ -324,6 +324,23 @@ test('modify array success', function(t) { }); +test('modify change plain object success (GH-31)', function(t) { + var change = { + type: 'replace', + modification: { + cn: 'test', + sn: 'bar' + } + }; + client.modify('cn=modify, ' + SUFFIX, change, function(err, res) { + t.ifError(err); + t.ok(res); + t.equal(res.status, 0); + t.end(); + }); +}); + + test('modify DN new RDN only', function(t) { client.modifyDN('cn=old, ' + SUFFIX, 'cn=new', function(err, res) { t.ifError(err);