1package auth
2
3import (
4 "crypto/rand"
5 "encoding/base64"
6 "sync"
7
8 "github.com/git-bug/git-bug/entity"
9)
10
11// SessionCookie is the name of the HTTP cookie that holds the session token.
12const SessionCookie = "git-bug-session"
13
14// SessionStore holds in-memory sessions mapping opaque tokens to identity IDs.
15// Sessions are intentionally not persisted: users simply re-authenticate after
16// a server restart. This keeps the implementation simple and dependency-free,
17// which is appropriate for a locally-run webui.
18type SessionStore struct {
19 mu sync.RWMutex
20 m map[string]entity.Id
21}
22
23func NewSessionStore() *SessionStore {
24 return &SessionStore{m: make(map[string]entity.Id)}
25}
26
27// Create generates a new session token for the given identity, stores it, and
28// returns the token. The token is 32 bytes of crypto/rand encoded as base64url.
29func (s *SessionStore) Create(userId entity.Id) (string, error) {
30 b := make([]byte, 32)
31 if _, err := rand.Read(b); err != nil {
32 return "", err
33 }
34 token := base64.RawURLEncoding.EncodeToString(b)
35 s.mu.Lock()
36 s.m[token] = userId
37 s.mu.Unlock()
38 return token, nil
39}
40
41// Get retrieves the identity ID associated with a token.
42func (s *SessionStore) Get(token string) (entity.Id, bool) {
43 s.mu.RLock()
44 id, ok := s.m[token]
45 s.mu.RUnlock()
46 return id, ok
47}
48
49// Delete removes a session token (logout).
50func (s *SessionStore) Delete(token string) {
51 s.mu.Lock()
52 delete(s.m, token)
53 s.mu.Unlock()
54}