Files
YouduWiki/backend/middleware/readonly.go
2026-05-21 19:52:45 +08:00

58 lines
1.3 KiB
Go

package middleware
import (
"os"
"strings"
"github.com/labstack/echo/v4"
"github.com/chaitin/panda-wiki/domain"
"github.com/chaitin/panda-wiki/log"
)
type ReadOnlyMiddleware struct {
logger *log.Logger
}
func NewReadonlyMiddleware(logger *log.Logger) *ReadOnlyMiddleware {
return &ReadOnlyMiddleware{
logger: logger.WithModule("middleware.readonly"),
}
}
// echo read only middleware, if request method is not get, return 403 forbidden
func (readonly *ReadOnlyMiddleware) ReadOnly(next echo.HandlerFunc) echo.HandlerFunc {
readonlyMode := os.Getenv("READONLY") == "1" || strings.ToLower(os.Getenv("READONLY")) == "true"
return func(c echo.Context) error {
if !readonlyMode {
return next(c)
}
path := c.Request().URL.Path
// only check /api/v1 path
if strings.HasPrefix(path, "/api/v1") {
method := c.Request().Method
// skip get
// skip /api/v1/user/login
if !isReadOnlyMethod(method) && path != "/api/v1/user/login" {
readonly.logger.Warn("readonly mode rejected request",
"method", method,
"path", path)
return c.JSON(503, domain.PWResponse{
Success: false,
Message: "API is in read-only mode",
})
}
}
return next(c)
}
}
func isReadOnlyMethod(method string) bool {
switch method {
case "GET", "HEAD", "OPTIONS":
return true
default:
return false
}
}