package middleware import ( "net/http" "github.com/gin-gonic/gin" "github.com/rs/xid" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "go.sebtobie.de/httpserver/auth" "go.sebtobie.de/httpserver/constants" ) // LogMiddleware is an middleware to log requests to rs/zerolog and catches panics. // If it is added multiple times, only the first time sends entries to the log. func LogMiddleware(c *gin.Context) { if _, exists := c.Get("xid"); exists { return } id := xid.New() c.Set("xid", id) defer func() { var entry *zerolog.Event interrupt := recover() if interrupt != nil { err := interrupt.(error) c.Header("requestid", id.String()) c.AbortWithStatus(http.StatusInternalServerError) entry = log.Error().Err(err).Int("statuscode", 500) entry.Stack() } else { statuscode := c.Writer.Status() switch { case statuscode >= 400 && statuscode < 500: entry = log.Warn() case statuscode >= 500: entry = log.Error() default: entry = log.Info() } entry.Int("statuscode", statuscode) } entry.Str("xid", id.String()).Msg("Request") }() c.Next() } // RequireUser is an middleware that looks if the user is an Anonymous user and redircts it to the login if so. func RequireUser(c *gin.Context) { var acc = c.MustGet(constants.Accounts).(auth.Account) if acc.Anonymous() { acc.Redirect(c) c.Abort() return } } // Config is the type For Configuration of the Middleware type Config map[string]any // Middleware is an type to Save data between executions and to provide help at the teardown. type Middleware interface { Gin(*gin.Context) Defaults() Config Setup(Config) Teardown() } // PreSetupMiddleware is for middleware that only needs the sites after their initialization type PreSetupMiddleware interface { Middleware PreSetup([]any) error } // PostSetupMiddleware is for middleware that requires sites to be already configured type PostSetupMiddleware interface { Middleware PostSetup([]any) error }