95 lines
1.8 KiB
Go
95 lines
1.8 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"source.toby3d.me/toby3d/auth/internal/domain"
|
|
"source.toby3d.me/toby3d/auth/internal/session"
|
|
)
|
|
|
|
type (
|
|
Session struct {
|
|
CreatedAt time.Time
|
|
domain.Session
|
|
}
|
|
|
|
memorySessionRepository struct {
|
|
mutex *sync.RWMutex
|
|
sessions map[string]Session
|
|
config domain.Config
|
|
}
|
|
)
|
|
|
|
func NewMemorySessionRepository(config domain.Config) session.Repository {
|
|
return &memorySessionRepository{
|
|
config: config,
|
|
mutex: new(sync.RWMutex),
|
|
sessions: make(map[string]Session),
|
|
}
|
|
}
|
|
|
|
func (repo *memorySessionRepository) Create(_ context.Context, s domain.Session) error {
|
|
repo.mutex.Lock()
|
|
defer repo.mutex.Unlock()
|
|
|
|
repo.sessions[s.Code] = Session{
|
|
CreatedAt: time.Now().UTC(),
|
|
Session: s,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *memorySessionRepository) Get(_ context.Context, code string) (*domain.Session, error) {
|
|
repo.mutex.Lock()
|
|
defer repo.mutex.Unlock()
|
|
|
|
if s, ok := repo.sessions[code]; ok {
|
|
return &s.Session, nil
|
|
}
|
|
|
|
return nil, session.ErrNotExist
|
|
}
|
|
|
|
func (repo *memorySessionRepository) GetAndDelete(ctx context.Context, code string) (*domain.Session, error) {
|
|
s, err := repo.Get(ctx, code)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot get and delete session: %w", err)
|
|
}
|
|
|
|
repo.mutex.Lock()
|
|
defer repo.mutex.Unlock()
|
|
|
|
delete(repo.sessions, s.Code)
|
|
|
|
return s, nil
|
|
}
|
|
|
|
func (repo *memorySessionRepository) GC() {
|
|
ticker := time.NewTicker(time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for ts := range ticker.C {
|
|
ts := ts
|
|
|
|
repo.mutex.RLock()
|
|
|
|
for code, s := range repo.sessions {
|
|
if s.CreatedAt.Add(repo.config.Code.Expiry).After(ts) {
|
|
continue
|
|
}
|
|
|
|
repo.mutex.RUnlock()
|
|
repo.mutex.Lock()
|
|
delete(repo.sessions, code)
|
|
repo.mutex.Unlock()
|
|
repo.mutex.RLock()
|
|
}
|
|
|
|
repo.mutex.RUnlock()
|
|
}
|
|
}
|