package main import ( "database/sql" "errors" "net/http" "stevenlr.com/locker/model" "stevenlr.com/locker/utils" ) func generateSessionId() (string, error) { return utils.GenerateRandomString(66) } type Sessions struct { sessions map[string]Session } type Session struct { UserId model.UUID } const sessionCookieName = "LockerSession" func removeCookie(cookieName string, w http.ResponseWriter) { cookie := http.Cookie{ Name: cookieName, Value: "", MaxAge: -1, } http.SetCookie(w, &cookie) } func MakeSessions() Sessions { return Sessions{ sessions: make(map[string]Session), } } func (sessions *Sessions) FindCurrentUser(db *sql.DB, w http.ResponseWriter, r *http.Request) *model.User { cookie, err := r.Cookie(sessionCookieName) if err != nil { return nil } userId, ok := sessions.sessions[cookie.Value] if !ok { removeCookie(sessionCookieName, w) return nil } user := model.GetUserById(db, userId.UserId) if user == nil { removeCookie(sessionCookieName, w) } return user } func (sessions *Sessions) StartSession(user model.UUID, w http.ResponseWriter) error { sessionId, err := generateSessionId() if err != nil { return errors.New("Couldn't generate session ID") } cookie := http.Cookie{ Name: sessionCookieName, Value: sessionId, HttpOnly: true, Secure: true, } sessions.sessions[sessionId] = Session{UserId: user} http.SetCookie(w, &cookie) return nil } func (sessions *Sessions) EndSession(w http.ResponseWriter, r *http.Request) { if cookie, err := r.Cookie(sessionCookieName); err == nil { delete(sessions.sessions, cookie.Value) removeCookie(sessionCookieName, w) } }