Files
wonderwall/pkg/session/store_memory.go
Trong Huu Nguyen c0138f4b49 feat(session): use locks for refreshing
One of the changes in OAuth 2.1 addresses attacks with refresh token
replays by recommending the use of one-time use tokens. A refresh token
is thus rotated and invalid after exactly one use, returning a new token
for each successful grant. Any further attempts must thus use the most
recently acquired refresh token. Reusing a refresh token may also
cause the authorization server to invalidate the current active refresh
token, requiring a refresh authorization grant to be reacquired for
further refresh token usage.

The use of locks prevents multiple refresh grant attempts for a given
session from happening across concurrent requests.
2022-09-04 17:14:35 +02:00

70 lines
1.2 KiB
Go

package session
import (
"context"
"fmt"
"sync"
"time"
)
type memorySessionStore struct {
lock sync.Mutex
sessions map[string]*EncryptedData
}
var _ Store = &memorySessionStore{}
func NewMemory() Store {
return &memorySessionStore{
sessions: make(map[string]*EncryptedData),
}
}
func (s *memorySessionStore) Read(_ context.Context, key string) (*EncryptedData, error) {
s.lock.Lock()
defer s.lock.Unlock()
data, ok := s.sessions[key]
if !ok {
return nil, fmt.Errorf("%w: no such session: %s", KeyNotFoundError, key)
}
return data, nil
}
func (s *memorySessionStore) Write(_ context.Context, key string, value *EncryptedData, _ time.Duration) error {
s.lock.Lock()
defer s.lock.Unlock()
s.sessions[key] = value
return nil
}
func (s *memorySessionStore) Delete(_ context.Context, keys ...string) error {
s.lock.Lock()
defer s.lock.Unlock()
for _, key := range keys {
delete(s.sessions, key)
}
return nil
}
func (s *memorySessionStore) Update(ctx context.Context, key string, value *EncryptedData) error {
_, err := s.Read(ctx, key)
if err != nil {
return err
}
s.lock.Lock()
defer s.lock.Unlock()
s.sessions[key] = value
return nil
}
func (s *memorySessionStore) MakeLock(_ string) Lock {
return NewNoOpLock()
}