107 lines
4.1 KiB
JavaScript
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;
|