diff --git a/auth_manager.go b/auth_manager.go index 1b3fca137c7..60019facab6 100644 --- a/auth_manager.go +++ b/auth_manager.go @@ -44,8 +44,9 @@ type DefaultAuthorisationManager struct { } type DefaultSessionManager struct { - store storage.Handler - asyncWrites bool + store storage.Handler + asyncWrites bool + disableCacheSessionState bool } func (b *DefaultAuthorisationManager) Init(store storage.Handler) { @@ -85,6 +86,7 @@ func (b *DefaultAuthorisationManager) KeyExpired(newSession *user.SessionState) func (b *DefaultSessionManager) Init(store storage.Handler) { b.asyncWrites = config.Global().UseAsyncSessionWrite + b.disableCacheSessionState = config.Global().LocalSessionCache.DisableCacheSessionState b.store = store b.store.Connect() } @@ -120,10 +122,16 @@ func (b *DefaultSessionManager) UpdateSession(keyName string, session *user.Sess v, _ := json.Marshal(session) - // Keep the TTL + if hashed { + keyName = b.store.GetKeyPrefix() + keyName + } + + // async update and return if needed if b.asyncWrites { + b.renewSessionState(keyName, session) + if hashed { - go b.store.SetRawKey(b.store.GetKeyPrefix()+keyName, string(v), resetTTLTo) + go b.store.SetRawKey(keyName, string(v), resetTTLTo) return nil } @@ -131,11 +139,28 @@ func (b *DefaultSessionManager) UpdateSession(keyName string, session *user.Sess return nil } + // sync update + var err error if hashed { - return b.store.SetRawKey(b.store.GetKeyPrefix()+keyName, string(v), resetTTLTo) + err = b.store.SetRawKey(keyName, string(v), resetTTLTo) + } else { + err = b.store.SetKey(keyName, string(v), resetTTLTo) } - return b.store.SetKey(keyName, string(v), resetTTLTo) + if err == nil { + b.renewSessionState(keyName, session) + } + + return err +} + +func (b *DefaultSessionManager) renewSessionState(keyName string, session *user.SessionState) { + // we have new session state so renew first-seen hash to prevent + session.SetFirstSeenHash() + // delete it from session cache to have it re-populated next time + if !b.disableCacheSessionState { + SessionCache.Delete(keyName) + } } // RemoveSession removes session from storage diff --git a/middleware.go b/middleware.go index b1e984dd609..1e648c9efbe 100644 --- a/middleware.go +++ b/middleware.go @@ -269,10 +269,17 @@ func (t BaseMiddleware) ApplyPolicies(key string, session *user.SessionState) er tags[tag] = true } } - session.Tags = make([]string, 0, len(tags)) - for tag := range tags { - session.Tags = append(session.Tags, tag) + + // set tags + if len(tags) > 0 { + session.Tags = make([]string, 0, len(tags)) + for tag := range tags { + session.Tags = append(session.Tags, tag) + } + } else { + session.Tags = nil } + session.AccessRights = rights // Update the session in the session manager in case it gets called again return t.Spec.SessionManager.UpdateSession(key, session, session.Lifetime(t.Spec.SessionLifetime), false) diff --git a/user/session.go b/user/session.go index c8655a6c5d8..6cc0d300808 100644 --- a/user/session.go +++ b/user/session.go @@ -72,13 +72,11 @@ type SessionState struct { IdExtractorDeadline int64 `json:"id_extractor_deadline" msg:"id_extractor_deadline"` SessionLifetime int64 `bson:"session_lifetime" json:"session_lifetime"` - FirstSeenHash string `bson:"-" json:"-"` + firstSeenHash string } -var murmurHasher = murmur3.New32() - func (s *SessionState) SetFirstSeenHash() { - s.FirstSeenHash = s.Hash() + s.firstSeenHash = s.Hash() } func (s *SessionState) Hash() string { @@ -87,11 +85,14 @@ func (s *SessionState) Hash() string { log.Error("Error encoding session data: ", err) return "" } - return string(murmurHasher.Sum(encoded)[:]) + murmurHasher := murmur3.New32() + murmurHasher.Write(encoded) + murmurHasher.Sum32() + return string(murmurHasher.Sum(nil)[:]) } func (s *SessionState) HasChanged() bool { - return s.FirstSeenHash == "" || s.FirstSeenHash != s.Hash() + return s.firstSeenHash == "" || s.firstSeenHash != s.Hash() } func (s *SessionState) Lifetime(fallback int64) int64 {