From 2d22877f11573e2244473708fd1e1897dcd414ac Mon Sep 17 00:00:00 2001 From: vilmibm Date: Fri, 17 Jun 2022 16:01:25 -0500 Subject: [PATCH] further unfucking of API/handlers --- server/cmd/api/api.go | 66 ++++++++++++++++++++++---------------- server/cmd/api/api_test.go | 24 +++++++++++--- server/cmd/db/db.go | 4 ++- server/cmd/main.go | 46 +++++--------------------- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/server/cmd/api/api.go b/server/cmd/api/api.go index f608647..aa22c7a 100644 --- a/server/cmd/api/api.go +++ b/server/cmd/api/api.go @@ -35,28 +35,48 @@ type BBJResponse struct { Usermap map[string]db.User `json:"usermap"` } -type APIHandler func() (*BBJResponse, error) +type APIHandler func(*ReqCtx) (*BBJResponse, error) type API struct { - User *db.User Opts config.Options +} + +func NewAPI(opts config.Options) *API { + return &API{Opts: opts} +} + +type ReqCtx struct { + User db.User Req *http.Request } -func NewAPI(opts config.Options, req *http.Request) (*API, error) { - user, err := getUserFromReq(opts, req) - if err != nil { - return nil, &HTTPError{Msg: err.Error(), Code: 403} - } - return &API{ - Opts: opts, - User: user, - Req: req, - }, nil +func (c *ReqCtx) IsGet() bool { + return c.Req.Method == "GET" } -func Invoke(w http.ResponseWriter, apiFn APIHandler) { - resp, err := apiFn() +func (c *ReqCtx) IsPost() bool { + return c.Req.Method == "POST" +} + +func (a *API) Invoke(w http.ResponseWriter, req *http.Request, apiFn APIHandler) { + a.Opts.Logger.Printf("<- %s", req.URL.Path) + user, err := getUserFromReq(a.Opts, req) + if err != nil { + a.Opts.Logger.Printf("failed to get user from req: %s", err.Error()) + w.WriteHeader(500) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(BBJResponse{ + Error: true, + Data: "server error check logs", + }) + } + + ctx := ReqCtx{ + User: *user, + Req: req, + } + + resp, err := apiFn(&ctx) if err != nil { he := &HTTPError{} _ = errors.As(err, &he) @@ -115,16 +135,8 @@ type instanceInfo struct { Admins []string } -func (a *API) IsGet() bool { - return a.Req.Method == "GET" -} - -func (a *API) IsPost() bool { - return a.Req.Method == "POST" -} - -func (a *API) InstanceInfo() (resp *BBJResponse, err error) { - if !a.IsGet() { +func (a *API) InstanceInfo(ctx *ReqCtx) (resp *BBJResponse, err error) { + if !ctx.IsGet() { err = badMethod() return } @@ -140,8 +152,8 @@ func (a *API) InstanceInfo() (resp *BBJResponse, err error) { return } -func (a *API) UserRegister() (resp *BBJResponse, err error) { - if !a.IsPost() { +func (a *API) UserRegister(ctx *ReqCtx) (resp *BBJResponse, err error) { + if !ctx.IsPost() { err = badMethod() return } @@ -151,7 +163,7 @@ func (a *API) UserRegister() (resp *BBJResponse, err error) { } var args AuthArgs - if err = json.NewDecoder(a.Req.Body).Decode(&args); err != nil { + if err = json.NewDecoder(ctx.Req.Body).Decode(&args); err != nil { err = invalidArgs(err.Error()) return } diff --git a/server/cmd/api/api_test.go b/server/cmd/api/api_test.go index e137b28..23482a0 100644 --- a/server/cmd/api/api_test.go +++ b/server/cmd/api/api_test.go @@ -7,6 +7,7 @@ import ( "reflect" "strings" "testing" + "time" "git.tilde.town/tildetown/bbj2/server/cmd/config" "git.tilde.town/tildetown/bbj2/server/cmd/db" @@ -51,8 +52,11 @@ func TestUserRegister(t *testing.T) { name: "user already exists", opts: *opts, setup: func(opts *config.Options) error { - // TODO - return nil + return db.CreateUser(opts.DB, db.User{ + Username: "albertwesker", + Hash: "1234abc", + Created: time.Now(), + }) }, assert: func(t *testing.T) error { // TODO @@ -64,15 +68,27 @@ func TestUserRegister(t *testing.T) { for _, tt := range ts { t.Run(tt.name, func(t *testing.T) { - teardown, err := db.Setup(*opts) + teardown, err := db.Setup(opts) if err != nil { t.Fatalf("could not initialize DB: %s", err.Error()) return } defer teardown() + err = tt.setup(&tt.opts) + if err != nil { + t.Fatalf("setup failed: %s", err.Error()) + return + } + // TODO + err = tt.assert(t) + if err != nil { + t.Fatal(err.Error()) + return + } + }) } } @@ -84,7 +100,7 @@ func TestInstanceInfo(t *testing.T) { return } - teardown, err := db.Setup(*opts) + teardown, err := db.Setup(opts) if err != nil { t.Fatalf("could not initialize DB: %s", err.Error()) return diff --git a/server/cmd/db/db.go b/server/cmd/db/db.go index fc9cbf9..41eaeb8 100644 --- a/server/cmd/db/db.go +++ b/server/cmd/db/db.go @@ -51,7 +51,7 @@ type Message struct { SendRaw int `json:"send_raw"` // TODO bool } -func Setup(opts config.Options) (func(), error) { +func Setup(opts *config.Options) (func(), error) { db, err := sql.Open("sqlite3", opts.Config.DBPath) opts.DB = db return func() { db.Close() }, err @@ -122,5 +122,7 @@ func CreateUser(db *sql.DB, u User) (err error) { _, err = stmt.Exec(id, u.Username, u.Hash, u.Created) + // TODO return user so we have ID + return } diff --git a/server/cmd/main.go b/server/cmd/main.go index 4d0eafe..3980750 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -1,7 +1,6 @@ package main import ( - "encoding/json" "flag" "fmt" "log" @@ -56,7 +55,7 @@ func _main(opts *config.Options) error { opts.Config = *cfg - teardown, err := db.Setup(*opts) + teardown, err := db.Setup(opts) if err != nil { return fmt.Errorf("could not initialize DB: %w", err) } @@ -78,45 +77,16 @@ func _main(opts *config.Options) error { return nil } -func handler(opts config.Options, f http.HandlerFunc) http.HandlerFunc { - // TODO make this more real - return func(w http.ResponseWriter, req *http.Request) { - opts.Logger.Printf("<- %s", req.URL.Path) - // TODO add user info to opts - f(w, req) - } -} - func setupAPI(opts config.Options) { - handleFailedAPICreate := func(w http.ResponseWriter, err error) { - opts.Logger.Printf("failed to create API: %s", err.Error()) - w.WriteHeader(500) - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(api.BBJResponse{ - Error: true, - Data: "server error check logs", - }) - } + a := api.NewAPI(opts) - // TODO could probably generalize this even further but it's fine for now + http.HandleFunc("/instance_info", func(w http.ResponseWriter, req *http.Request) { + a.Invoke(w, req, a.InstanceInfo) + }) - http.HandleFunc("/instance_info", handler(opts, func(w http.ResponseWriter, req *http.Request) { - a, err := api.NewAPI(opts, req) - if err != nil { - handleFailedAPICreate(w, err) - return - } - api.Invoke(w, a.InstanceInfo) - })) - - http.HandleFunc("/user_register", handler(opts, func(w http.ResponseWriter, req *http.Request) { - a, err := api.NewAPI(opts, req) - if err != nil { - handleFailedAPICreate(w, err) - return - } - api.Invoke(w, a.UserRegister) - })) + http.HandleFunc("/user_register", func(w http.ResponseWriter, req *http.Request) { + a.Invoke(w, req, a.UserRegister) + }) }