commit 9d4d0b357b18093737927460423b06ff785242b7
parent 334c3728d0e769f0a79a65c32eb03e3590335f24
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Tue, 5 Mar 2024 23:58:39 -0800
Take login process out of pages
Now loadpagerequest() is called to setup the pagedata struct, and
it contains a pointer to a struct for the logged in user (or NULL).
This really takes a load off of every page making things a lot more
simple.
Diffstat:
11 files changed, 61 insertions(+), 50 deletions(-)
diff --git a/page.c b/page.c
@@ -1,3 +1,5 @@
+#define const
+
#include <sys/types.h>
#include <stdarg.h>
#include <stddef.h>
@@ -5,7 +7,35 @@
#include <kcgi.h>
#include <kcgihtml.h>
+#include "user.h"
#include "page.h"
+#include "key.h"
+
+enum kcgi_err
+loadpagerequest(struct kfcgi *fcgi, struct pagedata *pd)
+{
+ enum kcgi_err status;
+
+ status = khttp_fcgi_parse(fcgi, &pd->req);
+ if (status != KCGI_OK)
+ return status;
+
+ pd->user = NULL;
+ if (!pd->req.cookiemap[KeyHash])
+ return KCGI_OK;
+
+ pd->user = getuser(pd, "hash", pd->req.cookiemap[KeyHash]->parsed.s);
+ /* propagate errors from getuser to here and handle them */
+
+ return KCGI_OK;
+}
+
+void
+freepagerequest(struct pagedata *pd)
+{
+ freeuser(pd->user);
+ khttp_free(&pd->req);
+}
enum kcgi_err
showpage(struct pagedata *pd, char **names,
@@ -23,7 +53,6 @@ showpage(struct pagedata *pd, char **names,
names[(pd->req.page == len ? (len - 1) : pd->req.page)],
status);
}
- khttp_free(&pd->req);
return status;
}
diff --git a/page.h b/page.h
@@ -1,3 +1,5 @@
+struct user;
+
struct pagedata {
struct kreq req;
struct khtmlreq html;
@@ -5,7 +7,10 @@ struct pagedata {
size_t dbid;
struct kvalid *keys;
char **pages; /* page names */
+ struct user *user;
};
+enum kcgi_err loadpagerequest(struct kfcgi *fcgi, struct pagedata *pd);
+void freepagerequest(struct pagedata *pd);
enum kcgi_err showpage(struct pagedata *pd, char **names,
enum kcgi_err (*functions[])(struct pagedata *), size_t len);
diff --git a/pages/account.c b/pages/account.c
@@ -7,14 +7,12 @@ enum kcgi_err
pageaccount(struct pagedata *pd)
{
enum kcgi_err status;
- struct user *user;
- user = sitegetlogin(pd);
- if (!user)
+ if (!pd->user)
return errorpage(pd, KHTTP_401);
if (pd->req.fieldmap[KeyDelete] && strcmp(pd->req.fieldmap[KeyDelete]->parsed.s, "yes") == 0) {
- if (deleteuser(pd, user->hash) == 0)
+ if (deleteuser(pd, pd->user->hash) == 0)
return redirect(pd, pd->pages[PageIndex], "Account deleted");
else
return errorpage(pd, KHTTP_500);
@@ -40,11 +38,8 @@ pageaccount(struct pagedata *pd)
KATTR_TYPE, "submit",
KATTR_VALUE, "Delete",
KATTR__MAX)) != KCGI_OK ||
- (status = khtml_closeelem(&pd->html, 1)) != KCGI_OK) {
- freeuser(user);
+ (status = khtml_closeelem(&pd->html, 1)) != KCGI_OK)
return status;
- }
- freeuser(user);
return khtml_close(&pd->html);
}
diff --git a/pages/index.c b/pages/index.c
@@ -6,22 +6,19 @@ enum kcgi_err
pageindex(struct pagedata *pd)
{
enum kcgi_err status;
- struct user *user;
-
- user = sitegetlogin(pd);
if ((status = starthtmldoc(pd, KHTTP_200)) != KCGI_OK)
return status;
khtml_elem(&pd->html, KELEM_H1);
- khtml_printf(&pd->html, "Welcome %s!", user ? user->name : "friend");
+ khtml_printf(&pd->html, "Welcome %s!", pd->user ? pd->user->name : "friend");
khtml_closeelem(&pd->html, 1);
- if ((status = htmllink(pd, user ? "/logout" : "/login",
- user ? "Logout" : "Login")) != KCGI_OK)
+ if ((status = htmllink(pd, pd->user ? "/logout" : "/login",
+ pd->user ? "Logout" : "Login")) != KCGI_OK)
return status;
- if (user) {
+ if (pd->user) {
if ((status = khtml_puts(&pd->html, " | ")) != KCGI_OK ||
(status = htmllink(pd, pd->pages[PageAccount], "Manage account")))
return status;
diff --git a/pages/login.c b/pages/login.c
@@ -33,12 +33,14 @@ enum kcgi_err
pagelogin(struct pagedata *pd)
{
enum kcgi_err status;
- struct user *user;
+ struct user *user = NULL;
char *fuser, *fpass;
enum LoginStatus ls;
char *msg;
- user = NULL;
+ if (pd->user)
+ return redirect(pd, pd->pages[PageIndex], "Logged in");
+
ls = LoginUntried;
if (pd->req.fieldmap[KeyUsername] && pd->req.fieldmap[KeyPassword]) {
fuser = pd->req.fieldmap[KeyUsername]->parsed.s;
@@ -54,17 +56,14 @@ pagelogin(struct pagedata *pd)
if (ls == LoginValid) {
status = khttp_head(&pd->req, kresps[KRESP_SET_COOKIE], "%s=%s; Path=/",
pd->keys[KeyHash].name, user->hash);
+ freeuser(user);
if (status != KCGI_OK)
return status;
+ return redirect(pd, pd->pages[PageIndex], "Logged in");
}
}
- } else {
- user = sitegetlogin(pd);
}
- if (user)
- return redirect(pd, pd->pages[PageIndex], "Logged in");
-
if ((status = starthtmldoc(pd, KHTTP_200)) != KCGI_OK)
return status;
diff --git a/pages/logout.c b/pages/logout.c
@@ -1,19 +1,16 @@
#include "common.h"
-
#include "pages.h"
enum kcgi_err
pagelogout(struct pagedata *pd)
{
enum kcgi_err status;
- struct user *user;
- if ((user = sitegetlogin(pd))) {
- freeuser(user);
- if ((status = khttp_head(&pd->req, kresps[KRESP_SET_COOKIE],
- "%s=; Path=/", pd->keys[KeyHash].name)) != KCGI_OK)
- return status;
- }
+ if (!pd->user)
+ return errorpage(pd, KHTTP_500);
+ if ((status = khttp_head(&pd->req, kresps[KRESP_SET_COOKIE],
+ "%s=; Path=/", pd->keys[KeyHash].name)) != KCGI_OK)
+ return status;
return redirect(pd, pd->pages[PageIndex], "You are being logged out");
}
diff --git a/pages/main.c b/pages/main.c
@@ -246,22 +246,20 @@ enum kcgi_err
pagemain(struct pagedata *pd)
{
enum kcgi_err status;
- struct user *user;
enum time_field tf;
time_t *times;
size_t ntimes;
- user = sitegetlogin(pd);
- if (!user)
+ if (!pd->user)
return errorpage(pd, KHTTP_401);
if (pd->req.fieldmap[KeyTime]) {
tf = gettf(pd->req.fieldmap[KeyTime]->parsed.s);
if (tf < 0)
err(1, "Invalid time field");
- if (tf == StartTime && newrow(pd, user->hash) != SQLBOX_CODE_OK)
+ if (tf == StartTime && newrow(pd, pd->user->hash) != SQLBOX_CODE_OK)
err(1, "New time");
- if (settime(pd, user->hash, tf, time(NULL)))
+ if (settime(pd, pd->user->hash, tf, time(NULL)))
return KCGI_SYSTEM;
}
@@ -269,7 +267,7 @@ pagemain(struct pagedata *pd)
if (status != KCGI_OK)
return status;
- times = gettimes(pd, user->hash, &ntimes);
+ times = gettimes(pd, pd->user->hash, &ntimes);
if (!times)
err(1, "gettimes");
@@ -280,6 +278,5 @@ pagemain(struct pagedata *pd)
}
free(times);
- freeuser(user);
return khtml_close(&pd->html);
}
diff --git a/pages/util.c b/pages/util.c
@@ -8,7 +8,6 @@
#include <kcgihtml.h>
#include "../page.h"
-#include "../user.h"
#include "../key.h"
enum kcgi_err
@@ -69,12 +68,3 @@ redirect(struct pagedata *pd, char *to, char *msg)
return status;
return khtml_close(&pd->html);
}
-
-/* getlogin is taken */
-struct user *
-sitegetlogin(struct pagedata *pd)
-{
- if (!pd->req.cookiemap[KeyHash])
- return NULL;
- return getuser(pd, "hash", pd->req.cookiemap[KeyHash]->parsed.s);
-}
diff --git a/pages/util.h b/pages/util.h
@@ -1,4 +1,3 @@
enum kcgi_err errorpage(struct pagedata *pd, enum khttp code);
enum kcgi_err starthtmldoc(struct pagedata *pd, enum khttp code);
enum kcgi_err redirect(struct pagedata *pd, char *to, char *msg);
-struct user *sitegetlogin(struct pagedata *pd);
diff --git a/timekeeper.c b/timekeeper.c
@@ -92,9 +92,10 @@ main(void)
err(1, "Unable to setup database");
status = KCGI_OK;
- while ((status = khttp_fcgi_parse(fcgi, &pd.req)) == KCGI_OK) {
+ while (loadpagerequest(fcgi, &pd) == KCGI_OK) {
/* Ignore return value */
showpage(&pd, pages, pagefunctions, Len(pages));
+ freepagerequest(&pd);
}
sqlbox_free(pd.db);
diff --git a/user.h b/user.h
@@ -15,6 +15,8 @@ struct user {
char *hash;
};
+struct pagedata;
+
int adduser(struct pagedata *pd, char *name, char *key);
void freeuser(struct user *user);
struct user *getuser(struct pagedata *pd, char *field, char *value);