Initial work for support for different user roles.
This commit is contained in:
parent
bebb5079c4
commit
4959c67e89
3 changed files with 45 additions and 14 deletions
|
@ -2,11 +2,14 @@ module calendarwebapp.authenticator;
|
|||
|
||||
import poodinis;
|
||||
|
||||
import std.typecons : nullable, Nullable;
|
||||
|
||||
import vibe.data.bson : Bson, BsonObjectID, deserializeBson;
|
||||
import vibe.db.mongo.collection : MongoCollection;
|
||||
|
||||
interface Authenticator
|
||||
{
|
||||
bool checkUser(string username, string password) @safe;
|
||||
Nullable!AuthInfo checkUser(string username, string password) @safe;
|
||||
}
|
||||
|
||||
class MongoDBAuthenticator(Collection = MongoCollection) : Authenticator
|
||||
|
@ -16,21 +19,48 @@ private:
|
|||
Collection users;
|
||||
|
||||
public:
|
||||
bool checkUser(string username, string password) @safe
|
||||
Nullable!AuthInfo checkUser(string username, string password) @safe
|
||||
{
|
||||
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))();
|
||||
if (result != Bson(null))
|
||||
{
|
||||
auto authInfo = result.deserializeBson!AuthInfo;
|
||||
if ((()@trusted => checkBcrypt(password, authInfo.passwordHash))())
|
||||
{
|
||||
return authInfo.nullable;
|
||||
}
|
||||
}
|
||||
return Nullable!AuthInfo();
|
||||
}
|
||||
}
|
||||
|
||||
enum Role
|
||||
{
|
||||
User,
|
||||
Admin
|
||||
}
|
||||
|
||||
struct AuthInfo
|
||||
{
|
||||
string userName;
|
||||
import vibe.data.serialization : name;
|
||||
|
||||
@name("_id") BsonObjectID id;
|
||||
string username;
|
||||
string passwordHash;
|
||||
Role role;
|
||||
|
||||
bool isUser()
|
||||
{
|
||||
return role == Role.User;
|
||||
}
|
||||
|
||||
bool isAdmin()
|
||||
{
|
||||
return role == Role.Admin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,9 +45,9 @@ public:
|
|||
|
||||
@noAuth @errorDisplay!getLogin void postLogin(string username, string password) @safe
|
||||
{
|
||||
enforce(authenticator.checkUser(username, password), "Benutzername oder Passwort ungültig");
|
||||
immutable AuthInfo authInfo = {username};
|
||||
auth = authInfo;
|
||||
auto authInfo = authenticator.checkUser(username, password);
|
||||
enforce(!authInfo.isNull, "Benutzername oder Passwort ungültig");
|
||||
auth = authInfo.get;
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
|
|
|
@ -41,13 +41,14 @@ public:
|
|||
container.register!(Authenticator, MongoDBAuthenticator!(Collection))(
|
||||
RegistrationOption.doNotAddConcreteTypeRegistration);
|
||||
|
||||
auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")), "username" : Bson("foo"),
|
||||
"password" : Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO")]);
|
||||
auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")),
|
||||
"username" : Bson("foo"), "passwordHash"
|
||||
: Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO"), "role" : Bson(1)]);
|
||||
|
||||
collection.returnValue!"findOne"(Bson(null), userBson, userBson);
|
||||
|
||||
auto authenticator = container.resolve!(Authenticator);
|
||||
authenticator.checkUser("", "").shouldBeFalse;
|
||||
authenticator.checkUser("foo", "bar").shouldBeTrue;
|
||||
authenticator.checkUser("foo", "baz").shouldBeFalse;
|
||||
authenticator.checkUser("", "").isNull.shouldBeTrue;
|
||||
authenticator.checkUser("foo", "bar").isNull.shouldBeFalse;
|
||||
authenticator.checkUser("foo", "baz").isNull.shouldBeTrue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue