|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- // Copyright 2011 Mark Cavage, Inc. All rights reserved.
-
- var assert = require('assert');
-
- var asn1 = require('asn1');
-
- var parents = require('ldap-filter');
-
- var Protocol = require('../protocol');
-
- var Filter = require('./filter');
- var AndFilter = require('./and_filter');
- var ApproximateFilter = require('./approx_filter');
- var EqualityFilter = require('./equality_filter');
- var ExtensibleFilter = require('./ext_filter');
- var GreaterThanEqualsFilter = require('./ge_filter');
- var LessThanEqualsFilter = require('./le_filter');
- var NotFilter = require('./not_filter');
- var OrFilter = require('./or_filter');
- var PresenceFilter = require('./presence_filter');
- var SubstringFilter = require('./substr_filter');
-
-
-
- ///--- Globals
-
- var BerReader = asn1.BerReader;
-
-
- ///--- Internal Parsers
-
- /*
- * A filter looks like this coming in:
- * Filter ::= CHOICE {
- * and [0] SET OF Filter,
- * or [1] SET OF Filter,
- * not [2] Filter,
- * equalityMatch [3] AttributeValueAssertion,
- * substrings [4] SubstringFilter,
- * greaterOrEqual [5] AttributeValueAssertion,
- * lessOrEqual [6] AttributeValueAssertion,
- * present [7] AttributeType,
- * approxMatch [8] AttributeValueAssertion,
- * extensibleMatch [9] MatchingRuleAssertion --v3 only
- * }
- *
- * SubstringFilter ::= SEQUENCE {
- * type AttributeType,
- * SEQUENCE OF CHOICE {
- * initial [0] IA5String,
- * any [1] IA5String,
- * final [2] IA5String
- * }
- * }
- *
- * The extensibleMatch was added in LDAPv3:
- *
- * MatchingRuleAssertion ::= SEQUENCE {
- * matchingRule [1] MatchingRuleID OPTIONAL,
- * type [2] AttributeDescription OPTIONAL,
- * matchValue [3] AssertionValue,
- * dnAttributes [4] BOOLEAN DEFAULT FALSE
- * }
- */
- function _parse(ber) {
- assert.ok(ber);
-
- function parseSet(f) {
- var end = ber.offset + ber.length;
- while (ber.offset < end)
- f.addFilter(_parse(ber));
- }
-
- var f;
-
- var type = ber.readSequence();
- switch (type) {
-
- case Protocol.FILTER_AND:
- f = new AndFilter();
- parseSet(f);
- break;
-
- case Protocol.FILTER_APPROX:
- f = new ApproximateFilter();
- f.parse(ber);
- break;
-
- case Protocol.FILTER_EQUALITY:
- f = new EqualityFilter();
- f.parse(ber);
- return f;
-
- case Protocol.FILTER_EXT:
- f = new ExtensibleFilter();
- f.parse(ber);
- return f;
-
- case Protocol.FILTER_GE:
- f = new GreaterThanEqualsFilter();
- f.parse(ber);
- return f;
-
- case Protocol.FILTER_LE:
- f = new LessThanEqualsFilter();
- f.parse(ber);
- return f;
-
- case Protocol.FILTER_NOT:
- var _f = _parse(ber);
- f = new NotFilter({
- filter: _f
- });
- break;
-
- case Protocol.FILTER_OR:
- f = new OrFilter();
- parseSet(f);
- break;
-
- case Protocol.FILTER_PRESENT:
- f = new PresenceFilter();
- f.parse(ber);
- break;
-
- case Protocol.FILTER_SUBSTRINGS:
- f = new SubstringFilter();
- f.parse(ber);
- break;
-
- default:
- throw new Error('Invalid search filter type: 0x' + type.toString(16));
- }
-
-
- assert.ok(f);
- return f;
- }
-
-
- function cloneFilter(input) {
- var child;
- if (input.type === 'and' || input.type === 'or') {
- child = input.filters.map(cloneFilter);
- } else if (input.type === 'not') {
- child = cloneFilter(input.filter);
- }
- switch (input.type) {
- case 'and':
- return new AndFilter({filters: child});
- case 'or':
- return new OrFilter({filters: child});
- case 'not':
- return new NotFilter({filter: child});
- case 'equal':
- return new EqualityFilter(input);
- case 'substring':
- return new SubstringFilter(input);
- case 'ge':
- return new GreaterThanEqualsFilter(input);
- case 'le':
- return new LessThanEqualsFilter(input);
- case 'present':
- return new PresenceFilter(input);
- case 'approx':
- return new ApproximateFilter(input);
- case 'ext':
- return new ExtensibleFilter(input);
- default:
- throw new Error('invalid filter type:' + input.type);
- }
- }
-
-
- function parseString(str) {
- var generic = parents.parse(str);
- // The filter object(s) return from ldap-filter.parse lack the toBer/parse
- // decoration that native ldapjs filter possess. cloneFilter adds that back.
- return cloneFilter(generic);
- }
-
-
- ///--- API
-
- module.exports = {
- parse: function (ber) {
- if (!ber || !(ber instanceof BerReader))
- throw new TypeError('ber (BerReader) required');
-
- return _parse(ber);
- },
-
- parseString: parseString,
-
- isFilter: Filter.isFilter,
-
- AndFilter: AndFilter,
- ApproximateFilter: ApproximateFilter,
- EqualityFilter: EqualityFilter,
- ExtensibleFilter: ExtensibleFilter,
- GreaterThanEqualsFilter: GreaterThanEqualsFilter,
- LessThanEqualsFilter: LessThanEqualsFilter,
- NotFilter: NotFilter,
- OrFilter: OrFilter,
- PresenceFilter: PresenceFilter,
- SubstringFilter: SubstringFilter
- };
|