package api import ( "context" "fmt" "net/http" "time" "dns.froth.zone/pomme/internal" "dns.froth.zone/pomme/internal/db" "github.com/go-chi/httplog" "github.com/go-chi/render" "gorm.io/gorm" ) // setDBMiddleware is the http Handler func for the GORM middleware with context. func setDBMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ( pommeDB *gorm.DB ok bool ) c, err := internal.ReadConfig() if err != nil { logHandler(genericResponseFields{"error": err.Error(), "message": "No config file defined:"}) } switch r.Header.Get("User-Agent") { case "pomme-api-test-slave": pommeDB, err, ok = db.InitDb(c.TestDB) default: pommeDB, err, ok = db.InitDb(c.DB) } if err != nil && !ok { logHandler(genericResponseFields{"error": err.Error(), "message": "Error initializing DB"}) err = internal.SysKill() if err != nil { panic("idk what to do with this but syscall.Kill errored out.") } } timeoutContext, cancelContext := context.WithTimeout(context.Background(), time.Second) ctx := context.WithValue(r.Context(), keyPrincipalContextID, pommeDB.WithContext(timeoutContext)) defer cancelContext() next.ServeHTTP(w, r.WithContext(ctx)) }) } func APIError[T ~map[string]any](w http.ResponseWriter, r *http.Request, v T) { w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Content-Type", "application/json; charset=utf-8") logHandler(v) switch v["realm"] { default: w.Header().Add("WWW-Authenticate", fmt.Sprintf(`realm="%s"`, v["realm"].(string))) fallthrough case nil: w.Header().Add("API Error", v["message"].(string)) } w.WriteHeader(v["status"].(int)) // remove unnecessary items from response delete(v, "error") delete(v, "status") render.JSON(w, r, v) } func logHandler(v map[string]any) { logger := httplog.NewLogger("Pomme", httplog.Options{ JSON: true, }) switch v["error"] { default: logger.Error().Msg(v["error"].(string)) fallthrough case nil: logger.Info().Msg(v["message"].(string)) } }