Search filter transformer based on schema
This commit is contained in:
parent
11fbda69e7
commit
73f913b2c4
|
@ -58,7 +58,7 @@ ApproximateFilter.prototype.matches = function(target) {
|
||||||
ApproximateFilter.prototype.parse = function(ber) {
|
ApproximateFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -67,7 +67,7 @@ EqualityFilter.prototype.matches = function(target) {
|
||||||
EqualityFilter.prototype.parse = function(ber) {
|
EqualityFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -49,6 +49,7 @@ GreaterThanEqualsFilter.prototype.matches = function(target) {
|
||||||
throw new TypeError('target (object) required');
|
throw new TypeError('target (object) required');
|
||||||
|
|
||||||
var matches = false;
|
var matches = false;
|
||||||
|
|
||||||
if (target.hasOwnProperty(this.attribute)) {
|
if (target.hasOwnProperty(this.attribute)) {
|
||||||
if (Array.isArray(target[this.attribute])) {
|
if (Array.isArray(target[this.attribute])) {
|
||||||
for (var i = 0; i < target[this.attribute].length; i++) {
|
for (var i = 0; i < target[this.attribute].length; i++) {
|
||||||
|
@ -68,7 +69,7 @@ GreaterThanEqualsFilter.prototype.matches = function(target) {
|
||||||
GreaterThanEqualsFilter.prototype.parse = function(ber) {
|
GreaterThanEqualsFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -69,7 +69,7 @@ LessThanEqualsFilter.prototype.matches = function(target) {
|
||||||
LessThanEqualsFilter.prototype.parse = function(ber) {
|
LessThanEqualsFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -50,11 +50,7 @@ PresenceFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute =
|
this.attribute =
|
||||||
ber
|
ber.buffer.slice(0, ber.length).toString('utf8').toLowerCase();
|
||||||
.buffer
|
|
||||||
.slice(0, ber.length)
|
|
||||||
.toString('utf8')
|
|
||||||
.toLowerCase();
|
|
||||||
|
|
||||||
ber._offset += ber.length;
|
ber._offset += ber.length;
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ SubstringFilter.prototype.matches = function(target) {
|
||||||
SubstringFilter.prototype.parse = function(ber) {
|
SubstringFilter.prototype.parse = function(ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
ber.readSequence();
|
ber.readSequence();
|
||||||
var end = ber.offset + ber.length;
|
var end = ber.offset + ber.length;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,8 @@ module.exports = {
|
||||||
|
|
||||||
loadSchema: schema.load,
|
loadSchema: schema.load,
|
||||||
createSchemaAddHandler: schema.createAddHandler,
|
createSchemaAddHandler: schema.createAddHandler,
|
||||||
createSchemaModifyHandler: schema.createModifyHandler
|
createSchemaModifyHandler: schema.createModifyHandler,
|
||||||
|
createSchemaSearchHandler: schema.createSearchHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
var createAddHandler = require('./add_handler');
|
var createAddHandler = require('./add_handler');
|
||||||
var createModifyHandler = require('./mod_handler');
|
var createModifyHandler = require('./mod_handler');
|
||||||
|
var createSearchHandler = require('./search_handler');
|
||||||
var parser = require('./parser');
|
var parser = require('./parser');
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ module.exports = {
|
||||||
|
|
||||||
createModifyHandler: createModifyHandler,
|
createModifyHandler: createModifyHandler,
|
||||||
|
|
||||||
|
createSearchHandler: createSearchHandler,
|
||||||
|
|
||||||
load: parser.load
|
load: parser.load
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,14 +9,54 @@ var logStub = require('../log_stub');
|
||||||
var getTransformer = require('./transform').getTransformer;
|
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) {
|
function createSearchHandler(options) {
|
||||||
if (!options || typeof(options) !== 'object')
|
if (!options || typeof(options) !== 'object')
|
||||||
throw new TypeError('options (object) required');
|
throw new TypeError('options (object) required');
|
||||||
if (!options.schema || typeof(options.schema) !== 'object')
|
if (!options.schema || typeof(options.schema) !== 'object')
|
||||||
throw new TypeError('options.schema (object) required');
|
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 log4js = options.log4js || logStub;
|
||||||
var log = log4js.getLogger('SchemaSearchHandler');
|
var log = log4js.getLogger('SchemaSearchHandler');
|
||||||
|
@ -30,8 +70,18 @@ function createSearchHandler(options) {
|
||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
log.debug('%s running %j against schema', req.logId, req.filter);
|
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();
|
return next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = createSearchHandler;
|
module.exports = createSearchHandler;
|
||||||
|
|
Loading…
Reference in New Issue