Chore: replace macaron with web package (#40136)

* replace macaron with web package

* add web.go
This commit is contained in:
Serge Zaitsev
2021-10-11 14:30:59 +02:00
committed by GitHub
parent 78ebac0116
commit 57fcfd578d
70 changed files with 369 additions and 375 deletions

View File

@@ -7,12 +7,11 @@ import (
"strconv"
"strings"
macaron "gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
type AuthOptions struct {
@@ -80,7 +79,7 @@ func EnsureEditorOrViewerCanEdit(c *models.ReqContext) {
}
}
func RoleAuth(roles ...models.RoleType) macaron.Handler {
func RoleAuth(roles ...models.RoleType) web.Handler {
return func(c *models.ReqContext) {
ok := false
for _, role := range roles {
@@ -95,7 +94,7 @@ func RoleAuth(roles ...models.RoleType) macaron.Handler {
}
}
func Auth(options *AuthOptions) macaron.Handler {
func Auth(options *AuthOptions) web.Handler {
return func(c *models.ReqContext) {
forceLogin := false
if c.AllowAnonymous {
@@ -134,7 +133,7 @@ func Auth(options *AuthOptions) macaron.Handler {
// feature flag is enabled.
// Intended for when feature flags open up access to APIs that
// are otherwise only available to admins.
func AdminOrFeatureEnabled(enabled bool) macaron.Handler {
func AdminOrFeatureEnabled(enabled bool) web.Handler {
return func(c *models.ReqContext) {
if c.OrgRole == models.ROLE_ADMIN {
return
@@ -148,7 +147,7 @@ func AdminOrFeatureEnabled(enabled bool) macaron.Handler {
// SnapshotPublicModeOrSignedIn creates a middleware that allows access
// if snapshot public mode is enabled or if user is signed in.
func SnapshotPublicModeOrSignedIn(cfg *setting.Cfg) macaron.Handler {
func SnapshotPublicModeOrSignedIn(cfg *setting.Cfg) web.Handler {
return func(c *models.ReqContext) {
if cfg.SnapshotPublicMode {
return
@@ -169,7 +168,7 @@ func ReqNotSignedIn(c *models.ReqContext) {
// NoAuth creates a middleware that doesn't require any authentication.
// If forceLogin param is set it will redirect the user to the login page.
func NoAuth() macaron.Handler {
func NoAuth() web.Handler {
return func(c *models.ReqContext) {
if shouldForceLogin(c) {
notAuthorized(c)

View File

@@ -8,12 +8,12 @@ import (
"net/http"
"strings"
macaron "gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/web"
)
type gzipResponseWriter struct {
w *gzip.Writer
macaron.ResponseWriter
web.ResponseWriter
}
func (grw *gzipResponseWriter) WriteHeader(c int) {
@@ -68,7 +68,7 @@ func Gziper() func(http.Handler) http.Handler {
return
}
grw := &gzipResponseWriter{gzip.NewWriter(rw), rw.(macaron.ResponseWriter)}
grw := &gzipResponseWriter{gzip.NewWriter(rw), rw.(web.ResponseWriter)}
grw.Header().Set("Content-Encoding", "gzip")
grw.Header().Set("Vary", "Accept-Encoding")

View File

@@ -21,15 +21,15 @@ import (
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
cw "github.com/weaveworks/common/middleware"
"gopkg.in/macaron.v1"
)
func Logger(cfg *setting.Cfg) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
func Logger(cfg *setting.Cfg) web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
start := time.Now()
rw := res.(macaron.ResponseWriter)
rw := res.(web.ResponseWriter)
c.Next()
timeTaken := time.Since(start) / time.Millisecond

View File

@@ -4,10 +4,9 @@ import (
"fmt"
"strings"
macaron "gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
var (
@@ -25,9 +24,9 @@ func HandleNoCacheHeader(ctx *models.ReqContext) {
ctx.SkipCache = ctx.Req.Header.Get("X-Grafana-NoCache") == "true"
}
func AddDefaultResponseHeaders(cfg *setting.Cfg) macaron.Handler {
return func(c *macaron.Context) {
c.Resp.Before(func(w macaron.ResponseWriter) {
func AddDefaultResponseHeaders(cfg *setting.Cfg) web.Handler {
return func(c *web.Context) {
c.Resp.Before(func(w web.ResponseWriter) {
// if response has already been written, skip.
if w.Written() {
return
@@ -47,7 +46,7 @@ func AddDefaultResponseHeaders(cfg *setting.Cfg) macaron.Handler {
}
// addSecurityHeaders adds HTTP(S) response headers that enable various security protections in the client's browser.
func addSecurityHeaders(w macaron.ResponseWriter, cfg *setting.Cfg) {
func addSecurityHeaders(w web.ResponseWriter, cfg *setting.Cfg) {
if (cfg.Protocol == setting.HTTPSScheme || cfg.Protocol == setting.HTTP2Scheme) && cfg.StrictTransportSecurity {
strictHeaderValues := []string{fmt.Sprintf("max-age=%v", cfg.StrictTransportSecurityMaxAge)}
if cfg.StrictTransportSecurityPreload {
@@ -68,12 +67,12 @@ func addSecurityHeaders(w macaron.ResponseWriter, cfg *setting.Cfg) {
}
}
func addNoCacheHeaders(w macaron.ResponseWriter) {
func addNoCacheHeaders(w web.ResponseWriter) {
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "-1")
}
func addXFrameOptionsDenyHeader(w macaron.ResponseWriter) {
func addXFrameOptionsDenyHeader(w web.ResponseWriter) {
w.Header().Set("X-Frame-Options", "deny")
}

View File

@@ -11,10 +11,6 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
@@ -30,6 +26,9 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func fakeGetTime() func() time.Time {
@@ -628,10 +627,10 @@ func middlewareScenario(t *testing.T, desc string, fn scenarioFunc, cbs ...func(
require.NoError(t, err)
require.Truef(t, exists, "Views directory should exist at %q", viewsPath)
sc.m = macaron.New()
sc.m = web.New()
sc.m.Use(AddDefaultResponseHeaders(cfg))
sc.m.UseMiddleware(AddCSPHeader(cfg, logger))
sc.m.UseMiddleware(macaron.Renderer(viewsPath, "[[", "]]"))
sc.m.UseMiddleware(web.Renderer(viewsPath, "[[", "]]"))
ctxHdlr := getContextHandler(t, cfg)
sc.sqlStore = ctxHdlr.SQLStore

View File

@@ -10,13 +10,13 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/web"
)
// OrgRedirect changes org and redirects users if the
// querystring `orgId` doesn't match the active org.
func OrgRedirect(cfg *setting.Cfg) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
func OrgRedirect(cfg *setting.Cfg) web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
orgIdValue := req.URL.Query().Get("orgId")
orgId, err := strconv.ParseInt(orgIdValue, 10, 64)

View File

@@ -3,19 +3,18 @@ package middleware
import (
"fmt"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/web"
)
// Quota returns a function that returns a function used to call quotaservice based on target name
func Quota(quotaService *quota.QuotaService) func(string) macaron.Handler {
func Quota(quotaService *quota.QuotaService) func(string) web.Handler {
if quotaService == nil {
panic("quotaService is nil")
}
//https://open.spotify.com/track/7bZSoBEAEEUsGEuLOf94Jm?si=T1Tdju5qRSmmR0zph_6RBw fuuuuunky
return func(target string) macaron.Handler {
return func(target string) web.Handler {
return func(c *models.ReqContext) {
limitReached, err := quotaService.QuotaReached(c, target)
if err != nil {

View File

@@ -9,8 +9,8 @@ import (
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
macaron "gopkg.in/macaron.v1"
)
func TestMiddlewareQuota(t *testing.T) {
@@ -266,7 +266,7 @@ func TestMiddlewareQuota(t *testing.T) {
})
}
func getQuotaHandler(sc *scenarioContext, target string) macaron.Handler {
func getQuotaHandler(sc *scenarioContext, target string) web.Handler {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
qs := &quota.QuotaService{
AuthTokenService: fakeAuthTokenService,

View File

@@ -3,10 +3,9 @@ package middleware
import (
"time"
"golang.org/x/time/rate"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/web"
"golang.org/x/time/rate"
)
type getTimeFn func() time.Time
@@ -14,7 +13,7 @@ type getTimeFn func() time.Time
// RateLimit is a very basic rate limiter.
// Will allow average of "rps" requests per second over an extended period of time, with max "burst" requests at the same time.
// getTime should return the current time. For non-testing purposes use time.Now
func RateLimit(rps, burst int, getTime getTimeFn) macaron.Handler {
func RateLimit(rps, burst int, getTime getTimeFn) web.Handler {
l := rate.NewLimiter(rate.Limit(rps), burst)
return func(c *models.ReqContext) {
if !l.AllowN(getTime(), 1) {

View File

@@ -9,9 +9,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/macaron.v1"
)
type execFunc func() *httptest.ResponseRecorder
@@ -31,8 +31,8 @@ func rateLimiterScenario(t *testing.T, desc string, rps int, burst int, fn rateL
cfg := setting.NewCfg()
m := macaron.New()
m.UseMiddleware(macaron.Renderer("../../public/views", "[[", "]]"))
m := web.New()
m.UseMiddleware(web.Renderer("../../public/views", "[[", "]]"))
m.Use(getContextHandler(t, cfg).Middleware)
m.Get("/foo", RateLimit(rps, burst, func() time.Time { return currentTime }), defaultHandler)

View File

@@ -23,11 +23,10 @@ import (
"net/http"
"runtime"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
var (
@@ -103,8 +102,8 @@ func function(pc uintptr) []byte {
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
// While Martini is in development mode, Recovery will also output the panic as HTML.
func Recovery(cfg *setting.Cfg) macaron.Handler {
return func(c *macaron.Context) {
func Recovery(cfg *setting.Cfg) web.Handler {
return func(c *web.Context) {
defer func() {
if r := recover(); r != nil {
panicLogger := log.Root

View File

@@ -10,9 +10,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
macaron "gopkg.in/macaron.v1"
)
func TestRecoveryMiddleware(t *testing.T) {
@@ -61,11 +61,11 @@ func recoveryScenario(t *testing.T, desc string, url string, fn scenarioFunc) {
viewsPath, err := filepath.Abs("../../public/views")
require.NoError(t, err)
sc.m = macaron.New()
sc.m = web.New()
sc.m.Use(Recovery(cfg))
sc.m.Use(AddDefaultResponseHeaders(cfg))
sc.m.UseMiddleware(macaron.Renderer(viewsPath, "[[", "]]"))
sc.m.UseMiddleware(web.Renderer(viewsPath, "[[", "]]"))
sc.userAuthTokenService = auth.NewFakeUserAuthTokenService()
sc.remoteCacheService = remotecache.NewFakeStore(t)

View File

@@ -8,9 +8,9 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/prometheus/client_golang/prometheus"
cw "github.com/weaveworks/common/middleware"
"gopkg.in/macaron.v1"
)
var (
@@ -45,10 +45,10 @@ func init() {
}
// RequestMetrics is a middleware handler that instruments the request.
func RequestMetrics(cfg *setting.Cfg) func(handler string) macaron.Handler {
return func(handler string) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
rw := res.(macaron.ResponseWriter)
func RequestMetrics(cfg *setting.Cfg) func(handler string) web.Handler {
return func(handler string) web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
rw := res.(web.ResponseWriter)
now := time.Now()
httpRequestsInFlight.Inc()
defer httpRequestsInFlight.Dec()

View File

@@ -9,7 +9,7 @@ import (
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/web"
)
type contextKey struct{}
@@ -19,8 +19,8 @@ var routeOperationNameKey = contextKey{}
// ProvideRouteOperationName creates a named middleware responsible for populating
// the context with the route operation name that can be used later in the request pipeline.
// Implements routing.RegisterNamedMiddleware.
func ProvideRouteOperationName(name string) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
func ProvideRouteOperationName(name string) web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
ctx := context.WithValue(c.Req.Context(), routeOperationNameKey, name)
c.Req = c.Req.WithContext(ctx)
}
@@ -36,15 +36,15 @@ func RouteOperationNameFromContext(ctx context.Context) (string, bool) {
return "", false
}
func RequestTracing() macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
func RequestTracing() web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
if strings.HasPrefix(c.Req.URL.Path, "/public/") ||
c.Req.URL.Path == "robots.txt" {
c.Next()
return
}
rw := res.(macaron.ResponseWriter)
rw := res.(web.ResponseWriter)
tracer := opentracing.GlobalTracer()
wireContext, _ := tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))

View File

@@ -6,20 +6,19 @@ import (
"net/http/httptest"
"testing"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
)
type scenarioContext struct {
t *testing.T
m *macaron.Macaron
m *web.Mux
context *models.ReqContext
resp *httptest.ResponseRecorder
apiKey string
@@ -28,7 +27,7 @@ type scenarioContext struct {
tokenSessionCookie string
respJson map[string]interface{}
handlerFunc handlerFunc
defaultHandler macaron.Handler
defaultHandler web.Handler
url string
userAuthTokenService *auth.FakeUserAuthTokenService
jwtAuthService *models.FakeJWTService

View File

@@ -5,10 +5,10 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/web"
)
func ValidateHostHeader(cfg *setting.Cfg) macaron.Handler {
func ValidateHostHeader(cfg *setting.Cfg) web.Handler {
return func(c *models.ReqContext) {
// ignore local render calls
if c.IsRenderCall {