diff --git a/lib/filters/approx_filter.js b/lib/filters/approx_filter.js index 0074adb..9647a42 100644 --- a/lib/filters/approx_filter.js +++ b/lib/filters/approx_filter.js @@ -58,7 +58,7 @@ ApproximateFilter.prototype.matches = function(target) { ApproximateFilter.prototype.parse = function(ber) { assert.ok(ber); - this.attribute = ber.readString(); + this.attribute = ber.readString().toLowerCase(); this.value = ber.readString(); return true; diff --git a/lib/filters/equality_filter.js b/lib/filters/equality_filter.js index 2fae0c6..c267f46 100644 --- a/lib/filters/equality_filter.js +++ b/lib/filters/equality_filter.js @@ -67,7 +67,7 @@ EqualityFilter.prototype.matches = function(target) { EqualityFilter.prototype.parse = function(ber) { assert.ok(ber); - this.attribute = ber.readString(); + this.attribute = ber.readString().toLowerCase(); this.value = ber.readString(); return true; diff --git a/lib/filters/ge_filter.js b/lib/filters/ge_filter.js index cb2e19b..9177c4c 100644 --- a/lib/filters/ge_filter.js +++ b/lib/filters/ge_filter.js @@ -49,6 +49,7 @@ GreaterThanEqualsFilter.prototype.matches = function(target) { throw new TypeError('target (object) required'); var matches = false; + if (target.hasOwnProperty(this.attribute)) { if (Array.isArray(target[this.attribute])) { for (var i = 0; i < target[this.attribute].length; i++) { @@ -68,7 +69,7 @@ GreaterThanEqualsFilter.prototype.matches = function(target) { GreaterThanEqualsFilter.prototype.parse = function(ber) { assert.ok(ber); - this.attribute = ber.readString(); + this.attribute = ber.readString().toLowerCase(); this.value = ber.readString(); return true; diff --git a/lib/filters/le_filter.js b/lib/filters/le_filter.js index 9c72303..eb87149 100644 --- a/lib/filters/le_filter.js +++ b/lib/filters/le_filter.js @@ -69,7 +69,7 @@ LessThanEqualsFilter.prototype.matches = function(target) { LessThanEqualsFilter.prototype.parse = function(ber) { assert.ok(ber); - this.attribute = ber.readString(); + this.attribute = ber.readString().toLowerCase(); this.value = ber.readString(); return true; diff --git a/lib/filters/presence_filter.js b/lib/filters/presence_filter.js index 4ed4ae3..9fccf90 100644 --- a/lib/filters/presence_filter.js +++ b/lib/filters/presence_filter.js @@ -50,11 +50,7 @@ PresenceFilter.prototype.parse = function(ber) { assert.ok(ber); this.attribute = - ber - .buffer - .slice(0, ber.length) - .toString('utf8') - .toLowerCase(); + ber.buffer.slice(0, ber.length).toString('utf8').toLowerCase(); ber._offset += ber.length; diff --git a/lib/filters/substr_filter.js b/lib/filters/substr_filter.js index 7bf7650..31ed374 100644 --- a/lib/filters/substr_filter.js +++ b/lib/filters/substr_filter.js @@ -85,7 +85,7 @@ SubstringFilter.prototype.matches = function(target) { SubstringFilter.prototype.parse = function(ber) { assert.ok(ber); - this.attribute = ber.readString(); + this.attribute = ber.readString().toLowerCase(); ber.readSequence(); var end = ber.offset + ber.length; diff --git a/lib/index.js b/lib/index.js index 491f30c..b067445 100644 --- a/lib/index.js +++ b/lib/index.js @@ -70,7 +70,8 @@ module.exports = { loadSchema: schema.load, createSchemaAddHandler: schema.createAddHandler, - createSchemaModifyHandler: schema.createModifyHandler + createSchemaModifyHandler: schema.createModifyHandler, + createSchemaSearchHandler: schema.createSearchHandler }; diff --git a/lib/schema/index.js b/lib/schema/index.js index 9299f76..9e28b20 100644 --- a/lib/schema/index.js +++ b/lib/schema/index.js @@ -2,6 +2,7 @@ var createAddHandler = require('./add_handler'); var createModifyHandler = require('./mod_handler'); +var createSearchHandler = require('./search_handler'); var parser = require('./parser'); @@ -14,6 +15,8 @@ module.exports = { createModifyHandler: createModifyHandler, + createSearchHandler: createSearchHandler, + load: parser.load }; diff --git a/lib/schema/search_handler.js b/lib/schema/search_handler.js index e0529e4..8b286e6 100644 --- a/lib/schema/search_handler.js +++ b/lib/schema/search_handler.js @@ -9,14 +9,54 @@ var logStub = require('../log_stub'); var getTransformer = require('./transform').getTransformer; +function transformFilter(schema, filter) { + assert.ok(schema); + assert.ok(filter); + + var attributes = schema.attributes; + + switch (filter.type) { + case 'equal': + case 'approx': + case 'ge': + case 'le': + if (!attributes[filter.attribute.toLowerCase()]) + throw new errors.NoSuchAttributeError(filter.attribute); + + var transform = getTransformer(schema, filter.attribute); + if (transform) + filter.value = transform(filter.value) || filter.value; + + break; + + case 'substring': + case 'present': + if (!attributes[filter.attribute.toLowerCase()]) + throw new errors.NoSuchAttributeError(filter.attribute); + + break; + + case 'and': + case 'or': + for (var i = 0; i < filter.filters.length; i++) + filter.filters[i] = transformFilter(schema, filter.filters[i]); + + break; + + case 'not': + filter.filter = trasnformFilter(schema, filter.filter); + } + + return filter; +} + + function createSearchHandler(options) { if (!options || typeof(options) !== 'object') throw new TypeError('options (object) required'); if (!options.schema || typeof(options.schema) !== 'object') throw new TypeError('options.schema (object) required'); - // TODO add a callback mechanism here so objectclass constraints can be - // enforced var log4js = options.log4js || logStub; var log = log4js.getLogger('SchemaSearchHandler'); @@ -30,8 +70,18 @@ function createSearchHandler(options) { if (log.isDebugEnabled()) log.debug('%s running %j against schema', req.logId, req.filter); + try { + req.filter = transformFilter(schema, req.filter); + } catch (e) { + if (log.isDebugEnabled()) + log.debug('%s error transforming filter: %s', req.logId, e.stack); + return next(e); + } + return next(); } } + + module.exports = createSearchHandler;