Added simple authentication and split source files
This commit is contained in:
parent
3af4f2fde9
commit
c509a166d8
4 changed files with 147 additions and 87 deletions
89
source/app.d
89
source/app.d
|
@ -1,92 +1,6 @@
|
||||||
import std.datetime.date;
|
import calendarwebapp;
|
||||||
import std.typecons : Nullable;
|
|
||||||
|
|
||||||
import vibe.vibe;
|
import vibe.vibe;
|
||||||
|
|
||||||
class CalendarWebapp
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
immutable fileName = Path("events.json");
|
|
||||||
|
|
||||||
enum EventType
|
|
||||||
{
|
|
||||||
Holiday,
|
|
||||||
Birthday,
|
|
||||||
FSI_Event,
|
|
||||||
General_University_Event,
|
|
||||||
Any
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Entry
|
|
||||||
{
|
|
||||||
@name("date") Date begin;
|
|
||||||
@name("end_date") Nullable!Date end;
|
|
||||||
Event event;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Event
|
|
||||||
{
|
|
||||||
@(vibe.data.serialization.name("eid")) string id;
|
|
||||||
string name;
|
|
||||||
@(vibe.data.serialization.name("desc")) string[] description;
|
|
||||||
@(vibe.data.serialization.name("etype")) EventType type;
|
|
||||||
bool shout;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry[] getEventsFromFile(in Path fileName)
|
|
||||||
{
|
|
||||||
Entry[] entries;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto entriesString = readFileUTF8(fileName);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
deserializeJson(entries, entriesString.parseJsonString);
|
|
||||||
}
|
|
||||||
catch (std.json.JSONException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{}
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
@method(HTTPMethod.POST) @path("/event/create")
|
|
||||||
void createEvent(Date begin, Nullable!Date end, string description,
|
|
||||||
string name, EventType type, bool shout)
|
|
||||||
{
|
|
||||||
import std.array : split, replace;
|
|
||||||
|
|
||||||
if (!end.isNull)
|
|
||||||
enforce(end - begin >= 1.days);
|
|
||||||
|
|
||||||
auto entry = Entry(begin, end, Event("", name,
|
|
||||||
description.replace("\r", "").split('\n'), type, shout));
|
|
||||||
|
|
||||||
auto entries = getEventsFromFile(fileName);
|
|
||||||
entries ~= entry;
|
|
||||||
writeFileUTF8(fileName, serializeToPrettyJson(entries));
|
|
||||||
render!("showevents.dt", entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
@method(HTTPMethod.GET) @path("create")
|
|
||||||
void newEvent()
|
|
||||||
{
|
|
||||||
render!("create.dt");
|
|
||||||
}
|
|
||||||
|
|
||||||
void index()
|
|
||||||
{
|
|
||||||
auto entries = getEventsFromFile(fileName);
|
|
||||||
render!("showevents.dt", entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
shared static this()
|
shared static this()
|
||||||
{
|
{
|
||||||
auto router = new URLRouter;
|
auto router = new URLRouter;
|
||||||
|
@ -95,6 +9,7 @@ shared static this()
|
||||||
auto settings = new HTTPServerSettings;
|
auto settings = new HTTPServerSettings;
|
||||||
settings.port = 8080;
|
settings.port = 8080;
|
||||||
settings.bindAddresses = ["::1", "127.0.0.1"];
|
settings.bindAddresses = ["::1", "127.0.0.1"];
|
||||||
|
settings.sessionStore = new MemorySessionStore;
|
||||||
listenHTTP(settings, router);
|
listenHTTP(settings, router);
|
||||||
|
|
||||||
logInfo("Please open http://127.0.0.1:8080/ in your browser.");
|
logInfo("Please open http://127.0.0.1:8080/ in your browser.");
|
||||||
|
|
93
source/calendarwebapp.d
Normal file
93
source/calendarwebapp.d
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
module calendarwebapp;
|
||||||
|
|
||||||
|
import event;
|
||||||
|
|
||||||
|
import std.datetime.date;
|
||||||
|
import std.typecons : Nullable;
|
||||||
|
|
||||||
|
import vibe.vibe;
|
||||||
|
|
||||||
|
class CalendarWebapp
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
enum auth = before!ensureAuth("userName");
|
||||||
|
|
||||||
|
immutable fileName = Path("events.json");
|
||||||
|
|
||||||
|
struct UserData
|
||||||
|
{
|
||||||
|
bool loggedIn;
|
||||||
|
string name;
|
||||||
|
string uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionVar!(UserData, "user") user;
|
||||||
|
|
||||||
|
Entry[] getEntriesFromFile(in Path fileName)
|
||||||
|
{
|
||||||
|
Entry[] entries;
|
||||||
|
if (fileName.existsFile)
|
||||||
|
{
|
||||||
|
deserializeJson(entries, fileName.readFileUTF8.parseJsonString);
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ensureAuth(HTTPServerRequest req, HTTPServerResponse res)
|
||||||
|
{
|
||||||
|
if (!user.loggedIn)
|
||||||
|
redirect("/login");
|
||||||
|
return user.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin PrivateAccessProxy;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
@auth @method(HTTPMethod.POST) @path("/event/create")
|
||||||
|
void createEvent(Date begin, Nullable!Date end, string description,
|
||||||
|
string name, EventType type, bool shout, string userName)
|
||||||
|
{
|
||||||
|
import std.array : split, replace;
|
||||||
|
|
||||||
|
if (!end.isNull)
|
||||||
|
enforce(end - begin >= 1.days);
|
||||||
|
|
||||||
|
auto entry = Entry(begin, end, Event("", name,
|
||||||
|
description.replace("\r", "").split('\n'), type, shout));
|
||||||
|
|
||||||
|
auto entries = getEntriesFromFile(fileName) ~ entry;
|
||||||
|
fileName.writeFileUTF8(entries.serializeToPrettyJson);
|
||||||
|
render!("showevents.dt", entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@auth @method(HTTPMethod.GET) @path("create")
|
||||||
|
void newEvent(string userName)
|
||||||
|
{
|
||||||
|
render!("create.dt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@auth void index(string userName)
|
||||||
|
{
|
||||||
|
auto entries = getEntriesFromFile(fileName);
|
||||||
|
render!("showevents.dt", entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getLogin()
|
||||||
|
{
|
||||||
|
render!("login.dt");
|
||||||
|
}
|
||||||
|
|
||||||
|
void postLogin(string username, string password)
|
||||||
|
{
|
||||||
|
import std.uuid : randomUUID;
|
||||||
|
|
||||||
|
enforce(username == "foo" && password == "bar", "Invalid username / password");
|
||||||
|
UserData d;
|
||||||
|
d.loggedIn = true;
|
||||||
|
d.name = username;
|
||||||
|
d.uuid = randomUUID.toString;
|
||||||
|
user = d;
|
||||||
|
redirect("/");
|
||||||
|
}
|
||||||
|
}
|
31
source/event.d
Normal file
31
source/event.d
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
module event;
|
||||||
|
|
||||||
|
import std.datetime.date;
|
||||||
|
import std.typecons : Nullable;
|
||||||
|
|
||||||
|
import vibe.data.serialization;
|
||||||
|
|
||||||
|
enum EventType
|
||||||
|
{
|
||||||
|
Holiday,
|
||||||
|
Birthday,
|
||||||
|
FSI_Event,
|
||||||
|
General_University_Event,
|
||||||
|
Any
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
@name("date") Date begin;
|
||||||
|
@name("end_date") Nullable!Date end;
|
||||||
|
Event event;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
@(vibe.data.serialization.name("eid")) string id;
|
||||||
|
string name;
|
||||||
|
@(vibe.data.serialization.name("desc")) string[] description;
|
||||||
|
@(vibe.data.serialization.name("etype")) EventType type;
|
||||||
|
bool shout;
|
||||||
|
}
|
21
views/login.dt
Normal file
21
views/login.dt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
extends layout
|
||||||
|
block content
|
||||||
|
h1 Anmelden
|
||||||
|
form(action="/login", method="post")
|
||||||
|
fieldset(name="loginFields")
|
||||||
|
table
|
||||||
|
tbody#fieldTable
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
label(for="username") Benutzername
|
||||||
|
td
|
||||||
|
input#username(value="", name="username", type="text")
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
label(for="password") Passwort
|
||||||
|
td
|
||||||
|
input#password(value="", name="password", type="password")
|
||||||
|
tfoot
|
||||||
|
tr
|
||||||
|
td(colspan="2")
|
||||||
|
input#submitButton(type="submit", value="Anmelden")
|
Loading…
Reference in a new issue