diff --git a/lib/controls/index.js b/lib/controls/index.js index d2d7f23..4157d5f 100644 --- a/lib/controls/index.js +++ b/lib/controls/index.js @@ -7,6 +7,7 @@ var EntryChangeNotificationControl = require('./entry_change_notification_control'); var PersistentSearchControl = require('./persistent_search_control'); var PagedResultsControl = require('./paged_results_control'); +var ServerSideSortingControl = require('./server_side_sorting_control.js'); @@ -57,6 +58,12 @@ module.exports = { value: value }); break; + case ServerSideSortingControl.OID: + control = new ServerSideSortingControl({ + critical: critical, + value: value + }); + break; default: control = new Control({ type: type, @@ -72,5 +79,6 @@ module.exports = { Control: Control, EntryChangeNotificationControl: EntryChangeNotificationControl, PagedResultsControl: PagedResultsControl, - PersistentSearchControl: PersistentSearchControl + PersistentSearchControl: PersistentSearchControl, + ServerSideSortingControl: ServerSideSortingControl }; diff --git a/lib/controls/server_side_sorting_control.js b/lib/controls/server_side_sorting_control.js new file mode 100644 index 0000000..995a369 --- /dev/null +++ b/lib/controls/server_side_sorting_control.js @@ -0,0 +1,117 @@ +var assert = require('assert'); +var util = require('util'); + +var asn1 = require('asn1'); + +var Control = require('./control'); + + + +///--- Globals + +var BerReader = asn1.BerReader; +var BerWriter = asn1.BerWriter; + + + +///--- API + +function ServerSideSortingControl(options) { + if (!options) + options = {}; + + options.type = ServerSideSortingControl.OID; + if (options.value) { + if (Buffer.isBuffer(options.value)) { + this.parse(options.value); + } else if (Array.isArray(options.value)) { + for (var i = 0; i < options.value.length; i++) { + if (!typeof (options.value[i]) === 'object') { + throw new TypeError('Elements of options.value must be Objects'); + } else if (!options.value[i].hasOwnProperty('attributeType')) { + throw new Error('Missing required key: attributeType'); + } + } + this._value = options.value; + } else if (typeof (options.value) === 'object') { + if (!options.value.hasOwnProperty('attributeType')) { + throw new Error('Missing required key: attributeType'); + } + this._value = options.value; + } else { + throw new TypeError('options.value must be a Buffer, Array or Object'); + } + options.value = null; + } + Control.call(this, options); + + var self = this; + this.__defineGetter__('value', function () { + return self._value || {}; + }); +} +util.inherits(ServerSideSortingControl, Control); +module.exports = ServerSideSortingControl; + + +ServerSideSortingControl.prototype.parse = function parse(buffer) { + assert.ok(buffer); + + var ber = new BerReader(buffer); + if (ber.readSequence()) { + this._value = {}; + this._value.sortResult = ber.readInt(); + this._value.attributeType = ber.readString(asn1.Ber.OctetString, true); + //readString returns '' instead of a zero-length buffer + if (!this._value.attributeType) + this._value.attributeType = new Buffer(0); + + return true; + } + + return false; +}; + + +ServerSideSortingControl.prototype._toBer = function (ber) { + assert.ok(ber); + + if (!this._value) + return; + + var writer = new BerWriter(); + writer.startSequence(0x30); + + if (Array.isArray(this.value)) { + for (var i = 0; i < this.value.length; i++) { + this._sortKeyListItemToBer(writer, this.value[i]); + } + } else if (typeof (this.value) === 'object') { + this._sortKeyListItemToBer(writer, this.value); + } + + writer.endSequence(); + ber.writeBuffer(writer.buffer, 0x04); +}; + + +ServerSideSortingControl.prototype._json = function (obj) { + obj.controlValue = this.value; + return obj; +}; + +ServerSideSortingControl.prototype._sortKeyListItemToBer = function(writer, obj) { + writer.startSequence(0x30); + if (obj.attributeType) { + writer.writeString(obj.attributeType, asn1.Ber.OctetString); + } + if (obj.orderingRule) { + writer.writeString(obj.orderingRule, 0x80); + } + if (obj.reverseOrder) { + writer.writeBoolean(obj.reverseOrder, 0x81); + } + writer.endSequence(); +}; + +ServerSideSortingControl.OID = '1.2.840.113556.1.4.473';