om/server/ldap_ohm.js

107 lines
4.1 KiB
JavaScript

// Original file created by Prof.Dr. Matthias Hopf
/*
* Valdiate ohm logins with ldap service
*/
const ldap = require('ldapjs');
const ldap_escape = require('ldap-escape');
// TODO: Where do I get the URL from?? A: Is given.
var ldap_client = ldap.createClient({
//url: 'ldap://gso2.ads1.fh-nuernberg.de/',
url: 'ldap://sso.cs.ohm-hochschule.de:389/',
//url: 'ldaps://sso.cs.ohm-hochschule.de:636/',
reconnect: true,
// timeouts don't work reliably
});
// TODO: Where do I get the 'bindpath' parameters info from? A: Is given.
const ldap_config = {
bindpath: 'cn=Users,dc=ohm-hochschule,dc=de',
timeout: 2000
};
const ldap_ohm = {
init: function () {
},
// Authorize user with password
// Calls callback with null if unauthorized
// Calls callback with object describing user if successful:
authorize: function (user, pwd, cb) {
if (typeof user != 'string' || typeof pwd != 'string')
return cb (null);
// Empty passwords *may* bind successfully anonymously
if (user.length < 1 || pwd.length < 1)
return cb (null);
/* Same function, different writing style */
/* Escape ldap login input */
//escaped = ldap_escape.dn`cn=${user},`+ldap_config.bindpath;
escaped = ldap_escape.dn (['cn=',','+ldap_config.bindpath], user);
// Timeout handler: call callback,
// make sure later ldap returns don't do anything weird
var return_object = {};
var timeoutHandle = setTimeout (function () {
console.log('ldap timeout');
return_object = null;
cb (null);
}, ldap_config.timeout);
// Bind ldap to user (authorize)
ldap_client.bind (escaped, pwd, function (err, res) {
if (return_object === null)
return; // Timeout, cb has already been called
if (err !== null) {
console.log ("ldap bind: failed for user " + user + ": " + err);
clearTimeout (timeoutHandle);
return cb (null);
}
// Search for user entry of just bound user
// There should be only one...
ldap_client.search (escaped, { sizeLimit: 1 }, function (err, res) {
if (return_object === null)
return; // Timeout, cb has already been called
if (err !== null) {
console.log ("ldap search: search after bind didn't work for user "
+ user + ": " + err);
clearTimeout (timeoutHandle);
return cb (null);
}
// Populate return with search results
res.on('searchEntry', function(entry) {
if (return_object === null)
return; // Timeout, cb has already been called
return_object.user = user;
return_object.name = entry.object.displayname;
return_object.type = entry.object.employeetype;
return_object.mail = entry.object.mail;
return_object.gender = entry.object.orclgender;
// Calling cb here, not in 'end', because of potential bugs with
// concurrency failures, and we have our single(!) entry
// https://github.com/joyent/node-ldapjs/pull/424
clearTimeout (timeoutHandle);
if (typeof return_object.mail != 'string' || return_object.mail.length < 1) {
console.log("ldap search error after bind for user " + user);
return cb (null);
}
return cb (return_object);
});
res.on('error', function(err) {
console.log('ldap error: ' + err.message);
});
res.on('end', function(result) {
// TODO: Did we forget something?
// TODO: analyze result.status?
});
});
});
}
};
module.exports = ldap_ohm;