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" ) var mode string // 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 ) logger := newResponder() c, err := internal.ReadConfig() if err != nil { logger.Response = Response{ Message: "No config file defined", Err: err.Error(), } logger.newLogEntry().panicLogger(logger.Response) } pommeDB, err, ok = db.InitDb(c.DB, mode) if err != nil && !ok { logger.Response = Response{ Message: "Error initializing DB", Err: err.Error(), } logger.newLogEntry().panicLogger(logger.Response) } 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 setLoggerMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { logger := newResponder() ctx := context.WithValue(r.Context(), keyLoggerContextID, logger) next.ServeHTTP(w, r.WithContext(ctx)) }) } // newLogEntry takes a Response struct and starts a new response chain. func (e *Responder) newLogEntry() *Responder { return &Responder{} } // apiError sends unsuccessful API requests back to the user with the appropriate information. func (e *Responder) apiError(logEntry Response, w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Content-Type", "application/json; charset=utf-8") if logEntry.Realm != "" { w.Header().Add("WWW-Authenticate", fmt.Sprintf(`realm="%v"`, logEntry.Realm)) } w.Header().Add("API Error", logEntry.Message) w.WriteHeader(logEntry.Status) if logEntry.Err != "" { logEntry.Err = "" } // nullify errors before returning to user render.JSON(w, r, logEntry) } func (e *Responder) panicLogger(logEntry Response) { logger := httplog.NewLogger("Pomme", httplog.Options{ JSON: true, }) logger.Panic().Msg(logEntry.Message) } func (e *Responder) infoLogger(logEntry Response) { logger := httplog.NewLogger("Pomme", httplog.Options{ JSON: true, }) logger.Info().Msg(logEntry.Message) } func (e *Responder) errorLogger(logEntry Response) { logger := httplog.NewLogger("Pomme", httplog.Options{ JSON: true, }) logger.Error().Msg(logEntry.Err) }