UNPKG

5.19 kBJavaScriptView Raw
1// Copyright 2011 Mark Cavage, Inc. All rights reserved.
2
3var assert = require('assert');
4
5var asn1 = require('asn1');
6
7var parents = require('ldap-filter');
8
9var Protocol = require('../protocol');
10
11var Filter = require('./filter');
12var AndFilter = require('./and_filter');
13var ApproximateFilter = require('./approx_filter');
14var EqualityFilter = require('./equality_filter');
15var ExtensibleFilter = require('./ext_filter');
16var GreaterThanEqualsFilter = require('./ge_filter');
17var LessThanEqualsFilter = require('./le_filter');
18var NotFilter = require('./not_filter');
19var OrFilter = require('./or_filter');
20var PresenceFilter = require('./presence_filter');
21var SubstringFilter = require('./substr_filter');
22
23
24
25///--- Globals
26
27var BerReader = asn1.BerReader;
28
29
30///--- Internal Parsers
31
32/*
33 * A filter looks like this coming in:
34 * Filter ::= CHOICE {
35 * and [0] SET OF Filter,
36 * or [1] SET OF Filter,
37 * not [2] Filter,
38 * equalityMatch [3] AttributeValueAssertion,
39 * substrings [4] SubstringFilter,
40 * greaterOrEqual [5] AttributeValueAssertion,
41 * lessOrEqual [6] AttributeValueAssertion,
42 * present [7] AttributeType,
43 * approxMatch [8] AttributeValueAssertion,
44 * extensibleMatch [9] MatchingRuleAssertion --v3 only
45 * }
46 *
47 * SubstringFilter ::= SEQUENCE {
48 * type AttributeType,
49 * SEQUENCE OF CHOICE {
50 * initial [0] IA5String,
51 * any [1] IA5String,
52 * final [2] IA5String
53 * }
54 * }
55 *
56 * The extensibleMatch was added in LDAPv3:
57 *
58 * MatchingRuleAssertion ::= SEQUENCE {
59 * matchingRule [1] MatchingRuleID OPTIONAL,
60 * type [2] AttributeDescription OPTIONAL,
61 * matchValue [3] AssertionValue,
62 * dnAttributes [4] BOOLEAN DEFAULT FALSE
63 * }
64 */
65function _parse(ber) {
66 assert.ok(ber);
67
68 function parseSet(f) {
69 var end = ber.offset + ber.length;
70 while (ber.offset < end)
71 f.addFilter(_parse(ber));
72 }
73
74 var f;
75
76 var type = ber.readSequence();
77 switch (type) {
78
79 case Protocol.FILTER_AND:
80 f = new AndFilter();
81 parseSet(f);
82 break;
83
84 case Protocol.FILTER_APPROX:
85 f = new ApproximateFilter();
86 f.parse(ber);
87 break;
88
89 case Protocol.FILTER_EQUALITY:
90 f = new EqualityFilter();
91 f.parse(ber);
92 return f;
93
94 case Protocol.FILTER_EXT:
95 f = new ExtensibleFilter();
96 f.parse(ber);
97 return f;
98
99 case Protocol.FILTER_GE:
100 f = new GreaterThanEqualsFilter();
101 f.parse(ber);
102 return f;
103
104 case Protocol.FILTER_LE:
105 f = new LessThanEqualsFilter();
106 f.parse(ber);
107 return f;
108
109 case Protocol.FILTER_NOT:
110 var _f = _parse(ber);
111 f = new NotFilter({
112 filter: _f
113 });
114 break;
115
116 case Protocol.FILTER_OR:
117 f = new OrFilter();
118 parseSet(f);
119 break;
120
121 case Protocol.FILTER_PRESENT:
122 f = new PresenceFilter();
123 f.parse(ber);
124 break;
125
126 case Protocol.FILTER_SUBSTRINGS:
127 f = new SubstringFilter();
128 f.parse(ber);
129 break;
130
131 default:
132 throw new Error('Invalid search filter type: 0x' + type.toString(16));
133 }
134
135
136 assert.ok(f);
137 return f;
138}
139
140
141function cloneFilter(input) {
142 var child;
143 if (input.type === 'and' || input.type === 'or') {
144 child = input.filters.map(cloneFilter);
145 } else if (input.type === 'not') {
146 child = cloneFilter(input.filter);
147 }
148 switch (input.type) {
149 case 'and':
150 return new AndFilter({filters: child});
151 case 'or':
152 return new OrFilter({filters: child});
153 case 'not':
154 return new NotFilter({filter: child});
155 case 'equal':
156 return new EqualityFilter(input);
157 case 'substring':
158 return new SubstringFilter(input);
159 case 'ge':
160 return new GreaterThanEqualsFilter(input);
161 case 'le':
162 return new LessThanEqualsFilter(input);
163 case 'present':
164 return new PresenceFilter(input);
165 case 'approx':
166 return new ApproximateFilter(input);
167 case 'ext':
168 return new ExtensibleFilter(input);
169 default:
170 throw new Error('invalid filter type:' + input.type);
171 }
172}
173
174
175function parseString(str) {
176 var generic = parents.parse(str);
177 // The filter object(s) return from ldap-filter.parse lack the toBer/parse
178 // decoration that native ldapjs filter possess. cloneFilter adds that back.
179 return cloneFilter(generic);
180}
181
182
183///--- API
184
185module.exports = {
186 parse: function (ber) {
187 if (!ber || !(ber instanceof BerReader))
188 throw new TypeError('ber (BerReader) required');
189
190 return _parse(ber);
191 },
192
193 parseString: parseString,
194
195 isFilter: Filter.isFilter,
196
197 AndFilter: AndFilter,
198 ApproximateFilter: ApproximateFilter,
199 EqualityFilter: EqualityFilter,
200 ExtensibleFilter: ExtensibleFilter,
201 GreaterThanEqualsFilter: GreaterThanEqualsFilter,
202 LessThanEqualsFilter: LessThanEqualsFilter,
203 NotFilter: NotFilter,
204 OrFilter: OrFilter,
205 PresenceFilter: PresenceFilter,
206 SubstringFilter: SubstringFilter
207};