Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ep_ldapauth

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ep_ldapauth - npm Package Compare versions

Comparing version 0.0.5 to 0.1.0

81

ep_ldapauth.js

@@ -35,3 +35,3 @@ // Copyright 2013 Andrew Grimberg <tykeal@bardicgrove.org>

var ldap = new MyLdapAuth({
var authenticateLDAP = new MyLdapAuth({
url: settings.users.ldapauth.url,

@@ -46,5 +46,11 @@ adminDn: settings.users.ldapauth.searchDN,

// Attempt to authenticate the user
ldap.authenticate(username, password, function(err, user) {
authenticateLDAP.authenticate(username, password, function(err, user) {
if (err) {
console.error('ep_ldapauth.authenticate: LDAP auth error: %s', err);
authenticateLDAP.close(function (err) {
if (err) {
console.error('ep_ldapauth.authenticate: LDAP close error: %s', err);
}
});
authenticateLDAP = null;
return cb([false]);

@@ -55,7 +61,18 @@ }

context.req.session.user = { username: username, displayName: user.cn };
if (settings.users.ldapauth.groupAttributeIsDN) {
context.req.session.user.userDN = user.dn;
}
settings.globalUserName = username;
console.debug('ep_ldapauth.authenticate: deferring setting of username [%s] to CLIENT_READY for express_sid = %s', username, express_sid);
authenticateLDAP.close(function (err) {
if (err) {
console.error('ep_ldapauth.authenticate: LDAP close error: %s', err);
}
});
authenticateLDAP = null;
console.debug('ep_ldapauth.authenticate: successful authentication');
return cb([true]);
});
} else {
console.debug('ep_ldapauth.authenticate: failed authentication no auth headers');
return cb([false]);

@@ -68,19 +85,10 @@ }

var ldap = new MyLdapAuth({
url: settings.users.ldapauth.url,
adminDn: settings.users.ldapauth.searchDN,
adminPassword: settings.users.ldapauth.searchPWD,
searchBase: settings.users.ldapauth.accountBase,
searchFilter: settings.users.ldapauth.accountPattern,
groupSearchBase: settings.users.ldapauth.groupSearchBase,
groupAttribute: settings.users.ldapauth.groupAttribute,
groupAttributeIsDN: settings.users.ldapauth.groupAttributeIsDN,
searchScope: settings.users.ldapauth.searchScope,
groupSearch: settings.users.ldapauth.groupSearch,
cache: true
});
userDN = null;
if (typeof(context.req.session.user) != 'undefined' &&
typeof(context.req.session.user.username) != 'undefined') {
if (typeof(context.req.session.user) !== 'undefined' &&
typeof(context.req.session.user.username) !== 'undefined') {
username = context.req.session.user.username;
if (typeof(context.req.session.user.userDN !== 'undefined')) {
userDN = context.req.session.user.userDN;
}
} else {

@@ -95,6 +103,27 @@ console.debug('ep_ldapauth.authorize: no username in user object');

} else if (context.resource.match(/^\/admin/)) {
console.debug('ep_ldapauth.authorize: authorizing along administrative path %s', context.resource);
ldap.groupsearch(username, function(err, groups) {
console.debug('ep_ldapauth.authorize: attempting to authorize along administrative path %s', context.resource);
var authorizeLDAP = new MyLdapAuth({
url: settings.users.ldapauth.url,
adminDn: settings.users.ldapauth.searchDN,
adminPassword: settings.users.ldapauth.searchPWD,
searchBase: settings.users.ldapauth.accountBase,
searchFilter: settings.users.ldapauth.accountPattern,
groupSearchBase: settings.users.ldapauth.groupSearchBase,
groupAttribute: settings.users.ldapauth.groupAttribute,
groupAttributeIsDN: settings.users.ldapauth.groupAttributeIsDN,
searchScope: settings.users.ldapauth.searchScope,
groupSearch: settings.users.ldapauth.groupSearch,
cache: true
});
authorizeLDAP.groupsearch(username, userDN, function(err, groups) {
if (err) {
console.error('ep_ldapauth.authorize: LDAP groupsearch error: %s', err);
authorizeLDAP.close(function (err) {
if (err) {
console.error('ep_ldapauth.authorize: LDAP close error: %s', err);
}
});
authorizeLDAP = null;
return cb([false]);

@@ -107,5 +136,19 @@ }

context.req.session.user.is_admin = true;
authorizeLDAP.close(function (err) {
if (err) {
console.error('ep_ldapauth.authorize: LDAP close error: %s', err);
}
});
authorizeLDAP = null;
console.debug('ep_ldapauth.authorize: successful authorization');
return cb([true]);
} else {
context.req.session.user.is_admin = false;
authorizeLDAP.close(function (err) {
if (err) {
console.error('ep_ldapauth.authorize: LDAP close error: %s', err);
}
});
authorizeLDAP = null;
console.debug('ep_ldapauth.authorize: failed authorization');
return cb([false]);

@@ -112,0 +155,0 @@ }

@@ -5,8 +5,24 @@ // Copyright 2013 Andrew Grimberg <tykeal@bardicgrove.org>

var assert = require('assert');
var util = require('util');
var LdapAuth = require('ldapauth');
var ldap = require('ldapjs');
/**
* Create the MyLdapAuth class which is a super class of LdapAuth
* Create the MyLdapAuth class which is a former super class of LdapAuth
* until I ended up having to reimplement too much of it
*
* @param opts {Object} config options. Keys (required, unless stated
* otherwise) are:
* url {String} E.g. 'ldaps://ldap.example.com:663'
* adminDn {String} E.g. 'uid=myapp,ou=users,o=example.com'
* adminPassword {String} Password for adminDn
* searchBase {String} The base DN from which to search for users by
* username. E.g. 'ou=users,o=example.com'
* searchFilter {String} LDAP search filter with which to find a user by
* username, e.g. '(uid={{username}})'. Use the literal '{{username}}'
* to have the given username be interpolated in for the LDAP search.
* log4js {Module} Optional. The require'd log4js module to use for logging.
* If given this will result in TRACE-level loggin for MyLdapAuth
* verbose {Boolean} Optional, default false. if `log4js` is also given,
* this will add TRACE-level logging for ldapjs (quite verbose).
* Additional @params opts (see LdapAuth for base params)

@@ -25,13 +41,127 @@ * groupSearchBase {string} Base search location for groups

function MyLdapAuth(opts) {
MyLdapAuth.super_.call(this, opts);
this.opts = opts;
assert.ok(opts.url);
assert.ok(opts.adminDn);
assert.ok(opts.searchBase);
assert.ok(opts.searchFilter);
this.log = opts.log4js && opts.jog4js.getLogger('ldapauth');
var clientOpts = {url: opts.url};
if (opts.log4js && opts.verbose) {
clientOpts.log4js = opts.log4js;
}
}
util.inherits(MyLdapAuth, LdapAuth);
MyLdapAuth.prototype.close = function (cb) {
var self = this;
if (typeof(self._adminClient) !== 'undefined') {
self._adminClient.unbind(function (err) {
if (err) {
return cb(err);
}
self._adminClient = null;
return cb();
});
}
}
MyLdapAuth.prototype._adminBind = function (cb) {
var self = this;
if (typeof(self._adminClient) !== 'undefined') {
return cb();
}
var clientOpts = {url: self.opts.url};
self._adminClient = ldap.createClient(clientOpts);
self._adminClient.bind(self.opts.adminDn, self.opts.adminPassword,
function (err) {
if (err) {
return cb(err);
}
return cb();
});
}
/**
* Find the user record for the given username.
*
* @param username {String}
* @param cb {Function} `function (err, user)`. If not such user is
* found but no error processing, then `user` is undefined.
*/
MyLdapAuth.prototype._findUser = function (username, cb) {
var self = this;
if (!username) {
return cb("empty username");
}
self._adminBind(function (err) {
if (err)
return cb(err);
var searchFilter = self.opts.searchFilter.replace('{{username}}', username);
var opts = {filter: searchFilter, scope: 'sub'};
self._adminClient.search(self.opts.searchBase, opts,
function (err, result) {
if (err) {
return cb(err);
}
var items = [];
result.on('searchEntry', function (entry) {
items.push(entry.object);
});
result.on('error', function (err) {
return cb(err);
});
result.on('end', function (result) {
if (result.status !== 0) {
var err = 'non-zero status from LDAP search: ' + result.status;
return cb(err);
}
switch (items.length) {
case 0:
return cb();
case 1:
return cb(null, items[0]);
default:
return cb(util.format(
'unexpected number of matches (%s) for "%s" username',
items.length, username));
}
});
});
});
}
MyLdapAuth.prototype.authenticate = function (username, password, cb) {
var self = this;
// 1. Find the user DN in question.
self._findUser(username, function (err, user) {
if (err)
return cb(err);
if (!user)
return cb(util.format('no such user: "%s"', username));
// 2. Attempt to bind as that user to check password.
var clientOpts = {url: self.opts.url};
var userClient = ldap.createClient(clientOpts);
userClient.bind(user.dn, password, function (err) {
if (err) {
return cb(err);
}
// User auth's cleanly, destroy the LDAP bind
userClient.unbind();
userClient = null;
return cb(null, user);
});
});
}
/**
* Searches groups to see if a given user is in them
*
* @param username {string} Username to lookup against groupSearch
* @param userDN {string}
*/
MyLdapAuth.prototype.groupsearch = function (username, cb) {
MyLdapAuth.prototype.groupsearch = function (username, userDN, cb) {
var self = this;

@@ -46,10 +176,3 @@ if (!username) {

if (self.opts.groupAttributeIsDN) {
// We need to lookup the user DN
self._findUser(username, function (err, user) {
if (err)
return cb(err);
if (!user)
return cb(util.format('no such user: "%s"', username));
usersearch = user.dn;
});
usersearch = userDN;
}

@@ -93,4 +216,5 @@

return (item === usersearch);
}))
})) {
return cb(null, items[0]);
}

@@ -97,0 +221,0 @@ return cb(util.format('LDAP groupsearch: "%s" is not a member of "%s"',

@@ -5,3 +5,3 @@ {

"author": "Andrew Grimberg <agrimberg@linuxfoundation.org>",
"version": "0.0.5",
"version": "0.1.0",
"license": "GPLv2",

@@ -13,5 +13,5 @@ "repository": {

"dependencies": {
"ldapauth": ">= 2.2.2",
"async-stacktrace": "0.0.2"
"async-stacktrace": "0.0.2",
"ldapjs": "0.6.3"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc