Chore: Remove untyped data map from macaron context (#39077)

This commit is contained in:
Serge Zaitsev 2021-09-13 16:41:03 +03:00 committed by GitHub
parent 1c892a2fc4
commit e1e385b318
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 48 deletions

View File

@ -45,7 +45,6 @@ type Context struct {
Resp ResponseWriter Resp ResponseWriter
params Params params Params
template *template.Template template *template.Template
Data map[string]interface{}
} }
func (ctx *Context) handler() Handler { func (ctx *Context) handler() Handler {

View File

@ -157,7 +157,6 @@ func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Cont
index: 0, index: 0,
Router: m.Router, Router: m.Router,
Resp: NewResponseWriter(req.Method, rw), Resp: NewResponseWriter(req.Method, rw),
Data: make(map[string]interface{}),
} }
req = req.WithContext(context.WithValue(req.Context(), macaronContextKey{}, c)) req = req.WithContext(context.WithValue(req.Context(), macaronContextKey{}, c))
c.Map(c) c.Map(c)

View File

@ -111,9 +111,8 @@ func Auth(options *AuthOptions) macaron.Handler {
requireLogin := !c.AllowAnonymous || forceLogin || options.ReqNoAnonynmous requireLogin := !c.AllowAnonymous || forceLogin || options.ReqNoAnonynmous
if !c.IsSignedIn && options.ReqSignedIn && requireLogin { if !c.IsSignedIn && options.ReqSignedIn && requireLogin {
lookupTokenErr, hasTokenErr := c.Data["lookupTokenErr"].(error)
var revokedErr *models.TokenRevokedError var revokedErr *models.TokenRevokedError
if hasTokenErr && errors.As(lookupTokenErr, &revokedErr) { if errors.As(c.LookupTokenErr, &revokedErr) {
tokenRevoked(c, revokedErr) tokenRevoked(c, revokedErr)
return return
} }

View File

@ -19,9 +19,8 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus"
cw "github.com/weaveworks/common/middleware" cw "github.com/weaveworks/common/middleware"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
) )
@ -29,16 +28,15 @@ import (
func Logger(cfg *setting.Cfg) macaron.Handler { func Logger(cfg *setting.Cfg) macaron.Handler {
return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) { return func(res http.ResponseWriter, req *http.Request, c *macaron.Context) {
start := time.Now() start := time.Now()
c.Data["perfmon.start"] = start
rw := res.(macaron.ResponseWriter) rw := res.(macaron.ResponseWriter)
c.Next() c.Next()
timeTaken := time.Since(start) / time.Millisecond timeTaken := time.Since(start) / time.Millisecond
if timer, ok := c.Data["perfmon.timer"]; ok { ctx := contexthandler.FromContext(c.Req.Context())
timerTyped := timer.(prometheus.Summary) if ctx != nil && ctx.PerfmonTimer != nil {
timerTyped.Observe(float64(timeTaken)) ctx.PerfmonTimer.Observe(float64(timeTaken))
} }
status := rw.Status() status := rw.Status()
@ -48,9 +46,7 @@ func Logger(cfg *setting.Cfg) macaron.Handler {
} }
} }
if ctx, ok := c.Data["ctx"]; ok { if ctx != nil {
ctxTyped := ctx.(*models.ReqContext)
logParams := []interface{}{ logParams := []interface{}{
"method", req.Method, "method", req.Method,
"path", req.URL.Path, "path", req.URL.Path,
@ -61,15 +57,15 @@ func Logger(cfg *setting.Cfg) macaron.Handler {
"referer", req.Referer(), "referer", req.Referer(),
} }
traceID, exist := cw.ExtractTraceID(ctxTyped.Req.Context()) traceID, exist := cw.ExtractTraceID(ctx.Req.Context())
if exist { if exist {
logParams = append(logParams, "traceID", traceID) logParams = append(logParams, "traceID", traceID)
} }
if status >= 500 { if status >= 500 {
ctxTyped.Logger.Error("Request Completed", logParams...) ctx.Logger.Error("Request Completed", logParams...)
} else { } else {
ctxTyped.Logger.Info("Request Completed", logParams...) ctx.Logger.Info("Request Completed", logParams...)
} }
} }
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
) )
@ -23,8 +24,8 @@ func OrgRedirect(cfg *setting.Cfg) macaron.Handler {
return return
} }
ctx, ok := c.Data["ctx"].(*models.ReqContext) ctx := contexthandler.FromContext(req.Context())
if !ok || !ctx.IsSignedIn { if !ctx.IsSignedIn {
return return
} }

View File

@ -26,7 +26,7 @@ import (
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
@ -109,9 +109,9 @@ func Recovery(cfg *setting.Cfg) macaron.Handler {
if r := recover(); r != nil { if r := recover(); r != nil {
panicLogger := log.Root panicLogger := log.Root
// try to get request logger // try to get request logger
if ctx, ok := c.Data["ctx"]; ok { ctx := contexthandler.FromContext(c.Req.Context())
ctxTyped := ctx.(*models.ReqContext) if ctx != nil {
panicLogger = ctxTyped.Logger panicLogger = ctx.Logger
} }
if err, ok := r.(error); ok { if err, ok := r.(error); ok {
@ -132,33 +132,34 @@ func Recovery(cfg *setting.Cfg) macaron.Handler {
return return
} }
c.Data["Title"] = "Server Error" data := struct {
c.Data["AppSubUrl"] = cfg.AppSubURL Title string
c.Data["Theme"] = cfg.DefaultTheme AppSubUrl string
Theme string
ErrorMsg string
}{"Server Error", cfg.AppSubURL, cfg.DefaultTheme, ""}
if setting.Env == setting.Dev { if setting.Env == setting.Dev {
if err, ok := r.(error); ok { if err, ok := r.(error); ok {
c.Data["Title"] = err.Error() data.Title = err.Error()
} }
c.Data["ErrorMsg"] = string(stack) data.ErrorMsg = string(stack)
} }
ctx, ok := c.Data["ctx"].(*models.ReqContext) if ctx != nil && ctx.IsApiRequest() {
if ok && ctx.IsApiRequest() {
resp := make(map[string]interface{}) resp := make(map[string]interface{})
resp["message"] = "Internal Server Error - Check the Grafana server logs for the detailed error message." resp["message"] = "Internal Server Error - Check the Grafana server logs for the detailed error message."
if c.Data["ErrorMsg"] != nil { if data.ErrorMsg != "" {
resp["error"] = fmt.Sprintf("%v - %v", c.Data["Title"], c.Data["ErrorMsg"]) resp["error"] = fmt.Sprintf("%v - %v", data.Title, data.ErrorMsg)
} else { } else {
resp["error"] = c.Data["Title"] resp["error"] = data.Title
} }
c.JSON(500, resp) c.JSON(500, resp)
} else { } else {
c.HTML(500, cfg.ErrTemplateName, c.Data) c.HTML(500, cfg.ErrTemplateName, data)
} }
} }
}() }()

View File

@ -21,22 +21,27 @@ type ReqContext struct {
Logger log.Logger Logger log.Logger
// RequestNonce is a cryptographic request identifier for use with Content Security Policy. // RequestNonce is a cryptographic request identifier for use with Content Security Policy.
RequestNonce string RequestNonce string
PerfmonTimer prometheus.Summary
LookupTokenErr error
} }
// Handle handles and logs error by given status. // Handle handles and logs error by given status.
func (ctx *ReqContext) Handle(cfg *setting.Cfg, status int, title string, err error) { func (ctx *ReqContext) Handle(cfg *setting.Cfg, status int, title string, err error) {
data := struct {
Title string
AppSubUrl string
Theme string
ErrorMsg error
}{title, cfg.AppSubURL, "dark", nil}
if err != nil { if err != nil {
ctx.Logger.Error(title, "error", err) ctx.Logger.Error(title, "error", err)
if setting.Env != setting.Prod { if setting.Env != setting.Prod {
ctx.Data["ErrorMsg"] = err data.ErrorMsg = err
} }
} }
ctx.Data["Title"] = title ctx.HTML(status, cfg.ErrTemplateName, data)
ctx.Data["AppSubUrl"] = cfg.AppSubURL
ctx.Data["Theme"] = "dark"
ctx.HTML(status, cfg.ErrTemplateName, ctx.Data)
} }
func (ctx *ReqContext) IsApiRequest() bool { func (ctx *ReqContext) IsApiRequest() bool {
@ -76,7 +81,7 @@ func (ctx *ReqContext) HasHelpFlag(flag HelpFlags1) bool {
} }
func (ctx *ReqContext) TimeRequest(timer prometheus.Summary) { func (ctx *ReqContext) TimeRequest(timer prometheus.Summary) {
ctx.Data["perfmon.timer"] = timer ctx.PerfmonTimer = timer
} }
// QueryBoolWithDefault extracts a value from the request query params and applies a bool default if not present. // QueryBoolWithDefault extracts a value from the request query params and applies a bool default if not present.

View File

@ -58,10 +58,7 @@ func TestInitContextWithAuthProxy_CachedInvalidUserID(t *testing.T) {
req, err := http.NewRequest("POST", "http://example.com", nil) req, err := http.NewRequest("POST", "http://example.com", nil)
require.NoError(t, err) require.NoError(t, err)
ctx := &models.ReqContext{ ctx := &models.ReqContext{
Context: &macaron.Context{ Context: &macaron.Context{Req: req},
Req: req,
Data: map[string]interface{}{},
},
Logger: log.New("Test"), Logger: log.New("Test"),
} }
req.Header.Set(svc.Cfg.AuthProxyHeaderName, name) req.Header.Set(svc.Cfg.AuthProxyHeaderName, name)

View File

@ -121,7 +121,6 @@ func (h *ContextHandler) Middleware(mContext *macaron.Context) {
} }
reqContext.Logger = log.New("context", "userId", reqContext.UserId, "orgId", reqContext.OrgId, "uname", reqContext.Login) reqContext.Logger = log.New("context", "userId", reqContext.UserId, "orgId", reqContext.OrgId, "uname", reqContext.Login)
reqContext.Data["ctx"] = reqContext
span.LogFields( span.LogFields(
ol.String("uname", reqContext.Login), ol.String("uname", reqContext.Login),
@ -299,7 +298,7 @@ func (h *ContextHandler) initContextWithToken(reqContext *models.ReqContext, org
token, err := h.AuthTokenService.LookupToken(ctx, rawToken) token, err := h.AuthTokenService.LookupToken(ctx, rawToken)
if err != nil { if err != nil {
reqContext.Logger.Error("Failed to look up user based on cookie", "error", err) reqContext.Logger.Error("Failed to look up user based on cookie", "error", err)
reqContext.Data["lookupTokenErr"] = err reqContext.LookupTokenErr = err
return false return false
} }