Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add authentication support

  • Loading branch information...
commit cd8d725608322807854ac0fe55f6d8400b9c87e3 1 parent 5e33680
@jankuca authored
View
2  package.json
@@ -1,5 +1,5 @@
{
- "version": "1.0.2",
+ "version": "1.0.3",
"name": "mongodb-lite",
"description": "A lightweight MongoDB driver",
"author": "Jan Kuča <jan@jankuca.com>",
View
1  src/Collection.js
@@ -125,7 +125,6 @@ Collection.prototype.getLastError = function (connection, callback) {
var cmd = this.database_.createCommand('getlasterror', {
'w': 1
});
- cmd.database = this.database_.name;
var buffer = cmd.build();
connection.postMessage(buffer);
View
74 src/Connection.js
@@ -1,3 +1,4 @@
+var crypto = require('crypto');
var net = require('net');
var EventEmitter = require('events').EventEmitter;
@@ -41,6 +42,79 @@ Connection.prototype.close = function () {
this.socket_.end();
};
+Connection.prototype.isAuthenticated = function () {
+ return this.authenticated_;
+};
+
+Connection.prototype.authenticate = function (database, callback) {
+ var self = this;
+ var server = this.getServer();
+ var username = server.username;
+
+ if (!username) {
+ this.authenticated_ = true;
+ callback(null);
+ } else {
+ this.getNonce_(database, function (err, nonce) {
+ if (err) {
+ callback(err);
+ } else {
+ self.authenticate_(database, nonce, callback);
+ }
+ });
+ }
+};
+
+Connection.prototype.getNonce_ = function (database, callback) {
+ var cmd = database.createCommand('getnonce');
+
+ var buffer = cmd.build();
+ this.postMessage(buffer);
+ this.waitForReplyTo(cmd.getRequestId(), function (err, message) {
+ if (err) {
+ callback(err, null);
+ } else {
+ var response = message.getDocumentAt(0);
+ var err = response['ok'] ? null : new Error(response['errmsg']);
+ callback(err, response['nonce'] || null);
+ }
+ });
+};
+
+Connection.prototype.authenticate_ = function (database, nonce, callback) {
+ var self = this;
+ var server = this.getServer();
+ var username = server.username;
+ var password = server.password;
+
+ var password_digest = crypto.createHash('md5')
+ .update(username + ':mongo:' + password).digest('hex');
+ var key = nonce + username + password_digest;
+
+ var cmd = database.createCommand('authenticate', {
+ 'user': username,
+ 'nonce': nonce,
+ 'key': crypto.createHash('md5').update(key).digest('hex')
+ });
+
+ var buffer = cmd.build();
+ this.postMessage(buffer);
+ this.waitForReplyTo(cmd.getRequestId(), function (err, message) {
+ if (err) {
+ callback(err);
+ } else {
+ var response = message.getDocumentAt(0);
+ self.authenticated_ = !!response['ok'];
+ callback(response['ok'] ? null : new Error(response['errmsg']));
+ }
+ });
+};
+
+
+Connection.prototype.getServer = function () {
+ return this.server_;
+};
+
Connection.prototype.postMessage = function (buffer) {
var socket = this.socket_;
socket.write(buffer);
View
21 src/Database.js
@@ -18,10 +18,27 @@ Database.prototype.getCollection = function (collection_name) {
};
Database.prototype.getWritableConnection = function (callback) {
+ var self = this;
+
+ var onConnection = function (connection) {
+ if (connection.isAuthenticated()) {
+ callback(connection);
+ } else {
+ connection.authenticate(self, function (err) {
+ if (err) {
+ console.log(err.stack);
+ callback(null);
+ } else {
+ callback(connection);
+ }
+ });
+ }
+ };
+
if (this.server_) {
- this.server_.getConnection(callback);
+ this.server_.getConnection(onConnection);
} else {
- this.replica_set_.getWritableConnection(callback);
+ this.replica_set_.getWritableConnection(onConnection);
}
};
View
4 src/Server.js
@@ -16,6 +16,10 @@ var Server = function (mongodb_url) {
this.host = this.url.hostname;
this.port = this.url.port;
+ var auth = this.url.auth;
+ this.username = auth ? auth.split(':')[0] : null;
+ this.password = auth ? auth.split(':')[1] : null;
+
this.connection_ = null;
this.is_primary_ = false;
};
Please sign in to comment.
Something went wrong with that request. Please try again.