pomme/internal/api/helpers.go
2023-05-28 01:36:23 -04:00

109 lines
2.7 KiB
Go

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 pommeLogger(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)
}