Prevent (caught) panic on login (#11590) (#11598)

Backport #11590

Unfortunately when the virtual session is released it requires that the
real session does not exist. This worked fine when sessions were only
saved at the end of request/response cycle however, now sessions are
saved proactively this does not hold.

The result is a caught panic in the logs during every log-in.  This
panic has no significant side-effects but should not occur.

This PR marks the virtual session as released when released and updates
it if the same session is released again.

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2020-05-27 21:37:27 +01:00 committed by GitHub
parent a854846f06
commit dc0ea133e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 14 additions and 6 deletions

View File

@ -107,10 +107,11 @@ func init() {
// VirtualStore represents a virtual session store implementation. // VirtualStore represents a virtual session store implementation.
type VirtualStore struct { type VirtualStore struct {
p *VirtualSessionProvider p *VirtualSessionProvider
sid string sid string
lock sync.RWMutex lock sync.RWMutex
data map[interface{}]interface{} data map[interface{}]interface{}
released bool
} }
// NewVirtualStore creates and returns a virtual session store. // NewVirtualStore creates and returns a virtual session store.
@ -164,7 +165,7 @@ func (s *VirtualStore) Release() error {
// Now ensure that we don't exist! // Now ensure that we don't exist!
realProvider := s.p.provider realProvider := s.p.provider
if realProvider.Exist(s.sid) { if !s.released && realProvider.Exist(s.sid) {
// This is an error! // This is an error!
return fmt.Errorf("new sid '%s' already exists", s.sid) return fmt.Errorf("new sid '%s' already exists", s.sid)
} }
@ -172,12 +173,19 @@ func (s *VirtualStore) Release() error {
if err != nil { if err != nil {
return err return err
} }
if err := realStore.Flush(); err != nil {
return err
}
for key, value := range s.data { for key, value := range s.data {
if err := realStore.Set(key, value); err != nil { if err := realStore.Set(key, value); err != nil {
return err return err
} }
} }
return realStore.Release() err = realStore.Release()
if err == nil {
s.released = true
}
return err
} }
return nil return nil
} }