added abstraction layer for password hashing
This commit is contained in:
parent
0143b933d5
commit
ec0c7a64b5
4 changed files with 40 additions and 9 deletions
|
@ -1,5 +1,7 @@
|
|||
module calendarwebapp.authenticator;
|
||||
|
||||
import calendarwebapp.passhash : PasswordHasher;
|
||||
|
||||
import poodinis;
|
||||
|
||||
import std.range : InputRange;
|
||||
|
@ -21,6 +23,7 @@ class MongoDBAuthenticator(Collection = MongoCollection) : Authenticator
|
|||
private:
|
||||
@Value("users")
|
||||
Collection users;
|
||||
@Autowire PasswordHasher passwordHasher;
|
||||
|
||||
public:
|
||||
Nullable!AuthInfo checkUser(string username, string password) @safe
|
||||
|
@ -28,13 +31,13 @@ public:
|
|||
import botan.passhash.bcrypt : checkBcrypt;
|
||||
|
||||
auto result = users.findOne(["username" : username]);
|
||||
/* checkBcrypt should be called using vibe.core.concurrency.async to
|
||||
/* checkHash should be called using vibe.core.concurrency.async to
|
||||
avoid blocking, but https://github.com/vibe-d/vibe.d/issues/1521 is
|
||||
blocking this */
|
||||
if (result != Bson(null))
|
||||
{
|
||||
auto authInfo = result.deserializeBson!AuthInfo;
|
||||
if ((()@trusted => checkBcrypt(password, authInfo.passwordHash))())
|
||||
if (passwordHasher.checkHash(password, authInfo.passwordHash))
|
||||
{
|
||||
return authInfo.nullable;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
module calendarwebapp.calendarwebapp;
|
||||
|
||||
import botan.rng.rng : RandomNumberGenerator;
|
||||
|
||||
import calendarwebapp.authenticator;
|
||||
import calendarwebapp.event;
|
||||
import calendarwebapp.passhash : PasswordHasher;
|
||||
|
||||
import core.time : days;
|
||||
|
||||
|
@ -108,12 +107,10 @@ public:
|
|||
}
|
||||
|
||||
@auth(Role.admin) @errorDisplay!getCreateuser void postCreateuser(string username,
|
||||
string password, Privilege role)
|
||||
string password, Privilege role) @safe
|
||||
{
|
||||
import botan.passhash.bcrypt;
|
||||
|
||||
authenticator.addUser(AuthInfo(BsonObjectID.generate, username,
|
||||
generateBcrypt(password, rng, 10), role));
|
||||
passwordHasher.generateHash(password), role));
|
||||
redirect("/users");
|
||||
}
|
||||
|
||||
|
@ -129,5 +126,5 @@ private:
|
|||
|
||||
@Autowire EventStore eventStore;
|
||||
@Autowire Authenticator authenticator;
|
||||
@Autowire RandomNumberGenerator rng;
|
||||
@Autowire PasswordHasher passwordHasher;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ 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 poodinis;
|
||||
|
||||
|
@ -22,6 +23,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!CalendarWebapp;
|
||||
container.register!(ValueInjector!string, StringInjector);
|
||||
|
|
29
source/calendarwebapp/passhash.d
Normal file
29
source/calendarwebapp/passhash.d
Normal file
|
@ -0,0 +1,29 @@
|
|||
module calendarwebapp.passhash;
|
||||
|
||||
import poodinis;
|
||||
|
||||
interface PasswordHasher
|
||||
{
|
||||
string generateHash(in string password) @safe;
|
||||
bool checkHash(in string password, in string hash) @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) @safe
|
||||
{
|
||||
return (()@trusted => checkBcrypt(password, hash))();
|
||||
}
|
||||
|
||||
private:
|
||||
@Autowire RandomNumberGenerator rng;
|
||||
enum cost = 10;
|
||||
}
|
Loading…
Reference in a new issue