Lame schema validator (not rfc compatible)

This commit is contained in:
Mark Cavage 2011-08-08 10:29:01 -05:00
parent 6e74d70486
commit a1fa0e46b1
2 changed files with 108 additions and 0 deletions

View File

@ -12,6 +12,7 @@ var errors = require('./errors');
var filters = require('./filters'); var filters = require('./filters');
var logStub = require('./log_stub'); var logStub = require('./log_stub');
var messages = require('./messages'); var messages = require('./messages');
var schema = require('./schema');
var url = require('./url'); var url = require('./url');
@ -65,6 +66,7 @@ module.exports = {
Control: Control, Control: Control,
log4js: logStub, log4js: logStub,
_schema: schema,
url: url url: url
}; };

106
lib/schema.js Normal file
View File

@ -0,0 +1,106 @@
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
var assert = require('assert');
var fs = require('fs');
var Protocol = require('./protocol');
var errors = require('./errors');
///--- API
module.exports = {
/**
*
* Supports definition of objectclasses like so:
* {
* person: {
* required: ['cn', 'sn'],
* optional: ['email']
* }
* }
*/
loadSchema: function(file, callback) {
if (!file || typeof(file) !== 'string')
throw new TypeError('file (string) required');
if (typeof(callback) !== 'function')
throw new TypeError('callback (function) required');
return fs.readFile(file, 'utf8', function(err, data) {
if (err)
return callback(err);
try {
return callback(null, JSON.parse(data));
} catch (e) {
return callback(e);
}
});
},
newInterceptor: function(schema) {
if (typeof(schema) !== 'object')
throw new TypeError('schema (object) required');
// Add/Modify request already have attributes sorted
return function(req, res, next) {
switch (req.protocolOp) {
case Protocol.LDAP_REQ_ADD:
var ocNdx = req.indexOf('objectclass');
if (ocNdx === -1)
return next(new errors.ConstraintViolation('objectclass'));
var reqOC = req.attributes[ocNdx];
// First make the "set" of required/optional attributes for all OCs in
// the union of all OCs. We destroy these arrays after the fact. Note
// that optional will get the set of attributes also not already in
// required, since we figure this out by destructively changing the
// list of attribute names.
var required = [];
var optional = [];
var i, j;
for (i = 0; i < reqOC.vals.length; i++) {
var oc = schema[reqOC.vals[i]];
if (!oc)
return next(new errors.UndefinedAttributeType(reqOC.vals[i]));
for (j = 0; j < oc.required.length; j++) {
if (required.indexOf(oc.required[j]) === -1)
required.push(oc.required[j]);
}
for (j = 0; j < oc.optional.length; j++) {
if (optional.indexOf(oc.optional[j]) === -1 &&
required.indexOf(oc.optional[j]) === -1)
optional.push(oc.optional[j]);
}
}
// Make a copy of just the attribute names
var attrs = req.attributeNames();
for (i = 0; i < attrs.length; i++) {
var ndx = required.indexOf(attrs[i]);
if (ndx === -1) {
ndx = optional.indexOf(attrs[i]);
if (ndx == -1)
return next(new errors.ConstraintViolation(attrs[i]));
}
attrs.splice(i, 1);
}
if (attrs.length)
return next(new errors.ConstraintViolation(attrs.join()));
break;
case Protocol.LDAP_REQ_MODIFY:
break;
default:
return next();
}
}
}
};