From a8560961ba99277b8026277dc2033188f18f26ee Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Tue, 29 Oct 2019 01:19:38 -0400 Subject: [PATCH] go: refactor * Move web stuff out to respective files * Move DB stuff to its own package * Move user stuff to its own package --- db/db.go | 84 ++++++++++ frontend/src/api.js | 6 +- frontend/src/store.js | 2 +- mood/mood.go | 29 ++++ serve.go | 358 ++---------------------------------------- user/user.go | 8 +- user/user_factory.go | 76 +++++++++ web/mood_handlers.go | 72 +++++++++ web/routes.go | 70 +++++++++ web/user_handlers.go | 72 +++++++++ web/web_handlers.go | 41 +++++ 11 files changed, 467 insertions(+), 351 deletions(-) create mode 100644 db/db.go create mode 100644 mood/mood.go create mode 100644 user/user_factory.go create mode 100644 web/mood_handlers.go create mode 100644 web/routes.go create mode 100644 web/user_handlers.go create mode 100644 web/web_handlers.go diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..2e7b6cc --- /dev/null +++ b/db/db.go @@ -0,0 +1,84 @@ +package db + +import "github.com/jmoiron/sqlx" + +type Database struct { + *sqlx.DB +} + +func New(path string) (*Database, error) { + d, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, err + } + return &Database{d}, nil +} + +func (d *Database) MakeDB() error { + q := `create table if not exists users ( + id integer primary key, + email text unique, + verification integer not null, + dateCreated integer, + lastLogin integer + )` + if _, err := d.Exec(q); err != nil { + return err + } + q = `create table if not exists mood_categories ( + id integer primary key, + name text + )` + if _, err := d.Exec(q); err != nil { + return err + } + q = `create table if not exists mood_category_texts ( + id integer primary key, + mood_category_id integer, + key text, + value integer, + foreign key(mood_category_id) references mood_categories(id) + + )` + if _, err := d.Exec(q); err != nil { + return err + } + q = `create table if not exists moods ( + id integer primary key, + user_id integer, + mood_category_id integer, + value integer, + time integer, + foreign key(user_id) references users(id), + foreign key(mood_category_id) references mood_categories(id) + )` + if _, err := d.Exec(q); err != nil { + return err + } + q = `select count(*) from mood_category_texts mct inner join mood_categories mc on mct.mood_category_id=mc.id` + var count int + if err := d.Get(&count, q); err != nil { + return err + } + if count == 0 { + return d.populateMoods() + } + return nil +} + +func (d *Database) populateMoods() error { + tx := d.MustBegin() + res := tx.MustExec(`insert into mood_categories (name) values ('happy')`) + id, err := res.LastInsertId() + if err != nil { + tx.Rollback() + return err + } + tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, + id, "😄", 1) + tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, + id, "😐", 0) + tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, + id, "😟", -1) + return tx.Commit() +} diff --git a/frontend/src/api.js b/frontend/src/api.js index 9792a15..fad3f0c 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -5,7 +5,7 @@ export default { return axios.get("/v1/moods", { headers: { 'X-user-id': userInfo.ID, - 'X-user-validation': userInfo.Validation + 'X-user-verification': userInfo.Verification } }) }, @@ -13,7 +13,7 @@ export default { return axios.post("/v1/moods", mood, { headers: { 'X-user-id': userInfo.ID, - 'X-user-validation': userInfo.Validation + 'X-user-verification': userInfo.Verification } }) }, @@ -24,7 +24,7 @@ export default { return axios.get("/v1/user/info", { headers: { 'X-user-id': userInfo.ID, - 'X-user-validation': userInfo.Validation + 'X-user-verification': userInfo.Verification } }) } diff --git a/frontend/src/store.js b/frontend/src/store.js index 2663b09..f85f4ee 100644 --- a/frontend/src/store.js +++ b/frontend/src/store.js @@ -8,7 +8,7 @@ Vue.use(Vuex); const store = new Vuex.Store({ state: { errs: [], - userInfo: {ID: "", Validation: ""}, + userInfo: {ID: "", Verification: ""}, moods: [], }, actions: { diff --git a/mood/mood.go b/mood/mood.go new file mode 100644 index 0000000..8720335 --- /dev/null +++ b/mood/mood.go @@ -0,0 +1,29 @@ +package mood + +import ( + "time" + + "code.chrissexton.org/cws/happy/db" + "code.chrissexton.org/cws/happy/user" +) + +type Mood struct { + db *db.Database +} + +func New(db *db.Database) *Mood { + return &Mood{db} +} + +type GetMoodsResponse struct { + CategoryID int64 `db:"category_id"` + CategoryName string `db:"category_name"` + Key string + Value int64 +} + +func (m *Mood) RecordMood(mood GetMoodsResponse, who user.User) error { + q := `insert into moods (user_id,mood_category_id,value,time) values (?,?,?,?)` + _, err := m.db.Exec(q, who.ID, mood.CategoryID, mood.Value, time.Now().Unix()) + return err +} diff --git a/serve.go b/serve.go index 77215c3..2323edf 100644 --- a/serve.go +++ b/serve.go @@ -1,31 +1,28 @@ package main import ( - "encoding/json" "flag" - "fmt" - "net/http" "os" - "path" "strconv" - "time" + + "code.chrissexton.org/cws/happy/web" + + "code.chrissexton.org/cws/happy/db" packr "github.com/gobuffalo/packr/v2" "code.chrissexton.org/cws/happy/email" - "code.chrissexton.org/cws/happy/user" _ "github.com/mattn/go-sqlite3" - "github.com/gorilla/mux" - "github.com/jmoiron/sqlx" "github.com/rs/zerolog" "github.com/rs/zerolog/log" hashids "github.com/speps/go-hashids" - "github.com/stretchr/graceful" ) var ( + dbPath = flag.String("db", "happy.db", "path to db") + httpAddr = flag.String("httpAddr", "0.0.0.0:8080", "http address") salt = flag.String("salt", "happy", "salt for IDs") minHashLen = flag.Int("minHashLen", 4, "minimum ID hash size") develop = flag.Bool("develop", false, "turn on develop mode") @@ -67,350 +64,25 @@ func main() { box := packr.New("dist", "frontend/dist") log.Debug().Strs("dirlist", box.List()).Msg("packr made") - s := server{ - addr: "0.0.0.0:8080", - assetPath: "pub", - salt: *salt, - box: box, - } - - db, err := sqlx.Connect("sqlite3", "happy.db") + db, err := db.New(*dbPath) if err != nil { log.Fatal(). Err(err). Msg("could not connect to database") } - s.db = db + hd := hashids.NewData() - hd.Salt = s.salt + hd.Salt = *salt hd.MinLength = *minHashLen - s.h, _ = hashids.NewWithData(hd) - if err := s.makeDB(); err != nil { - log.Fatal(). - Err(err). - Msg("could not create database") - } + h, _ := hashids.NewWithData(hd) + + var mailClient *email.EMailClient if validateMail() { log.Debug().Msg("sending mail") - s.email = email.New(*mailAddr, *mailPort, *mailUser, *mailPass) - u, _ := s.NewUser() - s.email.SendNewUserMail("chris@chrissexton.org", u, "http://happy.chrissexton.org") + mailClient = email.New(*mailAddr, *mailPort, *mailUser, *mailPass) } else { log.Debug().Msg("mail disabled") } - s.serve() -} - -type server struct { - addr string - assetPath string - db *sqlx.DB - salt string - h *hashids.HashID - box *packr.Box - email *email.EMailClient -} - -func (s *server) makeDB() error { - q := `create table if not exists users ( - id integer primary key, - email text unique, - verification integer not null, - dateCreated integer, - lastLogin integer - )` - if _, err := s.db.Exec(q); err != nil { - return err - } - q = `create table if not exists mood_categories ( - id integer primary key, - name text - )` - if _, err := s.db.Exec(q); err != nil { - return err - } - q = `create table if not exists mood_category_texts ( - id integer primary key, - mood_category_id integer, - key text, - value integer, - foreign key(mood_category_id) references mood_categories(id) - - )` - if _, err := s.db.Exec(q); err != nil { - return err - } - q = `create table if not exists moods ( - id integer primary key, - user_id integer, - mood_category_id integer, - value integer, - time integer, - foreign key(user_id) references users(id), - foreign key(mood_category_id) references mood_categories(id) - )` - if _, err := s.db.Exec(q); err != nil { - return err - } - q = `select count(*) from mood_category_texts mct inner join mood_categories mc on mct.mood_category_id=mc.id` - var count int - if err := s.db.Get(&count, q); err != nil { - return err - } - if count == 0 { - return s.populateMoods() - } - return nil -} - -func (s *server) populateMoods() error { - tx := s.db.MustBegin() - res := tx.MustExec(`insert into mood_categories (name) values ('happy')`) - id, err := res.LastInsertId() - if err != nil { - tx.Rollback() - return err - } - tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, - id, "😄", 1) - tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, - id, "😐", 0) - tx.MustExec(`insert into mood_category_texts (mood_category_id,key,value) values (?,?,?)`, - id, "😟", -1) - return tx.Commit() -} - -func (s *server) recordMood(mood getMoodsResponse, who user.User) error { - q := `insert into moods (user_id,mood_category_id,value,time) values (?,?,?,?)` - _, err := s.db.Exec(q, who.ID, mood.CategoryID, mood.Value, time.Now().Unix()) - return err -} - -func (s *server) NewUser() (user.User, error) { - uid := user.New(s.db, s.salt, s.h) - q := `insert into users (verification,dateCreated) values (?, ?)` - res, err := s.db.Exec(q, uid.Verification, uid.DateCreated) - if err != nil { - return uid, err - } - id, err := res.LastInsertId() - if err != nil { - return uid, err - } - uid.ID = id - return uid, nil -} - -func (s *server) FromStr(uid, verification string) (user.User, error) { - id := user.New(s.db, s.salt, s.h) - if uid == "" || verification == "" { - return id, fmt.Errorf("user ID and verification not given.") - } - idInt, err := s.h.DecodeInt64WithError(uid) - if err != nil { - return id, err - } - q := `select id,email,verification,datecreated,lastlogin from users where id=?` - if err := s.db.Get(&id, q, idInt[0]); err != nil { - log.Error(). - Err(err). - Msg("unable to select") - return id, err - } - verify, err := s.h.EncodeInt64([]int64{id.Verification}) - if err != nil { - log.Error(). - Err(err). - Str("verify", verify). - Str("id.Verification", verification). - Msg("unable to encode") - return id, err - } - if verify != verification { - log.Debug(). - Str("verify", verify). - Str("id.Verification", verification). - Msg("verification mismatch") - return id, fmt.Errorf("Invalid verification token") - } - return id, nil -} - -type RegisterResponse struct { - ID string - DateCreated int64 - Validation string `json:",omitempty"` -} - -func (s *server) handlerRegisterCode(w http.ResponseWriter, r *http.Request) { - uid, err := s.NewUser() - if err != nil { - w.WriteHeader(500) - log.Error().Err(err).Msg("error from NewUserID") - fmt.Fprintf(w, "Error registering user: %s", err) - return - } - if err != nil { - w.WriteHeader(500) - log.Error().Err(err).Msg("error converting date") - fmt.Fprintf(w, "Error registering user: %s", err) - return - } - resp := RegisterResponse{ - ID: uid.String(), - DateCreated: uid.DateCreated.Int64, - } - if *develop { - resp.Validation, _ = s.h.EncodeInt64([]int64{uid.Verification}) - } - out, err := json.Marshal(resp) - if err != nil { - w.WriteHeader(500) - log.Error().Err(err).Msg("error from json.Marshal") - fmt.Fprintf(w, "Error registering user: %s", err) - return - } - fmt.Fprintf(w, "%s", string(out)) -} - -type getMoodsResponse struct { - CategoryID int64 `db:"category_id"` - CategoryName string `db:"category_name"` - Key string - Value int64 -} - -func (s *server) getMoods(w http.ResponseWriter, r *http.Request) { - log.Debug().Interface("req", r).Msg("getMoods") - q := `select mc.id category_id,mc.name category_name,mct.key,mct.value - from mood_categories mc - inner join mood_category_texts mct - on mc.id=mct.mood_category_id` - recs := []getMoodsResponse{} - err := s.db.Select(&recs, q) - if err != nil { - log.Error().Err(err).Msg("could not retrieve mood categories and texts") - w.WriteHeader(500) - fmt.Fprintf(w, "Error getting moods: %s", err) - return - } - resp, err := json.Marshal(recs) - if err != nil { - log.Error().Err(err).Msg("error from json.Marshal") - w.WriteHeader(500) - fmt.Fprintf(w, "Error getting moods: %s", err) - return - } - fmt.Fprintf(w, "%s", string(resp)) -} - -func (s *server) checkUser(w http.ResponseWriter, r *http.Request) { - uid := r.Header.Get("X-user-id") - verify := r.Header.Get("X-user-validation") - log.Debug(). - Str("uid", uid). - Str("verify", verify). - Msg("checkUser") - user, err := s.FromStr(uid, verify) - if err != nil { - log.Error().Err(err).Msg("user not known") - w.WriteHeader(http.StatusUnauthorized) - fmt.Fprint(w, "User not known") - return - } - j, err := json.Marshal(user) - if err != nil { - w.WriteHeader(500) - log.Error().Err(err).Msg("could not marshal user") - fmt.Fprintf(w, "%s", err) - return - } - w.Write(j) -} - -func (s *server) handleMood(w http.ResponseWriter, r *http.Request) { - uid := r.Header.Get("X-user-id") - verify := r.Header.Get("X-user-validation") - log.Debug(). - Str("uid", uid). - Str("verify", verify). - Msg("handleMood") - dec := json.NewDecoder(r.Body) - happyReq := getMoodsResponse{} - err := dec.Decode(&happyReq) - if err != nil { - log.Error().Err(err).Msg("error with happy") - w.WriteHeader(400) - fmt.Fprintf(w, err.Error()) - return - } - log.Debug(). - Interface("mood", happyReq). - Msg("mood") - user, err := s.FromStr(uid, verify) - if err != nil { - log.Error(). - Err(err). - Msg("error getting user") - w.WriteHeader(403) - fmt.Fprintf(w, "Error: %s", err) - return - } - if err := s.recordMood(happyReq, user); err != nil { - log.Error().Err(err).Msg("error saving mood") - w.WriteHeader(500) - fmt.Fprintf(w, "Error: %s", err) - return - } - fmt.Fprintf(w, "ok") -} - -func (s *server) indexHandler(entryPoint string) func(w http.ResponseWriter, r *http.Request) { - fn := func(w http.ResponseWriter, r *http.Request) { - p := path.Clean(r.URL.Path) - - if s.box.Has(p) && !s.box.HasDir(p) { - f, err := s.box.Find(p) - if err != nil { - log.Error().Err(err).Msg("Error finding file") - w.WriteHeader(http.StatusNotFound) - } - w.Write(f) - return - } - if s.box.HasDir(p) && s.box.Has(path.Join(p, "index.html")) { - f, err := s.box.Find(path.Join(p, "index.html")) - if err != nil { - log.Error().Err(err).Msg("Error finding file") - w.WriteHeader(http.StatusNotFound) - } - w.Write(f) - return - } - - if f, err := s.box.Find(p); err != nil { - w.Write(f) - return - } - - w.WriteHeader(http.StatusNotFound) - } - return fn -} - -func (s *server) routeSetup() *mux.Router { - r := mux.NewRouter() - api := r.PathPrefix("/v1/").Subrouter() - api.HandleFunc("/moods", s.getMoods).Methods("GET") - api.HandleFunc("/moods", s.handleMood).Methods("POST") - api.HandleFunc("/user/code", s.handlerRegisterCode).Methods("GET") - api.HandleFunc("/user/info", s.checkUser).Methods("GET") - r.PathPrefix("/").HandlerFunc(s.indexHandler("/index.html")) - return r -} - -func (s *server) serve() { - middle := s.routeSetup() - log.Info().Str("addr", "http://"+s.addr).Msg("serving HTTP") - graceful.Run(s.addr, 10*time.Second, middle) + s := web.New(*httpAddr, "pub", db, *salt, h, box, mailClient) + s.Serve() } diff --git a/user/user.go b/user/user.go index b19cfcf..1d35b35 100644 --- a/user/user.go +++ b/user/user.go @@ -5,13 +5,13 @@ import ( "math/rand" "time" - "github.com/speps/go-hashids" + "code.chrissexton.org/cws/happy/db" - "github.com/jmoiron/sqlx" + "github.com/speps/go-hashids" ) type User struct { - db *sqlx.DB + db *db.Database ID int64 Email sql.NullString @@ -23,7 +23,7 @@ type User struct { str string } -func New(db *sqlx.DB, salt string, h *hashids.HashID) User { +func New(db *db.Database, salt string, h *hashids.HashID) User { u := User{ db: db, salt: salt, diff --git a/user/user_factory.go b/user/user_factory.go new file mode 100644 index 0000000..1fd5f84 --- /dev/null +++ b/user/user_factory.go @@ -0,0 +1,76 @@ +package user + +import ( + "fmt" + + "github.com/speps/go-hashids" + + "code.chrissexton.org/cws/happy/db" + "github.com/rs/zerolog/log" +) + +// lol + +type UserFactory struct { + db *db.Database + salt string + h *hashids.HashID +} + +func NewFactory(db *db.Database, salt string, h *hashids.HashID) *UserFactory { + return &UserFactory{ + db: db, + salt: salt, + h: h, + } +} + +func (uf *UserFactory) NewUser() (User, error) { + uid := New(uf.db, uf.salt, uf.h) + q := `insert into users (verification,dateCreated) values (?, ?)` + res, err := uf.db.Exec(q, uid.Verification, uid.DateCreated) + if err != nil { + return uid, err + } + id, err := res.LastInsertId() + if err != nil { + return uid, err + } + uid.ID = id + return uid, nil +} + +func (uf *UserFactory) FromStr(uid, verification string) (User, error) { + id := New(uf.db, uf.salt, uf.h) + if uid == "" || verification == "" { + return id, fmt.Errorf("user ID and verification not given.") + } + idInt, err := uf.h.DecodeInt64WithError(uid) + if err != nil { + return id, err + } + q := `select id,email,verification,datecreated,lastlogin from users where id=?` + if err := uf.db.Get(&id, q, idInt[0]); err != nil { + log.Error(). + Err(err). + Msg("unable to select") + return id, err + } + verify, err := uf.h.EncodeInt64([]int64{id.Verification}) + if err != nil { + log.Error(). + Err(err). + Str("verify", verify). + Str("id.Verification", verification). + Msg("unable to encode") + return id, err + } + if verify != verification { + log.Debug(). + Str("verify", verify). + Str("id.Verification", verification). + Msg("verification mismatch") + return id, fmt.Errorf("Invalid verification token") + } + return id, nil +} diff --git a/web/mood_handlers.go b/web/mood_handlers.go new file mode 100644 index 0000000..d7dad5b --- /dev/null +++ b/web/mood_handlers.go @@ -0,0 +1,72 @@ +package web + +import ( + "encoding/json" + "fmt" + "net/http" + + "code.chrissexton.org/cws/happy/mood" + + "github.com/rs/zerolog/log" +) + +func (web *Web) getMoods(w http.ResponseWriter, r *http.Request) { + log.Debug().Interface("req", r).Msg("getMoods") + q := `select mc.id category_id,mc.name category_name,mct.key,mct.value + from mood_categories mc + inner join mood_category_texts mct + on mc.id=mct.mood_category_id` + recs := []mood.GetMoodsResponse{} + err := web.db.Select(&recs, q) + if err != nil { + log.Error().Err(err).Msg("could not retrieve mood categories and texts") + w.WriteHeader(500) + fmt.Fprintf(w, "Error getting moods: %s", err) + return + } + resp, err := json.Marshal(recs) + if err != nil { + log.Error().Err(err).Msg("error from json.Marshal") + w.WriteHeader(500) + fmt.Fprintf(w, "Error getting moods: %s", err) + return + } + fmt.Fprintf(w, "%s", string(resp)) +} + +func (web *Web) handleMood(w http.ResponseWriter, r *http.Request) { + uid := r.Header.Get("X-user-id") + verify := r.Header.Get("X-user-verification") + log.Debug(). + Str("uid", uid). + Str("verify", verify). + Msg("handleMood") + dec := json.NewDecoder(r.Body) + happyReq := mood.GetMoodsResponse{} + err := dec.Decode(&happyReq) + if err != nil { + log.Error().Err(err).Msg("error with happy") + w.WriteHeader(400) + fmt.Fprintf(w, err.Error()) + return + } + log.Debug(). + Interface("mood", happyReq). + Msg("mood") + user, err := web.uf.FromStr(uid, verify) + if err != nil { + log.Error(). + Err(err). + Msg("error getting user") + w.WriteHeader(403) + fmt.Fprintf(w, "Error: %s", err) + return + } + if err := web.mood.RecordMood(happyReq, user); err != nil { + log.Error().Err(err).Msg("error saving mood") + w.WriteHeader(500) + fmt.Fprintf(w, "Error: %s", err) + return + } + fmt.Fprintf(w, "ok") +} diff --git a/web/routes.go b/web/routes.go new file mode 100644 index 0000000..112229d --- /dev/null +++ b/web/routes.go @@ -0,0 +1,70 @@ +package web + +import ( + "time" + + "code.chrissexton.org/cws/happy/mood" + + "code.chrissexton.org/cws/happy/user" + + packr "github.com/gobuffalo/packr/v2" + + "code.chrissexton.org/cws/happy/email" + "github.com/speps/go-hashids" + + "code.chrissexton.org/cws/happy/db" + "github.com/gorilla/mux" + "github.com/rs/zerolog/log" + "github.com/stretchr/graceful" +) + +type Web struct { + addr string + assetPath string + db *db.Database + salt string + h *hashids.HashID + box *packr.Box + email *email.EMailClient + uf *user.UserFactory + mood *mood.Mood +} + +func New(addr, assetPath string, db *db.Database, salt string, h *hashids.HashID, box *packr.Box, email *email.EMailClient) *Web { + w := &Web{ + addr: addr, + assetPath: assetPath, + db: db, + box: box, + email: email, + uf: user.NewFactory(db, salt, h), + mood: mood.New(db), + } + if err := db.MakeDB(); err != nil { + log.Fatal(). + Err(err). + Msg("could not create database") + } + if email != nil { + u, _ := w.uf.NewUser() + w.email.SendNewUserMail("chris@chrissexton.org", u, "http://happy.chrissexton.org") + } + return w +} + +func (web *Web) routeSetup() *mux.Router { + r := mux.NewRouter() + api := r.PathPrefix("/v1/").Subrouter() + api.HandleFunc("/moods", web.getMoods).Methods("GET") + api.HandleFunc("/moods", web.handleMood).Methods("POST") + api.HandleFunc("/user/code", web.handlerRegisterCode).Methods("GET") + api.HandleFunc("/user/info", web.checkUser).Methods("GET") + r.PathPrefix("/").HandlerFunc(web.indexHandler("/index.html")) + return r +} + +func (web *Web) Serve() { + middle := web.routeSetup() + log.Info().Str("addr", "http://"+web.addr).Msg("serving HTTP") + graceful.Run(web.addr, 10*time.Second, middle) +} diff --git a/web/user_handlers.go b/web/user_handlers.go new file mode 100644 index 0000000..d15b394 --- /dev/null +++ b/web/user_handlers.go @@ -0,0 +1,72 @@ +package web + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/rs/zerolog/log" +) + +var Develop = false + +type RegisterResponse struct { + ID string + DateCreated int64 + Verification string `json:",omitempty"` +} + +func (web *Web) handlerRegisterCode(w http.ResponseWriter, r *http.Request) { + uid, err := web.uf.NewUser() + if err != nil { + w.WriteHeader(500) + log.Error().Err(err).Msg("error from NewUserID") + fmt.Fprintf(w, "Error registering user: %s", err) + return + } + if err != nil { + w.WriteHeader(500) + log.Error().Err(err).Msg("error converting date") + fmt.Fprintf(w, "Error registering user: %s", err) + return + } + resp := RegisterResponse{ + ID: uid.String(), + DateCreated: uid.DateCreated.Int64, + } + if Develop { + resp.Verification, _ = web.h.EncodeInt64([]int64{uid.Verification}) + } + out, err := json.Marshal(resp) + if err != nil { + w.WriteHeader(500) + log.Error().Err(err).Msg("error from json.Marshal") + fmt.Fprintf(w, "Error registering user: %s", err) + return + } + fmt.Fprintf(w, "%s", string(out)) +} + +func (web *Web) checkUser(w http.ResponseWriter, r *http.Request) { + uid := r.Header.Get("X-user-id") + verify := r.Header.Get("X-user-verification") + log.Debug(). + Str("uid", uid). + Str("verify", verify). + Msg("checkUser") + user, err := web.uf.FromStr(uid, verify) + if err != nil { + log.Error().Err(err).Msg("user not known") + w.WriteHeader(http.StatusUnauthorized) + fmt.Fprint(w, "User not known") + return + } + j, err := json.Marshal(user) + if err != nil { + w.WriteHeader(500) + log.Error().Err(err).Msg("could not marshal user") + fmt.Fprintf(w, "%s", err) + return + } + w.Write(j) +} diff --git a/web/web_handlers.go b/web/web_handlers.go new file mode 100644 index 0000000..80b7744 --- /dev/null +++ b/web/web_handlers.go @@ -0,0 +1,41 @@ +package web + +import ( + "net/http" + "path" + + "github.com/rs/zerolog/log" +) + +func (web *Web) indexHandler(entryPoint string) func(w http.ResponseWriter, r *http.Request) { + fn := func(w http.ResponseWriter, r *http.Request) { + p := path.Clean(r.URL.Path) + + if web.box.Has(p) && !web.box.HasDir(p) { + f, err := web.box.Find(p) + if err != nil { + log.Error().Err(err).Msg("Error finding file") + w.WriteHeader(http.StatusNotFound) + } + w.Write(f) + return + } + if web.box.HasDir(p) && web.box.Has(path.Join(p, "index.html")) { + f, err := web.box.Find(path.Join(p, "index.html")) + if err != nil { + log.Error().Err(err).Msg("Error finding file") + w.WriteHeader(http.StatusNotFound) + } + w.Write(f) + return + } + + if f, err := web.box.Find(p); err != nil { + w.Write(f) + return + } + + w.WriteHeader(http.StatusNotFound) + } + return fn +}