Comparing version 0.1.1 to 0.1.2
@@ -424,1 +424,117 @@ --- | ||
}); | ||
# Address Book | ||
This is example is courtesy of [Diogo Resende](https://github.com/dresende) and | ||
illustrates setting up an address book for typical mail clients such as | ||
Thunderbird or Evolution over a MySQL database. | ||
// MySQL test: (create on database 'abook' with username 'abook' and password 'abook') | ||
// | ||
// CREATE TABLE IF NOT EXISTS `users` ( | ||
// `id` int(5) unsigned NOT NULL AUTO_INCREMENT, | ||
// `username` varchar(50) NOT NULL, | ||
// `password` varchar(50) NOT NULL, | ||
// PRIMARY KEY (`id`), | ||
// KEY `username` (`username`) | ||
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
// INSERT INTO `users` (`username`, `password`) VALUES | ||
// ('demo', 'demo'); | ||
// CREATE TABLE IF NOT EXISTS `contacts` ( | ||
// `id` int(5) unsigned NOT NULL AUTO_INCREMENT, | ||
// `user_id` int(5) unsigned NOT NULL, | ||
// `name` varchar(100) NOT NULL, | ||
// `email` varchar(255) NOT NULL, | ||
// PRIMARY KEY (`id`), | ||
// KEY `user_id` (`user_id`) | ||
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
// INSERT INTO `contacts` (`user_id`, `name`, `email`) VALUES | ||
// (1, 'John Doe', 'john.doe@example.com'), | ||
// (1, 'Jane Doe', 'jane.doe@example.com'); | ||
// | ||
var ldap = require('ldapjs'), | ||
mysql = require("mysql"), | ||
server = ldap.createServer(), | ||
addrbooks = {}, userinfo = {}, | ||
ldap_port = 389, | ||
basedn = "dc=example, dc=com", | ||
company = "Example", | ||
db = mysql.createClient({ | ||
user: "abook", | ||
password: "abook", | ||
database: "abook" | ||
}); | ||
db.query("SELECT c.*,u.username,u.password " + | ||
"FROM contacts c JOIN users u ON c.user_id=u.id", | ||
function(err, contacts) { | ||
if (err) { | ||
console.log("Error fetching contacts", err); | ||
process.exit(1); | ||
} | ||
for (var i = 0; i < contacts.length; i++) { | ||
if (!addrbooks.hasOwnProperty(contacts[i].username)) { | ||
addrbooks[contacts[i].username] = []; | ||
userinfo["cn=" + contacts[i].username + ", " + basedn] = { | ||
abook: addrbooks[contacts[i].username], | ||
pwd: contacts[i].password | ||
}; | ||
} | ||
var p = contacts[i].name.indexOf(" "); | ||
if (p != -1) | ||
contacts[i].firstname = contacts[i].name.substr(0, p); | ||
p = contacts[i].name.lastIndexOf(" "); | ||
if (p != -1) | ||
contacts[i].surname = contacts[i].name.substr(p + 1); | ||
addrbooks[contacts[i].username].push({ | ||
dn: "cn=" + contacts[i].name + ", " + basedn, | ||
attributes: { | ||
objectclass: [ "top" ], | ||
cn: contacts[i].name, | ||
mail: contacts[i].email, | ||
givenname: contacts[i].firstname, | ||
sn: contacts[i].surname, | ||
ou: company | ||
} | ||
}); | ||
} | ||
server.bind(basedn, function (req, res, next) { | ||
var username = req.dn.toString(), | ||
password = req.credentials; | ||
if (!userinfo.hasOwnProperty(username) || | ||
userinfo[username].pwd != password) { | ||
return next(new ldap.InvalidCredentialsError()); | ||
} | ||
res.end(); | ||
return next(); | ||
}); | ||
server.search(basedn, function(req, res, next) { | ||
var binddn = req.connection.ldap.bindDN.toString(); | ||
if (userinfo.hasOwnProperty(binddn)) { | ||
for (var i = 0; i < userinfo[binddn].abook.length; i++) { | ||
if (req.filter.matches(userinfo[binddn].abook[i].attributes)) | ||
res.send(userinfo[binddn].abook[i]); | ||
} | ||
} | ||
res.end(); | ||
}); | ||
server.listen(ldap_port, function() { | ||
console.log("Addressbook started at %s", server.url); | ||
}); | ||
}); | ||
To test out this example, try: | ||
$ ldapsearch -H ldap://localhost:389 -x -D cn=demo,dc=example,dc=com \ | ||
-w demo -b "dc=example,dc=com" objectclass=* |
@@ -107,4 +107,3 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
throw new TypeError('options.log4s must be an object'); | ||
if (options.numConnections && typeof(options.numConnections) !== 'number') | ||
throw new TypeError('options.numConnections must be a number'); | ||
if (!xor(options.url, options.socketPath)) | ||
@@ -123,5 +122,2 @@ throw new TypeError('options.url ^ options.socketPath required'); | ||
this.log4js = options.log4js || logStub; | ||
this.numConnections = Math.abs(options.numConnections) || 1; | ||
this.connections = []; | ||
this.currentConnection = 0; | ||
this.connectOptions = { | ||
@@ -173,29 +169,12 @@ port: self.url ? self.url.port : options.socketPath, | ||
c.on('end', function() { | ||
self.log.trace('%s end', c.ldap.id); | ||
c.ldap.connected = false; | ||
if (!self.shutdown) | ||
c.connect(); | ||
self.emit('end'); | ||
}); | ||
c.addListener('close', function(had_err) { | ||
self.log.trace('%s close; had_err=%j', c.ldap.id, had_err); | ||
c.ldap.connected = false; | ||
if (!self.shutdown) | ||
c.connect(); | ||
self.emit('close', had_err); | ||
}); | ||
c.on('error', function(err) { | ||
self.log.warn('%s unexpected connection error %s', c.ldap.id, err); | ||
self.emit('error', err, c.ldap.id); | ||
c.ldap.connected = false; | ||
if (!self.shutdown) { | ||
c.end(); | ||
c.connect(); | ||
} | ||
self.emit('error', err); | ||
}); | ||
c.on('timeout', function() { | ||
self.log.trace('%s timed out', c.ldap.id); | ||
c.ldap.connected = false; | ||
if (!self.shutdown) { | ||
c.end(); | ||
c.connect(); | ||
} | ||
self.emit('timeout'); | ||
}); | ||
@@ -214,4 +193,4 @@ c.on('data', function(data) { | ||
if (!callback) { | ||
self.log.error('%s: received unsolicited message: %j', | ||
c.ldap.id, message.json); | ||
self.log.error('%s: received unsolicited message: %j', c.ldap.id, | ||
message.json); | ||
return; | ||
@@ -225,5 +204,3 @@ } | ||
for (var i = 0; i < this.numConnections; i++) { | ||
self.connections.push(newConnection()); | ||
} | ||
self.connection = newConnection(); | ||
} | ||
@@ -266,22 +243,3 @@ util.inherits(Client, EventEmitter); | ||
var cbIssued = false; | ||
var finished = 0; | ||
function _callback(err, res) { | ||
if (err) { | ||
if (!cbIssued) { | ||
cbIssued = true; | ||
return callback(err); | ||
} | ||
} | ||
if (++finished >= self.connections.length && !cbIssued) { | ||
cbIssued = true; | ||
self.emit('bind'); | ||
return callback(null, res); | ||
} | ||
} | ||
this.connections.forEach(function(c) { | ||
return self._send(req, [errors.LDAP_SUCCESS], _callback, c); | ||
}); | ||
return self._send(req, [errors.LDAP_SUCCESS], callback); | ||
}; | ||
@@ -655,25 +613,4 @@ | ||
this.shutdown = true; | ||
var req = new UnbindRequest(); | ||
var finished = 0; | ||
var cbIssued = false; | ||
function _callback(err, res) { | ||
if (err) { | ||
if (!cbIssued) { | ||
cbIssued = true; | ||
return callback(err); | ||
} | ||
} | ||
if (++finished >= self.connections.length && !cbIssued) { | ||
cbIssued = true; | ||
self.emit('unbind'); | ||
return callback(null); | ||
} | ||
} | ||
this.connections.forEach(function(c) { | ||
return self._send(req, 'unbind', _callback, c); | ||
}); | ||
return self._send(req, 'unbind', callback); | ||
}; | ||
@@ -683,3 +620,3 @@ | ||
Client.prototype._send = function(message, expect, callback, conn) { | ||
Client.prototype._send = function(message, expect, callback) { | ||
assert.ok(message); | ||
@@ -691,23 +628,4 @@ assert.ok(expect); | ||
// First select a connection | ||
// Note bind and unbind are special in that they will pass in the | ||
// connection since they iterate over the whole pool | ||
if (!conn) { | ||
function nextConn() { | ||
if (++self.currentConnection >= self.connections.length) | ||
self.currentConnection = 0; | ||
var conn = self.connection; | ||
return self.connections[self.currentConnection]; | ||
} | ||
var save = this.currentConnection; | ||
while ((conn = nextConn()) && save !== this.currentConnection); | ||
if (!conn) { | ||
self.emit('error', new DisconnectedError('No connections available')); | ||
return; | ||
} | ||
} | ||
assert.ok(conn); | ||
// Now set up the callback in the messages table | ||
@@ -714,0 +632,0 @@ message.messageID = conn.ldap.nextMessageID; |
@@ -38,3 +38,3 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
d.getUTCFullYear(), | ||
pad(d.getUTCMonth()), | ||
pad(d.getUTCMonth() + 1), | ||
pad(d.getUTCDate()), | ||
@@ -41,0 +41,0 @@ pad(d.getUTCHours()), |
@@ -130,9 +130,9 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
ber.startSequence(Ber.Sequence | Ber.Constructor); | ||
if (this.attributes && this.attributes.length) { | ||
ber.startSequence(Ber.Sequence | Ber.Constructor); | ||
this.attributes.forEach(function(a) { | ||
ber.writeString(a); | ||
}); | ||
ber.endSequence(); | ||
} | ||
ber.endSequence(); | ||
@@ -139,0 +139,0 @@ return ber; |
@@ -6,3 +6,3 @@ { | ||
"description": "LDAP client and server APIs", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"repository": { | ||
@@ -14,3 +14,3 @@ "type": "git", | ||
"engines": { | ||
"node": ">=0.4.10" | ||
"node": ">=0.4" | ||
}, | ||
@@ -17,0 +17,0 @@ "dependencies": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
394714
102
8258