package main import ( "encoding/json" "fmt" "net/http" "os" "time" ) type Session struct { ID string LoggedIn bool Me string AuthorizationEndpoint string RedirectURI string State string NextURI string } func NewSession(w http.ResponseWriter, r *http.Request) (*Session, error) { sessionID, err := getSessionCookie(w, r) if err != nil { return nil, err } session := &Session{ID: sessionID} err = loadSession(session) if err != nil { return nil, err } return session, nil } func (sess *Session) Flush() error { return saveSession(sess) } func saveSession(sess *Session) error { filename := generateFilename(sess.ID) err := os.Mkdir("session", 0755) f, err := os.Create(filename) if err != nil { return err } defer f.Close() err = json.NewEncoder(f).Encode(sess) return err } func loadSession(sess *Session) error { filename := generateFilename(sess.ID) err := os.Mkdir("session", 0755) f, err := os.Open(filename) if err != nil { if os.IsNotExist(err) { // add defaults to session? return nil } return err } defer f.Close() err = json.NewDecoder(f).Decode(sess) return err } func generateFilename(id string) string { return fmt.Sprintf("session/%s.json", id) } func getSessionCookie(w http.ResponseWriter, r *http.Request) (string, error) { c, err := r.Cookie("session") var sessionVar string if err != nil { if err == http.ErrNoCookie { sessionVar = RandStringBytes(16) newCookie := &http.Cookie{ Name: "session", Value: sessionVar, Expires: time.Now().Add(24 * time.Hour), Path: "/", } http.SetCookie(w, newCookie) return sessionVar, nil } return "", err } else { sessionVar = c.Value } return sessionVar, nil }