forked from vibe-d/vibe.d
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for MongoDB authentication (digest).
- Loading branch information
Christian Schneider
committed
Mar 27, 2013
1 parent
3acb39a
commit 2438a64
Showing
1 changed file
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/** | ||
MongoDB authentication adapter | ||
Copyright: © 2012 RejectedSoftware e.K. | ||
License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. | ||
Authors: Sönke Ludwig, Christian Schneider | ||
*/ | ||
module vibe.db.mongo.auth; | ||
import | ||
std.string, | ||
std.digest.md, | ||
vibe.data.bson, | ||
vibe.db.mongo.client, | ||
vibe.db.mongo.database | ||
; | ||
|
||
class MongoAuth | ||
{ | ||
private | ||
{ | ||
MongoClient m_client; | ||
} | ||
|
||
/** | ||
Initialize adapter. | ||
Examples: | ||
--- | ||
auto ma = new MongoAuth(mongo); | ||
bool ok = ma.auth("admin", "guru", "secret"); | ||
--- | ||
*/ | ||
|
||
this(MongoClient client) | ||
{ | ||
m_client = client; | ||
} | ||
|
||
/** | ||
Initialize adapter and authenticate this connection. | ||
Throws: | ||
Exception if not successfully authenticated. | ||
Examples: | ||
--- | ||
auto ma = new MongoAuth(mongo, "admin", "guru", "secret"); | ||
--- | ||
*/ | ||
this(MongoClient client, string dbname, string username, string password) | ||
{ | ||
m_client = mongo; | ||
bool res = auth(dbname, username, password); | ||
if (!res) throw new Exception("MongoAuth failed."); | ||
} | ||
|
||
/** | ||
Authenticate this connection. | ||
Examples: | ||
--- | ||
auto ma = new MongoAuth(mongo); | ||
bool ok = ma.auth("admin", "guru", "secret"); | ||
logInfo("auth: %s", ok); | ||
--- | ||
*/ | ||
bool auth(string dbname, string username, string password) | ||
{ | ||
auto db = m_client.getDatabase(dbname); | ||
string nonce = getNonce(db); | ||
string key = getKey(nonce, username, password); | ||
Bson cmd = Bson.EmptyObject; | ||
cmd["authenticate"] = Bson(1); | ||
cmd["nonce"] = Bson(nonce); | ||
cmd["user"] = Bson(username); | ||
cmd["key"] = Bson(key); | ||
auto res = db.runCommand(cmd); | ||
if (res["ok"].get!double == 1.0) | ||
return true; | ||
return false; | ||
} | ||
|
||
package string getNonce(MongoDatabase db) | ||
{ | ||
auto res = db.runCommand(Bson(["getnonce":Bson(1)])); | ||
return res["nonce"].get!string; | ||
} | ||
|
||
package string getKey(string nonce, string username, string password) | ||
{ | ||
return toLower(toHexString(md5Of(nonce ~ username ~ createPasswordDigest(username, password))).idup); | ||
} | ||
|
||
package string createPasswordDigest(string username, string password) | ||
{ | ||
return toLower(toHexString(md5Of(username ~ ":mongo:" ~ password)).idup); | ||
} | ||
} |