Use DAuth instead of botan for password hashing. Fixes #7
This commit is contained in:
parent
2eec08b9bf
commit
fd89dd25ca
5 changed files with 31 additions and 50 deletions
6
dub.json
6
dub.json
|
@ -4,14 +4,10 @@
|
|||
"Johannes Loher"
|
||||
],
|
||||
"dependencies": {
|
||||
"botan": "~>1.12.9",
|
||||
"dauth": "~>0.6.3",
|
||||
"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",
|
||||
|
|
|
@ -28,8 +28,6 @@ private:
|
|||
public:
|
||||
Nullable!AuthInfo checkUser(string username, string password) @safe
|
||||
{
|
||||
import botan.passhash.bcrypt : checkBcrypt;
|
||||
|
||||
auto result = users.findOne(["username" : username]);
|
||||
/* checkHash should be called using vibe.core.concurrency.async to
|
||||
avoid blocking, but https://github.com/vibe-d/vibe.d/issues/1521 is
|
||||
|
@ -37,6 +35,8 @@ public:
|
|||
if (result != Bson(null))
|
||||
{
|
||||
auto authInfo = result.deserializeBson!AuthInfo;
|
||||
import vibe.core.log : logInfo;
|
||||
logInfo(passwordHasher.generateHash(password));
|
||||
if (passwordHasher.checkHash(password, authInfo.passwordHash))
|
||||
{
|
||||
return authInfo.nullable;
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
module calendarwebapp.configuration;
|
||||
|
||||
import botan.rng.auto_rng : AutoSeededRNG;
|
||||
import botan.rng.rng : RandomNumberGenerator;
|
||||
|
||||
import calendarwebapp.authenticator : Authenticator, MongoDBAuthenticator;
|
||||
import calendarwebapp.calendarwebapp : CalendarWebapp;
|
||||
import calendarwebapp.event : EventStore, MongoDBEventStore;
|
||||
import calendarwebapp.passhash : BcryptPasswordHasher, PasswordHasher;
|
||||
import calendarwebapp.passhash : PasswordHasher, SHA256PasswordHasher;
|
||||
|
||||
import poodinis;
|
||||
|
||||
|
@ -23,8 +20,7 @@ public:
|
|||
container.register!MongoClient.existingInstance(mongoClient);
|
||||
container.register!(EventStore, MongoDBEventStore!());
|
||||
container.register!(Authenticator, MongoDBAuthenticator!());
|
||||
container.register!(PasswordHasher, BcryptPasswordHasher);
|
||||
container.register!(RandomNumberGenerator, AutoSeededRNG);
|
||||
container.register!(PasswordHasher, SHA256PasswordHasher);
|
||||
container.register!CalendarWebapp;
|
||||
container.register!(ValueInjector!string, StringInjector);
|
||||
container.register!(ValueInjector!MongoCollection, MongoCollectionInjector);
|
||||
|
|
|
@ -4,30 +4,10 @@ import poodinis;
|
|||
|
||||
interface PasswordHasher
|
||||
{
|
||||
string generateHash(in string password) @safe;
|
||||
string generateHash(in string password) const @safe;
|
||||
bool checkHash(in string password, in string hash) const @safe;
|
||||
}
|
||||
|
||||
class BcryptPasswordHasher : PasswordHasher
|
||||
{
|
||||
import botan.passhash.bcrypt : checkBcrypt, generateBcrypt;
|
||||
import botan.rng.rng : RandomNumberGenerator;
|
||||
|
||||
string generateHash(in string password) @safe
|
||||
{
|
||||
return (() @trusted => generateBcrypt(password, rng, cost))();
|
||||
}
|
||||
|
||||
bool checkHash(in string password, in string hash) const @safe
|
||||
{
|
||||
return (()@trusted => checkBcrypt(password, hash))();
|
||||
}
|
||||
|
||||
private:
|
||||
@Autowire RandomNumberGenerator rng;
|
||||
enum cost = 10;
|
||||
}
|
||||
|
||||
class StubPasswordHasher : PasswordHasher
|
||||
{
|
||||
string generateHash(in string password) const @safe pure nothrow
|
||||
|
@ -40,3 +20,19 @@ class StubPasswordHasher : PasswordHasher
|
|||
return password == hash;
|
||||
}
|
||||
}
|
||||
|
||||
class SHA256PasswordHasher : PasswordHasher
|
||||
{
|
||||
import dauth;
|
||||
import std.digest.sha : SHA256;
|
||||
|
||||
string generateHash(in string password) const @safe
|
||||
{
|
||||
return (() @trusted => password.dupPassword.makeHash!SHA256.toCryptString)();
|
||||
}
|
||||
|
||||
bool checkHash(in string password, in string hash) const @safe
|
||||
{
|
||||
return (() @trusted => isSameHash(password.dupPassword, parseHash(hash)))();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,24 +4,8 @@ import calendarwebapp.passhash;
|
|||
|
||||
import poodinis;
|
||||
|
||||
//import unit_threaded.should;
|
||||
import unit_threaded;
|
||||
|
||||
@("BcryptPasswordHasher")
|
||||
@Values("", "test", "langesKompliziertesPasswort")
|
||||
@system unittest
|
||||
{
|
||||
import botan.rng.rng : RandomNumberGenerator;
|
||||
import botan.rng.auto_rng : AutoSeededRNG;
|
||||
auto container = new shared DependencyContainer;
|
||||
container.register!(RandomNumberGenerator, AutoSeededRNG);
|
||||
container.register!(PasswordHasher, BcryptPasswordHasher);
|
||||
|
||||
auto hasher = container.resolve!PasswordHasher;
|
||||
immutable testPassword = getValue!string;
|
||||
hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue;
|
||||
}
|
||||
|
||||
@("StubPasswordHasher")
|
||||
@Values("", "test", "langesKompliziertesPasswort")
|
||||
@safe unittest
|
||||
|
@ -30,3 +14,12 @@ import unit_threaded;
|
|||
immutable testPassword = getValue!string;
|
||||
hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue;
|
||||
}
|
||||
|
||||
@("SHA256PasswordHasher")
|
||||
@Values("", "test", "langesKompliziertesPasswort")
|
||||
@safe unittest
|
||||
{
|
||||
immutable hasher = new SHA256PasswordHasher;
|
||||
immutable testPassword = getValue!string;
|
||||
hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue