58 lines
1.3 KiB
Go
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
|
|
}
|
|
}
|