hlfw.ca

webbing

Download patch

ref: 87f250a3c8b6f331d621cda0aa5a2928859058cf
parent: 0f51c810b296f0a42793a83f5ce1368cdf544fda
author: Michael Misch <michaelmisch1985@gmail.com>
date: Tue Nov 26 15:44:33 PST 2019

Fix sessions

--- /dev/null
+++ b/db/token.go
@@ -1,0 +1,30 @@
+package db
+
+import (
+	"errors"
+	"net/http"
+
+	"github.com/google/uuid"
+	"github.com/olmaxmedical/olmax_go/session"
+)
+
+// NewToken returns a unique token string
+func NewToken() string {
+	u, _ := uuid.NewRandom()
+	t := u.String()
+	return t
+}
+
+// ValidateToken - verify old token was correct, set new
+func ValidateToken(h *http.Request, s session.Session) error {
+	defer s.Delete("token")
+	if h == nil {
+		return errors.New("Invalid session")
+	}
+	token := h.PostFormValue("token")
+	if s.Get("token") != token {
+		return errors.New("Invalid/expired token")
+	}
+	s.Set("token", NewToken())
+	return nil
+}
--- a/pages/patient/symptoms.go
+++ b/pages/patient/symptoms.go
@@ -12,7 +12,7 @@
 		CSS:    "",
 		Path:   "patient/symptoms",
 		Data:   symptoms,
-		Extra:  plugins.FormErrors | plugins.SessionToken,
+		Extra:  plugins.FormErrors,
 	}
 	router.AddPage(b)
 }
--- a/plugins/password.go
+++ b/plugins/password.go
@@ -38,8 +38,10 @@
 		us.Set("username", user)
 		us.Set("login", "true")
 		us.Set("role", db.UserRole(user))
+		us.Set("token", db.NewToken())
 		return nil
 	}
+
 	return errors.New(p.Sprint("Invalid login"))
 }
 
--- a/plugins/tokens.go
+++ b/plugins/tokens.go
@@ -1,28 +1,14 @@
 package plugins
 
 import (
-	"errors"
-
-	"github.com/google/uuid"
+	"github.com/olmaxmedical/olmax_go/db"
 	"github.com/olmaxmedical/olmax_go/router"
 )
 
-//TODO(halfwit) Set up in memory tokens in db as well as
-var tokens []string
-
-// SessionToken - An in-memory token to allow a client to track
-const SessionToken router.PluginMask = 1 << 13
-
 // FormToken - A database-persisted one time use token to relate forms to POST requests
 const FormToken router.PluginMask = 1 << 14
 
 func init() {
-	b := &router.Plugin{
-		Name:     "sessionToken",
-		Run:      newSessionToken,
-		Validate: validateToken,
-	}
-	router.AddPlugin(b, SessionToken)
 	c := &router.Plugin{
 		Name:     "formToken",
 		Run:      newFormToken,
@@ -31,39 +17,13 @@
 	router.AddPlugin(c, FormToken)
 }
 
-func newSessionToken(r *router.Request) map[string]interface{} {
-	return map[string]interface{}{
-		"token": newToken(),
-	}
+func validateToken(r *router.Request) error {
+	return db.ValidateToken(r.Request(), r.Session())
 }
 
 // TODO(halfwit) - database
 func newFormToken(r *router.Request) map[string]interface{} {
 	return map[string]interface{}{
-		"token": newToken(),
+		"token": db.NewToken(),
 	}
-}
-
-func validateToken(r *router.Request) error {
-	s := r.Request()
-	if s == nil {
-		return errors.New("Invalid session")
-	}
-	token := s.PostFormValue("token")
-	for n, t := range tokens {
-		if token == t {
-			// n will always be at least 0, tokens at least 1
-			tokens[n] = tokens[len(tokens)-1]
-			tokens = tokens[:len(tokens)-1]
-			return nil
-		}
-	}
-	return errors.New("Invalid/missing token")
-}
-
-func newToken() string {
-	u, _ := uuid.NewRandom()
-	t := u.String()
-	tokens = append(tokens, t)
-	return t
 }
--- a/router/run.go
+++ b/router/run.go
@@ -50,7 +50,6 @@
 	p := userLang(r)
 	user, _, us, _ := getUser(d, w, r)
 	token := email.NextResetToken(r.URL.Path[7:], user)
-	fmt.Println(r.URL.Path[7:], token)
 	if token == "" {
 		us.Set("errors", [1]string{p.Sprint("Token expired")})
 		return
@@ -165,6 +164,9 @@
 	}
 	if !ok3 {
 		role = db.GuestAuth
+	}
+	if status == "true" {
+		us.Set("token", db.NewToken())
 	}
 	return user, status, us, role
 }
--- a/session/data.go
+++ b/session/data.go
@@ -92,10 +92,10 @@
 	for {
 		element := pder.list.Back()
 		if element == nil {
-			break
+			return
 		}
 		if (element.Value.(*Store).atime.Unix() + maxlifetime) >= time.Now().Unix() {
-			break
+			return
 		}
 		pder.list.Remove(element)
 		delete(pder.sessions, element.Value.(*Store).sid)
--- a/session/manager.go
+++ b/session/manager.go
@@ -110,7 +110,9 @@
 	manager.lock.Lock()
 	defer manager.lock.Unlock()
 	manager.provider.GC(manager.maxlifetime)
-	time.AfterFunc(time.Duration(manager.maxlifetime), func() { manager.GC() })
+	time.AfterFunc(10*time.Second, func() {
+		manager.GC()
+	})
 }
 
 func (manager *Manager) sessionID() string {