hlfw.ca

webbing

Download patch

ref: 8ab5d39abc4297d008d438dde3adddd21575df36
parent: cceb70f7849948ee9a2972899ae4cfd1cb8daec5
author: Halfwit <halfwit@MacBook-Pro.hitronhub.home>
date: Thu Dec 12 12:07:17 PST 2019

Organize code a bit

--- a/router/forms.go
+++ b/router/forms.go
@@ -4,6 +4,7 @@
 	"fmt"
 	"net/http"
 
+	"github.com/olmaxmedical/olmax_go/session"
 	"golang.org/x/text/message"
 )
 
@@ -46,4 +47,20 @@
 		}
 	}
 	return form, errors
+}
+
+func postform(p *Request, us session.Session, w http.ResponseWriter, r *http.Request) {
+	form, errors := parseform(p, w, r)
+	if len(errors) > 0 && errors[0] != "nil" {
+		// NOTE(halfwit) this stashes previous entries, but does not work
+		// on multipart forms (with file uploads)
+		us.Set("errors", errors)
+		// Maybe store form args instead here in session
+		url := fmt.Sprintf("%s?%s", r.URL.String(), r.Form.Encode())
+		http.Redirect(w, r, url, 302)
+	}
+	if form != nil {
+		us.Set("errors", []string{})
+		http.Redirect(w, r, form.Redirect, 302)
+	}
 }
--- /dev/null
+++ b/router/handler.go
@@ -1,0 +1,121 @@
+package router
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/olmaxmedical/olmax_go/db"
+	"github.com/olmaxmedical/olmax_go/email"
+	"github.com/olmaxmedical/olmax_go/session"
+)
+
+// Handle specific endpoints
+
+type handler struct {
+	manager *session.Manager
+}
+
+func (d *handler) logout(w http.ResponseWriter, r *http.Request) {
+	d.manager.Destroy(w, r)
+	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
+	http.Redirect(w, r, "/index.html", 302)
+}
+
+func (d *handler) normal(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
+	if r.URL.Path == "/" {
+		http.Redirect(w, r, "/index.html", 302)
+		return
+	}
+	user, status, us, role := getUser(d, w, r)
+	p := &Request{
+		printer: userLang(r),
+		status:  status,
+		request: r,
+		user:    user,
+		role:    role,
+		session: us,
+		path:    r.URL.Path[1:],
+	}
+
+	switch r.Method {
+	case "GET":
+		getpage(p, w)
+	case "POST":
+		postform(p, us, w, r)
+	}
+}
+
+// TODO: This will require actual client data from the database to populate the page
+func (d *handler) profile(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
+	user, status, us, role := getUser(d, w, r)
+	if status == "false" {
+		http.Redirect(w, r, "/login.html", 302)
+		return
+	}
+	if rd, ok := us.Get("redirect").(string); ok {
+		us.Delete("redirect")
+		http.Redirect(w, r, "/"+rd, 302)
+		return
+	}
+	p := &Request{
+		printer: userLang(r),
+		status:  status,
+		session: us,
+		user:    user,
+		role:    role,
+	}
+	var data []byte
+	var err error
+	switch db.UserRole(user) {
+	case db.DoctorAuth:
+		if role != db.DoctorAuth {
+			http.Error(w, "Unauthorized", 401)
+			return
+		}
+		p.path = "doctor/profile.html"
+		data, err = getdata(p, "doctor")
+	case db.PatientAuth:
+		if role != db.PatientAuth {
+			http.Error(w, "Unauthorized", 401)
+			return
+		}
+		p.path = "patient/profile.html"
+		data, err = getdata(p, "patient")
+	default:
+		http.Error(w, "Forbidden", 403)
+		return
+	}
+	if err != nil {
+		http.Error(w, "Service Unavailable", 503)
+		return
+	}
+	fmt.Fprintf(w, "%s", data)
+}
+
+func (d *handler) activate(w http.ResponseWriter, r *http.Request) {
+	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
+	if len(r.URL.Path) != 46 && r.URL.Path[:9] != "/activate" {
+		http.Error(w, "Bad Request", 400)
+		return
+	}
+	email.ValidateSignupToken(w, r, r.URL.Path[10:])
+}
+
+func (d *handler) reset(w http.ResponseWriter, r *http.Request) {
+	if len(r.URL.Path) != 43 && r.URL.Path[:6] != "/reset" {
+		http.Error(w, "Bad Request", 400)
+		return
+	}
+	p := userLang(r)
+	user, _, us, _ := getUser(d, w, r)
+	token := email.NextResetToken(r.URL.Path[7:], user)
+	if token == "" {
+		us.Set("errors", [1]string{p.Sprint("Token expired")})
+		return
+	}
+	us.Set("token", token)
+	r.URL.Path = "/newpassword.html"
+	d.normal(w, r)
+}
--- a/router/pages.go
+++ b/router/pages.go
@@ -6,6 +6,7 @@
 	"errors"
 	"fmt"
 	"html/template"
+	"net/http"
 	"os"
 	"path"
 	"strings"
@@ -87,6 +88,29 @@
 		}
 	}
 	return errs
+}
+
+func getpage(p *Request, w http.ResponseWriter) {
+	var data []byte
+	var err error
+	switch db.UserRole(p.user) {
+	case db.DoctorAuth:
+		data, err = getdata(p, "doctor")
+	case db.PatientAuth:
+		data, err = getdata(p, "patient")
+	default:
+		data, err = getdata(p, "guest")
+	}
+	if err != nil && err.Error() == "Unauthorized" {
+		p.Session().Set("redirect", p.path)
+		http.Redirect(w, p.Request(), "/login.html", 302)
+		return
+	}
+	if err != nil {
+		http.Error(w, "Service Unavailable", 503)
+		return
+	}
+	fmt.Fprintf(w, "%s", data)
 }
 
 func getdata(p *Request, in string) ([]byte, error) {
--- a/router/run.go
+++ b/router/run.go
@@ -2,22 +2,16 @@
 
 import (
 	"crypto/tls"
-	"fmt"
 	"net/http"
 
 	"github.com/olmaxmedical/olmax_go/db"
-	"github.com/olmaxmedical/olmax_go/email"
 	"github.com/olmaxmedical/olmax_go/session"
 	"golang.org/x/text/message"
 )
 
-type handle struct {
-	manager *session.Manager
-}
-
 // Route - All requests pass through here first
 func Route(manager *session.Manager) error {
-	d := &handle{
+	d := &handler{
 		manager: manager,
 	}
 	css := http.FileServer(http.Dir("resources/css/"))
@@ -42,102 +36,7 @@
 	return srv.ListenAndServeTLS("cert.pem", "key.pem")
 }
 
-func (d *handle) activate(w http.ResponseWriter, r *http.Request) {
-	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
-	if len(r.URL.Path) != 46 && r.URL.Path[:9] != "/activate" {
-		http.Error(w, "Bad Request", 400)
-		return
-	}
-	email.ValidateSignupToken(w, r, r.URL.Path[10:])
-}
-
-func (d *handle) reset(w http.ResponseWriter, r *http.Request) {
-	if len(r.URL.Path) != 43 && r.URL.Path[:6] != "/reset" {
-		http.Error(w, "Bad Request", 400)
-		return
-	}
-	p := userLang(r)
-	user, _, us, _ := getUser(d, w, r)
-	token := email.NextResetToken(r.URL.Path[7:], user)
-	if token == "" {
-		us.Set("errors", [1]string{p.Sprint("Token expired")})
-		return
-	}
-	us.Set("token", token)
-	r.URL.Path = "/newpassword.html"
-	d.normal(w, r)
-}
-
-func (d *handle) normal(w http.ResponseWriter, r *http.Request) {
-	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
-	if r.URL.Path == "/" {
-		http.Redirect(w, r, "/index.html", 302)
-		return
-	}
-	user, status, us, role := getUser(d, w, r)
-	p := &Request{
-		printer: userLang(r),
-		status:  status,
-		request: r,
-		user:    user,
-		role:    role,
-		session: us,
-		path:    r.URL.Path[1:],
-	}
-
-	switch r.Method {
-	case "GET":
-		get(p, w)
-	case "POST":
-		post(p, us, w, r)
-	}
-}
-
-func (d *handle) logout(w http.ResponseWriter, r *http.Request) {
-	d.manager.Destroy(w, r)
-	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
-	http.Redirect(w, r, "/index.html", 302)
-}
-
-func post(p *Request, us session.Session, w http.ResponseWriter, r *http.Request) {
-	form, errors := parseform(p, w, r)
-	if len(errors) > 0 && errors[0] != "nil" {
-		// NOTE(halfwit) this stashes previous entries, but does not work
-		// on multipart forms (with file uploads)
-		us.Set("errors", errors)
-		// Maybe store form args instead here in session
-		url := fmt.Sprintf("%s?%s", r.URL.String(), r.Form.Encode())
-		http.Redirect(w, r, url, 302)
-	}
-	if form != nil {
-		us.Set("errors", []string{})
-		http.Redirect(w, r, form.Redirect, 302)
-	}
-}
-
-func get(p *Request, w http.ResponseWriter) {
-	var data []byte
-	var err error
-	switch db.UserRole(p.user) {
-	case db.DoctorAuth:
-		data, err = getdata(p, "doctor")
-	case db.PatientAuth:
-		data, err = getdata(p, "patient")
-	default:
-		data, err = getdata(p, "guest")
-	}
-	if err != nil && err.Error() == "Unauthorized" {
-		p.Session().Set("redirect", p.path)
-		http.Redirect(w, p.Request(), "/login.html", 302)
-		return
-	}
-	if err != nil {
-		http.Error(w, "Service Unavailable", 503)
-		return
-	}
-	fmt.Fprintf(w, "%s", data)
-}
-
+// Some utility functions that are shared across pages and forms
 func userLang(r *http.Request) *message.Printer {
 	accept := r.Header.Get("Accept-Language")
 	lang := r.FormValue("lang")
@@ -145,7 +44,7 @@
 	return message.NewPrinter(tag)
 }
 
-func getUser(d *handle, w http.ResponseWriter, r *http.Request) (string, string, session.Session, db.Access) {
+func getUser(d *handler, w http.ResponseWriter, r *http.Request) (string, string, session.Session, db.Access) {
 	us := d.manager.Start(w, r)
 	user, ok1 := us.Get("username").(string)
 	status, ok2 := us.Get("login").(string)
@@ -160,52 +59,4 @@
 		us.Set("token", db.NewToken())
 	}
 	return user, status, us, role
-}
-
-// TODO: This will require actual client data from the database to populate the page
-func (d *handle) profile(w http.ResponseWriter, r *http.Request) {
-	w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
-	user, status, us, role := getUser(d, w, r)
-	if status == "false" {
-		http.Redirect(w, r, "/login.html", 302)
-		return
-	}
-	if rd, ok := us.Get("redirect").(string); ok {
-		us.Delete("redirect")
-		http.Redirect(w, r, "/"+rd, 302)
-		return
-	}
-	p := &Request{
-		printer: userLang(r),
-		status:  status,
-		session: us,
-		user:    user,
-		role:    role,
-	}
-	var data []byte
-	var err error
-	switch db.UserRole(user) {
-	case db.DoctorAuth:
-		if role != db.DoctorAuth {
-			http.Error(w, "Unauthorized", 401)
-			return
-		}
-		p.path = "doctor/profile.html"
-		data, err = getdata(p, "doctor")
-	case db.PatientAuth:
-		if role != db.PatientAuth {
-			http.Error(w, "Unauthorized", 401)
-			return
-		}
-		p.path = "patient/profile.html"
-		data, err = getdata(p, "patient")
-	default:
-		http.Error(w, "Forbidden", 403)
-		return
-	}
-	if err != nil {
-		http.Error(w, "Service Unavailable", 503)
-		return
-	}
-	fmt.Fprintf(w, "%s", data)
 }