diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2025-08-14 18:07:12 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2025-08-14 18:07:12 +0100 |
| commit | 4697556cac819c47d068819b9fc9c3b4ea84e279 (patch) | |
| tree | b832d8fc6b643a8b9d0eeca35c1268e1649da731 /pkg/session/memory.go | |
| parent | dd49c9205bb04844b686b9c3396c40eb49d25826 (diff) | |
Merge confplanner-web and replace fiber with native net/http
Diffstat (limited to 'pkg/session/memory.go')
| -rw-r--r-- | pkg/session/memory.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/pkg/session/memory.go b/pkg/session/memory.go new file mode 100644 index 0000000..96e416b --- /dev/null +++ b/pkg/session/memory.go @@ -0,0 +1,95 @@ +package session + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "sync" + "time" +) + +type memoryStore struct { + sessionsByToken map[string]*UserSession + sessionsBySID map[uint]*UserSession + nextSessionId uint + lock sync.RWMutex +} + +func NewMemoryStore() Service { + return &memoryStore{ + sessionsByToken: make(map[string]*UserSession), + sessionsBySID: make(map[uint]*UserSession), + } +} + +func (s *memoryStore) GetByToken(token string) *UserSession { + if token == "" { + return nil + } + + s.lock.RLock() + defer s.lock.RUnlock() + + return s.sessionsByToken[token] +} + +func (s *memoryStore) GetBySID(sid uint) *UserSession { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.sessionsBySID[sid] +} + +func (s *memoryStore) Create(uid int32, username string, ip string, ua string) (*UserSession, error) { + token := generateSessionToken() + + s.lock.Lock() + defer s.lock.Unlock() + + sessionId := s.nextSessionId + s.nextSessionId++ + + _, sidExists := s.sessionsBySID[sessionId] + _, tokenExists := s.sessionsByToken[token] + + // should never realistically happen but still theoretically possible + if sidExists || tokenExists { + return nil, fmt.Errorf("session conflict") + } + + session := &UserSession{ + UserID: uid, + SessionID: sessionId, + Token: token, + Username: username, + IP: ip, + UserAgent: ua, + LoginTime: time.Now(), + } + s.sessionsByToken[token] = session + s.sessionsBySID[sessionId] = session + + return session, nil +} + +func (s *memoryStore) Destroy(sid uint) error { + s.lock.Lock() + defer s.lock.Unlock() + + session := s.sessionsBySID[sid] + if session == nil { + return fmt.Errorf("session does not exist") + } + + delete(s.sessionsBySID, sid) + delete(s.sessionsByToken, session.Token) + return nil +} + +func generateSessionToken() string { + b := make([]byte, 100) + if _, err := rand.Read(b); err != nil { + return "" + } + return hex.EncodeToString(b) +} |
