package allowances import ( "encoding/json" "fmt" "log" "net/http" "strconv" "strings" "github.com/gorilla/sessions" "mcquay.me/allowances/children" "mcquay.me/fs" ) func init() { log.SetFlags(log.Lshortfile | log.Ltime) } type failure struct { Success bool `json:"success"` Error string `json:"error"` } func NewFailure(msg string) *failure { return &failure{ Success: false, Error: msg, } } type Allowances struct { db children.DB dbfile string hashes Passes store *sessions.CookieStore } func NewAllowances(sm *http.ServeMux, dbfile, passfile, staticFiles string) (*Allowances, error) { var err error tmpls, err = getTemplates() if err != nil { return nil, err } hashes, exists, err := GetHashes(passfile) if !exists { return nil, fmt.Errorf("passes file doesn't exist: %q", passfile) } if err != nil { return nil, err } if !fs.Exists(dbfile) { return nil, fmt.Errorf("child db file doesn't exist: %q", dbfile) } db, err := children.Load(dbfile) if err != nil { return nil, err } r := &Allowances{ db: db, dbfile: dbfile, hashes: hashes, store: sessions.NewCookieStore([]byte("hello world")), } addRoutes(sm, r, staticFiles) return r, nil } func (a *Allowances) home(w http.ResponseWriter, req *http.Request, uid string) error { tmpls["home"].Execute(w, map[string]interface{}{"children": a.db}) return nil } func (a *Allowances) login(w http.ResponseWriter, req *http.Request) { attempt := req.FormValue("passwd") ok, err := a.hashes.Check(attempt) if err != nil { b, _ := json.Marshal(NewFailure(err.Error())) http.Error(w, string(b), http.StatusBadRequest) return } if ok { session, _ := a.store.Get(req, sessionName) session.Values["uuid"] = "me" session.Save(req, w) http.Redirect(w, req, "/", http.StatusSeeOther) return } tmpls["login"].Execute(w, map[string]interface{}{}) } func (a *Allowances) logout(w http.ResponseWriter, req *http.Request, u string) error { session, err := a.store.Get(req, sessionName) if err != nil { return err } delete(session.Values, "uuid") session.Save(req, w) http.Redirect(w, req, "/", http.StatusSeeOther) return nil } func (a *Allowances) add(w http.ResponseWriter, req *http.Request, uid string) error { path := req.URL.Path[len(prefix["add"]):] bits := strings.Split(path, "/") child := bits[0] amount, err := strconv.Atoi(bits[1]) if err != nil { return fmt.Errorf("couldn't parse a dollar amount: %v", err) } a.db[child] += amount a.db.Save(a.dbfile) w.Header().Set("Content-Type", "application/json") b, err := json.Marshal(map[string]interface{}{ "amount": dollarize(a.db[child]), "name": child, }) if err != nil { return err } w.Write(b) return nil }