Files
cloudron-box/src/externalldap.js

125 lines
4.5 KiB
JavaScript
Raw Normal View History

'use strict';
exports = module.exports = {
ExternalLdapError: ExternalLdapError,
testConfig: testConfig,
sync: sync
};
var assert = require('assert'),
debug = require('debug')('box:ldapclient'),
ldap = require('ldapjs'),
settings = require('./settings.js'),
util = require('util');
function ExternalLdapError(reason, errorOrMessage) {
assert.strictEqual(typeof reason, 'string');
assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined');
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.reason = reason;
if (typeof errorOrMessage === 'undefined') {
this.message = reason;
} else if (typeof errorOrMessage === 'string') {
this.message = errorOrMessage;
} else {
this.message = 'Internal error';
this.nestedError = errorOrMessage;
}
}
util.inherits(ExternalLdapError, Error);
ExternalLdapError.EXTERNAL_ERROR = 'external error';
ExternalLdapError.INTERNAL_ERROR = 'internal error';
ExternalLdapError.INVALID_CREDENTIALS = 'invalid credentials';
ExternalLdapError.BAD_STATE = 'bad state';
ExternalLdapError.BAD_FIELD = 'bad field';
ExternalLdapError.NOT_FOUND = 'not found';
// performs service bind if required
function getClientAndConfig(callback) {
assert.strictEqual(typeof callback, 'function');
settings.getExternalLdapConfig(function (error, externalLdapConfig) {
if (error) return callback(new ExternalLdapError(ExternalLdapError.INTERNAL_ERROR, error));
var client = ldap.createClient({ url: externalLdapConfig.url });
if (!externalLdapConfig.bindDn) return callback(null, client);
client.bind(externalLdapConfig.bindDn, externalLdapConfig.bindPassword, function (error) {
if (error instanceof ldap.InvalidCredentialsError) return callback(new ExternalLdapError(ExternalLdapError.INVALID_CREDENTIALS));
if (error) return callback(new ExternalLdapError(ExternalLdapError.EXTERNAL_ERROR, error));
debug('getClient: successful');
callback(null, client, externalLdapConfig);
});
});
}
function testConfig(config, callback) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof callback, 'function');
if (!config.url) return callback(new ExternalLdapError(ExternalLdapError.BAD_FIELD, 'url must not be empty'));
if (!config.baseDn) return callback(new ExternalLdapError(ExternalLdapError.BAD_FIELD, 'basedn must not be empty'));
if (!config.filter) return callback(new ExternalLdapError(ExternalLdapError.BAD_FIELD, 'filter must not be empty'));
var client = ldap.createClient({ url: config.url });
if (!config.bindDn) return callback(null, client);
client.bind(config.bindDn, config.bindPassword, function (error) {
if (error instanceof ldap.InvalidCredentialsError) return callback(new ExternalLdapError(ExternalLdapError.INVALID_CREDENTIALS));
if (error) return callback(new ExternalLdapError(ExternalLdapError.EXTERNAL_ERROR, error));
var opts = {
filter: config.filter,
scope: 'sub'
};
client.search(config.baseDn, opts, function (error, result) {
if (error) return callback(new ExternalLdapError(ExternalLdapError.EXTERNAL_ERROR, error));
result.on('searchEntry', function (entry) {});
result.on('error', function (error) { callback(new ExternalLdapError(ExternalLdapError.EXTERNAL_ERROR, error)); });
result.on('end', function (result) { callback(); });
});
});
}
function sync(callback) {
assert.strictEqual(typeof callback, 'function');
getClientAndConfig(function (error, client, externalLdapConfig) {
if (error) return callback(error);
var opts = {
filter: externalLdapConfig.filter,
scope: 'sub'
};
client.search(externalLdapConfig.baseDn, opts, function(err, res) {
assert.ifError(err);
res.on('searchEntry', function(entry) {
console.log('entry: ' + JSON.stringify(entry.object));
});
res.on('searchReference', function(referral) {
console.log('referral: ' + referral.uris.join());
});
res.on('error', function(err) {
console.error('error: ' + err.message);
});
res.on('end', function(result) {
console.log('status: ' + result.status);
});
});
});
}