1 |
|
2 |
|
3 | const assert = require('assert-plus')
|
4 | const util = require('util')
|
5 |
|
6 |
|
7 |
|
8 | const LDAPMessage = require('./message')
|
9 | const Attribute = require('../attribute')
|
10 | const Protocol = require('../protocol')
|
11 | const lassert = require('../assert')
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | function 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 | }
|
30 | util.inherits(SearchEntry, LDAPMessage)
|
31 | Object.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 |
|
91 | SearchEntry.prototype.addAttribute = function (attr) {
|
92 | if (!attr || typeof (attr) !== 'object') { throw new TypeError('attr (attribute) required') }
|
93 |
|
94 | this.attributes.push(attr)
|
95 | }
|
96 |
|
97 | SearchEntry.prototype.toObject = function () {
|
98 | return this.object
|
99 | }
|
100 |
|
101 | SearchEntry.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 |
|
117 | SearchEntry.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 |
|
143 | SearchEntry.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 |
|
155 | SearchEntry.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 |
|
171 | SearchEntry.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 |
|
179 | ber = Attribute.toBer(a, ber)
|
180 | })
|
181 | ber.endSequence()
|
182 |
|
183 | return ber
|
184 | }
|
185 |
|
186 |
|
187 |
|
188 | module.exports = SearchEntry
|