diff pkg/auth/session.go @ 498:22e1bf563a04 metamorph-for-all

Throw away the connection level for sessions. This is not needed any more because the db connection are not bound to the sessions any more.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 24 Aug 2018 15:12:22 +0200
parents 8a0737aa6ab6
children e1466e65bc35
line wrap: on
line diff
--- a/pkg/auth/session.go	Fri Aug 24 14:28:05 2018 +0200
+++ b/pkg/auth/session.go	Fri Aug 24 15:12:22 2018 +0200
@@ -4,6 +4,7 @@
 	"encoding/base64"
 	"errors"
 	"io"
+	"sync"
 	"time"
 
 	"gemma.intevation.de/gemma/pkg/common"
@@ -16,6 +17,10 @@
 	ExpiresAt int64  `json:"expires"`
 	User      string `json:"user"`
 	Roles     Roles  `json:"roles"`
+
+	// private fields for managing expiration.
+	access time.Time
+	mu     sync.Mutex
 }
 
 func (r Roles) Has(role string) bool {
@@ -51,7 +56,7 @@
 	}
 }
 
-func (s *Session) serialize(w io.Writer) error {
+func (s *Session) serializePublic(w io.Writer) error {
 	wr := misc.BinWriter{w, nil}
 	wr.WriteBin(s.ExpiresAt)
 	wr.WriteString(s.User)
@@ -62,21 +67,76 @@
 	return wr.Err
 }
 
+func (s *Session) serialize(w io.Writer) error {
+
+	access, err := s.last().MarshalText()
+	if err != nil {
+		return err
+	}
+
+	wr := misc.BinWriter{w, nil}
+	wr.WriteBin(s.ExpiresAt)
+	wr.WriteString(s.User)
+	wr.WriteBin(uint32(len(s.Roles)))
+	for _, role := range s.Roles {
+		wr.WriteString(role)
+	}
+	wr.WriteBin(uint32(len(access)))
+	wr.WriteBin(access)
+	return wr.Err
+}
+
 func (s *Session) deserialize(r io.Reader) error {
-	var x Session
+
+	var session Session
+
 	var n uint32
 	rd := misc.BinReader{r, nil}
-	rd.ReadBin(&x.ExpiresAt)
-	rd.ReadString(&x.User)
+	rd.ReadBin(&session.ExpiresAt)
+	rd.ReadString(&session.User)
 	rd.ReadBin(&n)
-	x.Roles = make(Roles, n)
+	session.Roles = make(Roles, n)
+
 	for i := uint32(0); n > 0 && i < n; i++ {
-		rd.ReadString(&x.Roles[i])
+		rd.ReadString(&session.Roles[i])
+	}
+
+	if rd.Err != nil {
+		return rd.Err
+	}
+
+	var l uint32
+	rd.ReadBin(&l)
+	access := make([]byte, l)
+	rd.ReadBin(access)
+
+	if rd.Err != nil {
+		return rd.Err
+	}
+
+	var t time.Time
+	if err := t.UnmarshalText(access); err != nil {
+		return err
 	}
-	if rd.Err == nil {
-		*s = x
-	}
-	return rd.Err
+
+	session.access = t
+
+	*s = session
+
+	return nil
+}
+
+func (c *Session) touch() {
+	c.mu.Lock()
+	c.access = time.Now()
+	c.mu.Unlock()
+}
+
+func (c *Session) last() time.Time {
+	c.mu.Lock()
+	access := c.access
+	c.mu.Unlock()
+	return access
 }
 
 func GenerateSessionKey() string {