1
0
Fork 0
httpserver/middleware/middleware.go

80 Zeilen
1.9 KiB
Go

package middleware
2021-01-09 20:39:05 +00:00
import (
"net/http"
"github.com/gin-gonic/gin"
2022-11-05 07:29:17 +00:00
"github.com/rs/xid"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
2021-01-18 23:13:35 +00:00
"go.sebtobie.de/httpserver/auth"
"go.sebtobie.de/httpserver/constants"
2021-01-09 20:39:05 +00:00
)
2022-11-05 07:44:37 +00:00
// LogMiddleware is an middleware to log requests to rs/zerolog and catches panics.
2021-01-18 23:18:08 +00:00
// If it is added multiple times, only the first time sends entries to the log.
2021-01-09 20:39:05 +00:00
func LogMiddleware(c *gin.Context) {
2021-01-18 23:18:08 +00:00
if _, exists := c.Get("xid"); exists {
return
2021-01-09 20:39:05 +00:00
}
2022-11-05 07:29:17 +00:00
id := xid.New()
c.Set("xid", id)
2021-01-09 20:39:05 +00:00
defer func() {
2022-11-05 07:29:17 +00:00
var entry *zerolog.Event
interrupt := recover()
if interrupt != nil {
err := interrupt.(error)
2022-11-05 07:29:17 +00:00
c.Header("requestid", id.String())
2021-01-09 20:39:05 +00:00
c.AbortWithStatus(http.StatusInternalServerError)
entry = log.Error().Err(err).Int("statuscode", 500)
entry.Stack()
2021-01-09 20:39:05 +00:00
} else {
2021-01-10 14:15:29 +00:00
statuscode := c.Writer.Status()
switch {
case statuscode >= 400 && statuscode < 500:
entry = log.Warn()
case statuscode >= 500:
2021-01-09 20:39:05 +00:00
entry = log.Error()
default:
entry = log.Info()
2021-01-09 20:39:05 +00:00
}
entry.Int("statuscode", statuscode)
2021-01-09 20:39:05 +00:00
}
2022-11-05 07:29:17 +00:00
entry.Bytes("xid", id.Bytes()).Msg("Request")
2021-01-09 20:39:05 +00:00
}()
c.Next()
}
2021-01-18 23:13:35 +00:00
// 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)
2021-01-18 23:13:35 +00:00
if acc.Anonymous() {
acc.Redirect(c)
c.Abort()
2021-01-18 23:13:35 +00:00
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
}