Store passwords as salted hashes using bcrypt

This commit is contained in:
Johannes Loher 2017-10-15 16:43:39 +02:00
parent 8f37710536
commit ed717679ba
3 changed files with 22 additions and 11 deletions

View file

@ -4,9 +4,14 @@
"Johannes Loher"
],
"dependencies": {
"botan": "~>1.12.9",
"vibe-d": "~>0.8.1",
"vibe-d:tls": "~>0.8.1",
"poodinis": "~>8.0.1"
},
"subConfigurations": {
"vibe-d:tls": "botan"
},
"description": "A simple webapplication to edit and view calendar entries",
"copyright": "Copyright © 2017, Johannes Loher",
"license": "MIT",

View file

@ -2,7 +2,6 @@ module calendarwebapp.authenticator;
import poodinis;
import vibe.data.bson : Bson;
import vibe.db.mongo.collection : MongoCollection;
interface Authenticator
@ -19,8 +18,15 @@ private:
public:
bool checkUser(string username, string password) @safe
{
auto result = users.findOne(["username" : username, "password" : password]);
return result != Bson(null);
import botan.passhash.bcrypt : checkBcrypt;
import vibe.data.bson : Bson;
auto result = users.findOne(["username" : username]);
/* checkBcrypt should be called using vibe.core.concurrency.async to
avoid blocking, but https://github.com/vibe-d/vibe.d/issues/1521 is
blocking this */
return (result != Bson(null)) && (() @trusted => checkBcrypt(password,
result["password"].get!string))();
}
}

View file

@ -7,7 +7,7 @@ import poodinis;
import unit_threaded.mock;
import unit_threaded.should;
import vibe.data.bson : Bson;
import vibe.data.bson : Bson, BsonObjectID;
interface Collection
{
@ -41,13 +41,13 @@ public:
container.register!(Authenticator, MongoDBAuthenticator!(Collection))(
RegistrationOption.doNotAddConcreteTypeRegistration);
collection.returnValue!"findOne"(Bson(true), Bson(null));
collection.expect!"findOne"(["username" : "", "password" : ""]);
collection.expect!"findOne"(["username" : "foo", "password" : "bar"]);
auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")), "username" : Bson("foo"),
"password" : Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO")]);
collection.returnValue!"findOne"(Bson(null), userBson, userBson);
auto authenticator = container.resolve!(Authenticator);
authenticator.checkUser("", "").shouldBeTrue;
authenticator.checkUser("foo", "bar").shouldBeFalse;
collection.verify;
authenticator.checkUser("", "").shouldBeFalse;
authenticator.checkUser("foo", "bar").shouldBeTrue;
authenticator.checkUser("foo", "baz").shouldBeFalse;
}