Merge branch 'pw-salted-hash' into 'master'

Store passwords as salted hashes using bcrypt

See merge request fsimphy/calendar-webapp!3
This commit is contained in:
Oliver Rümpelein 2017-10-16 19:10:38 +02:00
commit b8be9a0932
3 changed files with 22 additions and 11 deletions

View file

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

View file

@ -2,7 +2,6 @@ module calendarwebapp.authenticator;
import poodinis; import poodinis;
import vibe.data.bson : Bson;
import vibe.db.mongo.collection : MongoCollection; import vibe.db.mongo.collection : MongoCollection;
interface Authenticator interface Authenticator
@ -19,8 +18,15 @@ private:
public: public:
bool checkUser(string username, string password) @safe bool checkUser(string username, string password) @safe
{ {
auto result = users.findOne(["username" : username, "password" : password]); import botan.passhash.bcrypt : checkBcrypt;
return result != Bson(null); 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.mock;
import unit_threaded.should; import unit_threaded.should;
import vibe.data.bson : Bson; import vibe.data.bson : Bson, BsonObjectID;
interface Collection interface Collection
{ {
@ -41,13 +41,13 @@ public:
container.register!(Authenticator, MongoDBAuthenticator!(Collection))( container.register!(Authenticator, MongoDBAuthenticator!(Collection))(
RegistrationOption.doNotAddConcreteTypeRegistration); RegistrationOption.doNotAddConcreteTypeRegistration);
collection.returnValue!"findOne"(Bson(true), Bson(null)); auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")), "username" : Bson("foo"),
collection.expect!"findOne"(["username" : "", "password" : ""]); "password" : Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO")]);
collection.expect!"findOne"(["username" : "foo", "password" : "bar"]);
collection.returnValue!"findOne"(Bson(null), userBson, userBson);
auto authenticator = container.resolve!(Authenticator); auto authenticator = container.resolve!(Authenticator);
authenticator.checkUser("", "").shouldBeTrue; authenticator.checkUser("", "").shouldBeFalse;
authenticator.checkUser("foo", "bar").shouldBeFalse; authenticator.checkUser("foo", "bar").shouldBeTrue;
authenticator.checkUser("foo", "baz").shouldBeFalse;
collection.verify;
} }