changeset 200:8426a92fda00

Persistent session store: Implmented Renew.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 22 Jul 2018 09:25:25 +0200
parents ddc7ef95c247
children 80dc7bbe97db
files auth/persistent.go
diffstat 1 files changed, 52 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/auth/persistent.go	Fri Jul 20 23:06:53 2018 +0200
+++ b/auth/persistent.go	Sun Jul 22 09:25:25 2018 +0200
@@ -80,6 +80,16 @@
 	log.Println("cleanToken: Not implemented, yet.")
 }
 
+func (pcp *PersistentConnectionPool) remove(token string) {
+	err := pcp.db.Update(func(tx *bolt.Tx) error {
+		b := tx.Bucket(sessionsBucket)
+		return b.Delete([]byte(token))
+	})
+	if err != nil {
+		log.Printf("error: %v\n", err)
+	}
+}
+
 func (pcp *PersistentConnectionPool) Delete(token string) bool {
 	res := make(chan bool)
 	pcp.cmds <- func(pcp *PersistentConnectionPool) {
@@ -90,18 +100,26 @@
 		}
 		conn.close()
 		delete(pcp.conns, token)
-		err := pcp.db.Update(func(tx *bolt.Tx) error {
-			b := tx.Bucket(sessionsBucket)
-			return b.Delete([]byte(token))
-		})
-		if err != nil {
-			log.Printf("error: %v\n", err)
-		}
+		pcp.remove(token)
 		res <- true
 	}
 	return <-res
 }
 
+func (pcp *PersistentConnectionPool) store(token string, con *Connection) {
+	err := pcp.db.Update(func(tx *bolt.Tx) error {
+		b := tx.Bucket(sessionsBucket)
+		var buf bytes.Buffer
+		if err := con.serialize(&buf); err != nil {
+			return err
+		}
+		return b.Put([]byte(token), buf.Bytes())
+	})
+	if err != nil {
+		log.Printf("error: %v\n", err)
+	}
+}
+
 func (pcp *PersistentConnectionPool) Add(token string, session *Session) *Connection {
 	res := make(chan *Connection)
 
@@ -112,17 +130,7 @@
 			pcp.conns[token] = con
 		}
 		con.set(session)
-		err := pcp.db.Update(func(tx *bolt.Tx) error {
-			b := tx.Bucket(sessionsBucket)
-			var buf bytes.Buffer
-			if err := con.serialize(&buf); err != nil {
-				return err
-			}
-			return b.Put([]byte(token), buf.Bytes())
-		})
-		if err != nil {
-			log.Printf("error: %v\n", err)
-		}
+		pcp.store(token, con)
 		res <- con
 	}
 
@@ -131,8 +139,32 @@
 }
 
 func (pcp *PersistentConnectionPool) Renew(token string) (string, error) {
-	log.Println("Renew: Not implemented, yet.")
-	return "", nil
+
+	type result struct {
+		newToken string
+		err      error
+	}
+
+	resCh := make(chan result)
+
+	pcp.cmds <- func(cp *PersistentConnectionPool) {
+		con := pcp.conns[token]
+		if con == nil {
+			resCh <- result{err: ErrNoSuchToken}
+		} else {
+			delete(pcp.conns, token)
+			pcp.remove(token)
+			newToken := GenerateSessionKey()
+			// TODO: Ensure that this is not racy!
+			con.session.ExpiresAt = time.Now().Add(maxTokenValid).Unix()
+			pcp.conns[newToken] = con
+			pcp.store(newToken, con)
+			resCh <- result{newToken: newToken}
+		}
+	}
+
+	r := <-resCh
+	return r.newToken, r.err
 }
 
 func (pcp *PersistentConnectionPool) Do(token string, fn func(*sql.DB) error) error {