mirror of
https://git.freecumextremist.com/grumbulon/pomme.git
synced 2024-11-13 06:54:11 +00:00
122 lines
2.6 KiB
Go
122 lines
2.6 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
|
|
)
|
|
|
|
c, err := internal.ReadConfig()
|
|
if err != nil {
|
|
logger := newResponder(Response[any]{
|
|
Message: "No config file defined",
|
|
Err: err.Error(),
|
|
})
|
|
logger.writeLogEntry()
|
|
}
|
|
|
|
pommeDB, err, ok = db.InitDb(c.DB, mode)
|
|
|
|
if err != nil && !ok {
|
|
logger := newResponder(Response[any]{
|
|
Message: "Error initializing DB",
|
|
Err: err.Error(),
|
|
})
|
|
logger.writeLogEntry()
|
|
err = internal.SysKill()
|
|
if err != nil {
|
|
panic("this should not happen.")
|
|
}
|
|
}
|
|
|
|
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))
|
|
})
|
|
}
|
|
|
|
// apiError sends unsuccessful API requests back to the user with the appropriate information.
|
|
func (e *Response[T]) apiError(w http.ResponseWriter, r *http.Request) {
|
|
v := map[string]any{
|
|
"message": e.Message,
|
|
"status": e.Status,
|
|
"realm": e.Realm,
|
|
"error": e.Err,
|
|
}
|
|
|
|
message, ok := v["message"].(string)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
|
|
switch v["realm"] {
|
|
default:
|
|
w.Header().Add("WWW-Authenticate", fmt.Sprintf(`realm="%v"`, e.Realm))
|
|
delete(v, "realm")
|
|
|
|
fallthrough
|
|
case nil:
|
|
w.Header().Add("API Error", message)
|
|
}
|
|
|
|
w.WriteHeader(v["status"].(int))
|
|
|
|
delete(v, "error")
|
|
delete(v, "status")
|
|
delete(v, "realm")
|
|
|
|
render.JSON(w, r, v)
|
|
}
|
|
|
|
// writeLogEntry takes a response struct and writes info and error level logs
|
|
// todo: make it write to file maybe
|
|
func (e *Response[T]) writeLogEntry() {
|
|
logger := httplog.NewLogger("Pomme", httplog.Options{
|
|
JSON: true,
|
|
})
|
|
|
|
v := map[string]any{
|
|
"message": e.Message,
|
|
"error": e.Err,
|
|
}
|
|
|
|
errorString, ok := v["error"].(string)
|
|
if !ok {
|
|
logger.Error().Msg("unable to convert any type 'error' to string")
|
|
}
|
|
|
|
message, ok := v["message"].(string)
|
|
if !ok {
|
|
logger.Error().Msg("unable to convert any type 'message' to string")
|
|
}
|
|
|
|
switch v["error"] {
|
|
default:
|
|
logger.Error().Msg(errorString)
|
|
|
|
fallthrough
|
|
case nil:
|
|
logger.Info().Msg(message)
|
|
}
|
|
}
|