Skip to content
Snippets Groups Projects
Commit 064293b8 authored by Christian Pointner's avatar Christian Pointner
Browse files

added session expiry

parent 7632ceaa
No related branches found
No related tags found
No related merge requests found
......@@ -25,12 +25,10 @@
package auth
import (
"os"
"time"
)
type SessionsConfig struct {
Secret string `json:"secret" yaml:"secret" toml:"secret"`
MaxAge time.Duration `json:"max-age" yaml:"max-age" toml:"max-age"`
}
......@@ -39,5 +37,5 @@ type Config struct {
}
func (c *Config) ExpandEnv() {
c.Sessions.Secret = os.ExpandEnv(c.Sessions.Secret)
// nothing to do here.
}
......@@ -27,6 +27,7 @@ package auth
import (
"crypto/rand"
"encoding/base64"
"errors"
"sync"
"time"
)
......@@ -36,8 +37,9 @@ const (
)
type Session struct {
username string
groups []string
Expires time.Time
Username string
Groups []string
}
func generateSessionId() (string, error) {
......@@ -48,9 +50,13 @@ func generateSessionId() (string, error) {
return base64.RawURLEncoding.EncodeToString(b[:]), nil
}
func (s *Session) Expired() bool {
return s.Expires.Before(time.Now())
}
type SessionManager struct {
maxAge time.Duration
mutex sync.RWMutex
maxAge time.Duration
sessions map[string]*Session
}
......@@ -63,13 +69,35 @@ func NewSessionManager(cfg SessionsConfig) (sm *SessionManager, err error) {
return
}
func (sm *SessionManager) NewSession() (id string, err error) {
func (sm *SessionManager) newSession() (id string, err error) {
if id, err = generateSessionId(); err != nil {
return
}
sm.mutex.Lock()
defer sm.mutex.Unlock()
sm.sessions[id] = &Session{}
sm.sessions[id] = &Session{Expires: time.Now().Add(sm.maxAge)}
return
}
func (sm *SessionManager) updateSession(id string, s *Session) error {
sm.mutex.Lock()
defer sm.mutex.Unlock()
if _, ok := sm.sessions[id]; !ok {
return errors.New("session not found.")
}
sm.sessions[id] = s
return nil
}
func (sm *SessionManager) getSession(id string) (*Session, error) {
sm.mutex.RLock()
defer sm.mutex.RUnlock()
s, ok := sm.sessions[id]
if !ok {
return nil, errors.New("session not found.")
}
return s, nil
}
......@@ -26,6 +26,7 @@ package auth
import (
"testing"
"time"
)
var (
......@@ -42,3 +43,28 @@ func TestCreateSessionManager(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
}
func TestSessionExpiry(t *testing.T) {
cfg := SessionsConfig{}
cfg.MaxAge = time.Second
sm, err := NewSessionManager(cfg)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
id, err := sm.newSession()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
s, err := sm.getSession(id)
if s.Expired() {
t.Fatalf("session has already expired")
}
time.Sleep(time.Second + 100*time.Millisecond)
if !s.Expired() {
t.Fatalf("session hasn't expired in time")
}
}
......@@ -30,8 +30,7 @@ importer:
auth:
sessions:
## keys will be randomly generated if this is not set
secret: "very very secret - don't tell anyone"
## defaults to 24h
max-age: 12h
### uncomment to enable CORS headers
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment