changeset 2639:0db742c7813d

Make session timeout configurable Useful e.g. for testing, long running scripts, coping with a client clock which is more than 3 hours fast and maybe more. Even configuring a timeout <= 0 might be useful to actually prevent clients from doing anything.
author Tom Gottfried <tom@intevation.de>
date Thu, 14 Mar 2019 11:15:43 +0100
parents 6c1730fc3dc1
children 4bcb26542767
files example_conf.toml pkg/auth/session.go pkg/auth/store.go pkg/config/config.go
diffstat 4 files changed, 31 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/example_conf.toml	Thu Mar 14 10:50:18 2019 +0100
+++ b/example_conf.toml	Thu Mar 14 11:15:43 2019 +0100
@@ -15,6 +15,9 @@
 # File to persist session data:
 sessions = "/tmp/gemma_session.data"
 
+# Duration until sessions expire if not renewed
+#session-timeout = "3h"
+
 # ----------------------------------------------------------------------
 # Database:
 
--- a/pkg/auth/session.go	Thu Mar 14 10:50:18 2019 +0100
+++ b/pkg/auth/session.go	Thu Mar 14 11:15:43 2019 +0100
@@ -21,6 +21,7 @@
 	"time"
 
 	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/config"
 	"gemma.intevation.de/gemma/pkg/misc"
 )
 
@@ -66,7 +67,6 @@
 
 const (
 	sessionKeyLength = 20
-	maxTokenValid    = time.Hour * 3
 )
 
 // newSession creates a new session.
@@ -74,7 +74,7 @@
 
 	// Create the Claims
 	return &Session{
-		ExpiresAt: time.Now().Add(maxTokenValid).Unix(),
+		ExpiresAt: time.Now().Add(config.SessionTimeout()).Unix(),
 		User:      user,
 		Roles:     roles,
 	}
--- a/pkg/auth/store.go	Thu Mar 14 10:50:18 2019 +0100
+++ b/pkg/auth/store.go	Thu Mar 14 11:15:43 2019 +0100
@@ -19,6 +19,7 @@
 	"log"
 	"time"
 
+	"gemma.intevation.de/gemma/pkg/config"
 	bolt "github.com/etcd-io/bbolt"
 )
 
@@ -207,7 +208,7 @@
 			ss.remove(token)
 			newToken := generateSessionKey()
 			// TODO: Ensure that this is not racy!
-			session.ExpiresAt = time.Now().Add(maxTokenValid).Unix()
+			session.ExpiresAt = time.Now().Add(config.SessionTimeout()).Unix()
 			ss.sessions[newToken] = session
 			ss.store(newToken, session)
 			resCh <- result{newToken: newToken}
--- a/pkg/config/config.go	Thu Mar 14 10:50:18 2019 +0100
+++ b/pkg/config/config.go	Thu Mar 14 11:15:43 2019 +0100
@@ -19,6 +19,7 @@
 	"fmt"
 	"log"
 	"sync"
+	"time"
 
 	homedir "github.com/mitchellh/go-homedir"
 	"github.com/spf13/cobra"
@@ -106,12 +107,14 @@
 func TmpDir() string { return viper.GetString("tmp-dir") }
 
 var (
-	proxyKeyOnce    sync.Once
-	proxyKey        []byte
-	proxyPrefixOnce sync.Once
-	proxyPrefix     string
-	externalURLOnce sync.Once
-	externalURL     string
+	proxyKeyOnce       sync.Once
+	proxyKey           []byte
+	proxyPrefixOnce    sync.Once
+	proxyPrefix        string
+	externalURLOnce    sync.Once
+	externalURL        string
+	sessionTimeoutOnce sync.Once
+	sessionTimeout     time.Duration
 )
 
 // ProxyKey is a crytographic key to sign the URLs generated by the proxy.
@@ -166,6 +169,20 @@
 	return externalURL
 }
 
+// SessionTimeout is the duration until a session expires if not renewed
+func SessionTimeout() time.Duration {
+	fetchTimeout := func() {
+		if sessionTimeout == 0 {
+			sessionTimeout = viper.GetDuration("session-timeout")
+			if sessionTimeout <= 0 {
+				log.Println("warn: non-positive session-timeout configured.")
+			}
+		}
+	}
+	sessionTimeoutOnce.Do(fetchTimeout)
+	return sessionTimeout
+}
+
 // The root directories where to find schema files.
 func SchemaDirs() string { return viper.GetString("schema-dirs") }
 
@@ -219,6 +236,7 @@
 	strP("db-ssl", "S", "prefer", "SSL mode of the database")
 
 	strP("sessions", "s", "", "path to the sessions file")
+	str("session-timeout", "3h", "duration until sessions expire")
 
 	strP("web", "w", "./web", "path to the web files")
 	strP("host", "o", "localhost", "host of the web app")