Only show menu when authenticated and only show user management when logged in as admin

This commit is contained in:
Johannes Loher 2017-10-27 18:03:55 +02:00
parent dafb065eb3
commit 0143b933d5
6 changed files with 65 additions and 41 deletions

View file

@ -64,8 +64,9 @@ public:
} }
} }
enum Role enum Privilege
{ {
None,
User, User,
Admin Admin
} }
@ -77,7 +78,7 @@ struct AuthInfo
@name("_id") BsonObjectID id; @name("_id") BsonObjectID id;
string username; string username;
string passwordHash; string passwordHash;
Role role; Privilege privilege;
mixin(generateAuthMethods); mixin(generateAuthMethods);
@ -89,12 +90,12 @@ private:
import std.traits : EnumMembers; import std.traits : EnumMembers;
string ret; string ret;
foreach (member; EnumMembers!Role) foreach (member; EnumMembers!Privilege)
{ {
ret ~= q{ ret ~= q{
bool is%s() const pure @safe nothrow bool is%s() const pure @safe nothrow
{ {
return role == Role.%s; return privilege == Privilege.%s;
} }
}.format(member.to!string, member.to!string); }.format(member.to!string, member.to!string);
} }

View file

@ -2,7 +2,7 @@ module calendarwebapp.calendarwebapp;
import botan.rng.rng : RandomNumberGenerator; import botan.rng.rng : RandomNumberGenerator;
import calendarwebapp.authenticator : Authenticator, AuthInfo, Privilege = Role; import calendarwebapp.authenticator;
import calendarwebapp.event; import calendarwebapp.event;
import core.time : days; import core.time : days;
@ -25,24 +25,24 @@ import vibe.web.web : errorDisplay, noRoute, redirect, render, SessionVar,
{ {
@noRoute AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse) @safe @noRoute AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse) @safe
{ {
if (!req.session || !req.session.isKeySet("authInfo")) if (authInfo.value.isNone)
{
redirect("/login"); redirect("/login");
return AuthInfo.init;
} return authInfo.value;
return req.session.get!AuthInfo("authInfo");
} }
public: public:
@anyAuth void index() @auth(Role.user | Role.admin) void index()
{ {
auto events = eventStore.getAllEvents(); auto events = eventStore.getAllEvents();
render!("showevents.dt", events); auto authInfo = this.authInfo.value;
render!("showevents.dt", events, authInfo);
} }
@noAuth void getLogin(string _error = null) @noAuth void getLogin(string _error = null)
{ {
render!("login.dt", _error); auto authInfo = this.authInfo.value;
render!("login.dt", _error, authInfo);
} }
@noAuth @errorDisplay!getLogin void postLogin(string username, string password) @safe @noAuth @errorDisplay!getLogin void postLogin(string username, string password) @safe
@ -53,18 +53,20 @@ public:
redirect("/"); redirect("/");
} }
@anyAuth void getLogout() @safe @auth(Role.user | Role.admin) void getLogout() @safe
{ {
terminateSession(); terminateSession();
redirect("/"); redirect("/");
} }
@anyAuth void getCreateevent(ValidationErrorData _error = ValidationErrorData.init) @auth(Role.user | Role.admin) void getCreateevent(
ValidationErrorData _error = ValidationErrorData.init)
{ {
render!("createevent.dt", _error); auto authInfo = this.authInfo.value;
render!("createevent.dt", _error, authInfo);
} }
@anyAuth @errorDisplay!getCreateevent void postCreateevent(Date begin, @auth(Role.user | Role.admin) @errorDisplay!getCreateevent void postCreateevent(Date begin,
Nullable!Date end, string description, string name, EventType type, bool shout) @safe Nullable!Date end, string description, string name, EventType type, bool shout) @safe
{ {
import std.array : replace, split; import std.array : replace, split;
@ -80,7 +82,7 @@ public:
redirect("/"); redirect("/");
} }
@anyAuth void postRemoveevent(BsonObjectID id) @safe @auth(Role.user | Role.admin) void postRemoveevent(BsonObjectID id) @safe
{ {
eventStore.removeEvent(id); eventStore.removeEvent(id);
redirect("/"); redirect("/");
@ -89,7 +91,8 @@ public:
@auth(Role.admin) void getUsers() @auth(Role.admin) void getUsers()
{ {
auto users = authenticator.getAllUsers; auto users = authenticator.getAllUsers;
render!("showusers.dt", users); auto authInfo = this.authInfo.value;
render!("showusers.dt", users, authInfo);
} }
@auth(Role.admin) void postRemoveuser(BsonObjectID id) @safe @auth(Role.admin) void postRemoveuser(BsonObjectID id) @safe
@ -100,7 +103,8 @@ public:
@auth(Role.admin) void getCreateuser(ValidationErrorData _error = ValidationErrorData.init) @auth(Role.admin) void getCreateuser(ValidationErrorData _error = ValidationErrorData.init)
{ {
render!("createuser.dt", _error); auto authInfo = this.authInfo.value;
render!("createuser.dt", _error, authInfo);
} }
@auth(Role.admin) @errorDisplay!getCreateuser void postCreateuser(string username, @auth(Role.admin) @errorDisplay!getCreateuser void postCreateuser(string username,
@ -120,7 +124,8 @@ private:
string field; string field;
} }
SessionVar!(AuthInfo, "authInfo") authInfo; SessionVar!(AuthInfo, "authInfo") authInfo = AuthInfo(BsonObjectID.init,
string.init, string.init, Privilege.None);
@Autowire EventStore eventStore; @Autowire EventStore eventStore;
@Autowire Authenticator authenticator; @Autowire Authenticator authenticator;

View file

@ -46,7 +46,7 @@ public:
auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")), auto userBson = Bson(["_id" : Bson(BsonObjectID.fromString("5988ef4ae6c19089a1a53b79")),
"username" : Bson("foo"), "passwordHash" "username" : Bson("foo"), "passwordHash"
: Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO"), "role" : Bson(1)]); : Bson("$2a$10$9LBqOZV99ARiE4Nx.2b7GeYfqk2.0A32PWGu2cRGyW2hRJ0xeDfnO"), "privilege" : Bson(1)]);
collection.returnValue!"findOne"(Bson(null), userBson, userBson); collection.returnValue!"findOne"(Bson(null), userBson, userBson);
@ -60,7 +60,7 @@ public:
@safe unittest @safe unittest
{ {
AuthInfo auth; AuthInfo auth;
auth.role = Role.User; auth.privilege = Privilege.User;
auth.isUser.shouldBeTrue; auth.isUser.shouldBeTrue;
} }
@ -68,7 +68,7 @@ public:
@safe unittest @safe unittest
{ {
AuthInfo auth; AuthInfo auth;
auth.role = Role.Admin; auth.privilege = Privilege.None;
auth.isUser.shouldBeFalse; auth.isUser.shouldBeFalse;
} }
@ -76,7 +76,7 @@ public:
@safe unittest @safe unittest
{ {
AuthInfo auth; AuthInfo auth;
auth.role = Role.Admin; auth.privilege = Privilege.Admin;
auth.isAdmin.shouldBeTrue; auth.isAdmin.shouldBeTrue;
} }
@ -84,6 +84,22 @@ public:
@safe unittest @safe unittest
{ {
AuthInfo auth; AuthInfo auth;
auth.role = Role.User; auth.privilege = Privilege.None;
auth.isAdmin.shouldBeFalse; auth.isAdmin.shouldBeFalse;
} }
@("AuthInfo.isNone success")
@safe unittest
{
AuthInfo auth;
auth.privilege = Privilege.None;
auth.isNone.shouldBeTrue;
}
@("AuthInfo.isNone failure")
@safe unittest
{
AuthInfo auth;
auth.privilege = Privilege.User;
auth.isNone.shouldBeFalse;
}

View file

@ -29,4 +29,4 @@ block content
tfoot tfoot
tr tr
td(colspan="2") td(colspan="2")
input#submitButton(type="submit", value="Ereignis erstellen") input#submitButton(type="submit", value="Benutzer erstellen")

View file

@ -1,12 +1,14 @@
nav - if(!authInfo.isNone())
ul nav
li ul
a(href='/') Home li
li a(href='/') Home
a(href='/createevent') Ereignis erstellen li
li a(href='/createevent') Ereignis erstellen
a(href='/users') Benutzerliste - if(authInfo.isAdmin())
li li
a(href='/createuser') Benutzer erstellen a(href='/users') Benutzerliste
li li
a(href='/logout') Ausloggen a(href='/createuser') Benutzer erstellen
li
a(href='/logout') Ausloggen

View file

@ -10,8 +10,8 @@ block content
td username td username
td #{user.username} td #{user.username}
tr tr
td role td privilege
td #{user.role} td #{user.privilege}
form(action="/removeuser", method="post") form(action="/removeuser", method="post")
input#id(value="#{user.id}", name="id", type="hidden") input#id(value="#{user.id}", name="id", type="hidden")
input#submitButton(type="submit", value="Entfernen") input#submitButton(type="submit", value="Entfernen")