UNPKG

4.45 kBJavaScriptView Raw
1// Copyright 2011 Mark Cavage, Inc. All rights reserved.
2
3const assert = require('assert-plus')
4const util = require('util')
5
6// var asn1 = require('asn1')
7
8const LDAPMessage = require('./message')
9const Attribute = require('../attribute')
10const Protocol = require('../protocol')
11const lassert = require('../assert')
12
13/// --- Globals
14
15// var BerWriter = asn1.BerWriter
16
17/// --- API
18
19function SearchEntry (options) {
20 options = options || {}
21 assert.object(options)
22 lassert.optionalStringDN(options.objectName)
23
24 options.protocolOp = Protocol.LDAP_REP_SEARCH_ENTRY
25 LDAPMessage.call(this, options)
26
27 this.objectName = options.objectName || null
28 this.setAttributes(options.attributes || [])
29}
30util.inherits(SearchEntry, LDAPMessage)
31Object.defineProperties(SearchEntry.prototype, {
32 type: {
33 get: function getType () { return 'SearchEntry' },
34 configurable: false
35 },
36 _dn: {
37 get: function getDN () { return this.objectName },
38 configurable: false
39 },
40 object: {
41 get: function getObject () {
42 const obj = {
43 dn: this.dn.toString(),
44 controls: []
45 }
46 this.attributes.forEach(function (a) {
47 if (a.vals && a.vals.length) {
48 if (a.vals.length > 1) {
49 obj[a.type] = a.vals.slice()
50 } else {
51 obj[a.type] = a.vals[0]
52 }
53 } else {
54 obj[a.type] = []
55 }
56 })
57 this.controls.forEach(function (element, index, array) {
58 obj.controls.push(element.json)
59 })
60 return obj
61 },
62 configurable: false
63 },
64 raw: {
65 get: function getRaw () {
66 const obj = {
67 dn: this.dn.toString(),
68 controls: []
69 }
70
71 this.attributes.forEach(function (a) {
72 if (a.buffers && a.buffers.length) {
73 if (a.buffers.length > 1) {
74 obj[a.type] = a.buffers.slice()
75 } else {
76 obj[a.type] = a.buffers[0]
77 }
78 } else {
79 obj[a.type] = []
80 }
81 })
82 this.controls.forEach(function (element, index, array) {
83 obj.controls.push(element.json)
84 })
85 return obj
86 },
87 configurable: false
88 }
89})
90
91SearchEntry.prototype.addAttribute = function (attr) {
92 if (!attr || typeof (attr) !== 'object') { throw new TypeError('attr (attribute) required') }
93
94 this.attributes.push(attr)
95}
96
97SearchEntry.prototype.toObject = function () {
98 return this.object
99}
100
101SearchEntry.prototype.fromObject = function (obj) {
102 if (typeof (obj) !== 'object') { throw new TypeError('object required') }
103
104 const self = this
105 if (obj.controls) { this.controls = obj.controls }
106
107 if (obj.attributes) { obj = obj.attributes }
108 this.attributes = []
109
110 Object.keys(obj).forEach(function (k) {
111 self.attributes.push(new Attribute({ type: k, vals: obj[k] }))
112 })
113
114 return true
115}
116
117SearchEntry.prototype.setAttributes = function (obj) {
118 if (typeof (obj) !== 'object') { throw new TypeError('object required') }
119
120 if (Array.isArray(obj)) {
121 obj.forEach(function (a) {
122 if (!Attribute.isAttribute(a)) { throw new TypeError('entry must be an Array of Attributes') }
123 })
124 this.attributes = obj
125 } else {
126 const self = this
127
128 self.attributes = []
129 Object.keys(obj).forEach(function (k) {
130 const attr = new Attribute({ type: k })
131 if (Array.isArray(obj[k])) {
132 obj[k].forEach(function (v) {
133 attr.addValue(v.toString())
134 })
135 } else {
136 attr.addValue(obj[k].toString())
137 }
138 self.attributes.push(attr)
139 })
140 }
141}
142
143SearchEntry.prototype._json = function (j) {
144 assert.ok(j)
145
146 j.objectName = this.objectName.toString()
147 j.attributes = []
148 this.attributes.forEach(function (a) {
149 j.attributes.push(a.json || a)
150 })
151
152 return j
153}
154
155SearchEntry.prototype._parse = function (ber) {
156 assert.ok(ber)
157
158 this.objectName = ber.readString()
159 assert.ok(ber.readSequence())
160
161 const end = ber.offset + ber.length
162 while (ber.offset < end) {
163 const a = new Attribute()
164 a.parse(ber)
165 this.attributes.push(a)
166 }
167
168 return true
169}
170
171SearchEntry.prototype._toBer = function (ber) {
172 assert.ok(ber)
173
174 const formattedObjectName = this.objectName.format({ skipSpace: true })
175 ber.writeString(formattedObjectName)
176 ber.startSequence()
177 this.attributes.forEach(function (a) {
178 // This may or may not be an attribute
179 ber = Attribute.toBer(a, ber)
180 })
181 ber.endSequence()
182
183 return ber
184}
185
186/// --- Exports
187
188module.exports = SearchEntry