session.go

 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}