Backend: Remove more globals (#29644)

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Arve Knudsen
2020-12-15 19:09:04 +01:00
committed by GitHub
parent aa8fb1ae98
commit dd2d206d99
35 changed files with 526 additions and 484 deletions

View File

@@ -24,8 +24,8 @@ func (hs *HTTPServer) registerRoutes() {
reqCanAccessTeams := middleware.AdminOrFeatureEnabled(hs.Cfg.EditorsCanAdmin)
reqSnapshotPublicModeOrSignedIn := middleware.SnapshotPublicModeOrSignedIn(hs.Cfg)
redirectFromLegacyDashboardURL := middleware.RedirectFromLegacyDashboardURL()
redirectFromLegacyDashboardSoloURL := middleware.RedirectFromLegacyDashboardSoloURL()
redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL()
redirectFromLegacyDashboardSoloURL := middleware.RedirectFromLegacyDashboardSoloURL(hs.Cfg)
redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL(hs.Cfg)
quota := middleware.Quota(hs.QuotaService)
bind := binding.Bind

View File

@@ -8,6 +8,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/fs"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
@@ -26,7 +27,7 @@ func loggedInUserScenario(t *testing.T, desc string, url string, fn scenarioFunc
func loggedInUserScenarioWithRole(t *testing.T, desc string, method string, url string, routePattern string, role models.RoleType, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
defer bus.ClearBusHandlers()
t.Cleanup(bus.ClearBusHandlers)
sc := setupScenarioContext(t, url)
sc.defaultHandler = Wrap(func(c *models.ReqContext) Response {
@@ -129,6 +130,7 @@ func (sc *scenarioContext) fakeReqNoAssertionsWithCookie(method, url string, coo
type scenarioContext struct {
t *testing.T
cfg *setting.Cfg
m *macaron.Macaron
context *models.ReqContext
resp *httptest.ResponseRecorder
@@ -146,12 +148,15 @@ func (sc *scenarioContext) exec() {
type scenarioFunc func(c *scenarioContext)
type handlerFunc func(c *models.ReqContext) Response
func getContextHandler(t *testing.T) *contexthandler.ContextHandler {
func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHandler {
t.Helper()
if cfg == nil {
cfg = setting.NewCfg()
}
sqlStore := sqlstore.InitTestDB(t)
remoteCacheSvc := &remotecache.RemoteCache{}
cfg := setting.NewCfg()
cfg.RemoteCacheOptions = &setting.RemoteCacheOptions{
Name: "database",
}
@@ -187,19 +192,24 @@ func getContextHandler(t *testing.T) *contexthandler.ContextHandler {
}
func setupScenarioContext(t *testing.T, url string) *scenarioContext {
cfg := setting.NewCfg()
sc := &scenarioContext{
url: url,
t: t,
cfg: cfg,
}
viewsPath, err := filepath.Abs("../../public/views")
require.NoError(t, err)
exists, err := fs.Exists(viewsPath)
require.NoError(t, err)
require.Truef(t, exists, "Views should be in %q", viewsPath)
sc.m = macaron.New()
sc.m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: viewsPath,
Delims: macaron.Delims{Left: "[[", Right: "]]"},
}))
sc.m.Use(getContextHandler(t).Middleware)
sc.m.Use(getContextHandler(t, cfg).Middleware)
return sc
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/live"
"github.com/grafana/grafana/pkg/services/provisioning"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -1177,11 +1178,15 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
t.Cleanup(bus.ClearBusHandlers)
cfg := setting.NewCfg()
hs := HTTPServer{
Bus: bus.GetBus(),
Cfg: setting.NewCfg(),
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(),
Live: &live.GrafanaLive{Cfg: setting.NewCfg()},
QuotaService: &quota.QuotaService{
Cfg: cfg,
},
}
sc := setupScenarioContext(t, url)
@@ -1238,11 +1243,13 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
defer bus.ClearBusHandlers()
cfg := setting.NewCfg()
hs := HTTPServer{
Cfg: setting.NewCfg(),
Cfg: cfg,
Bus: bus.GetBus(),
ProvisioningService: provisioning.NewProvisioningServiceMock(),
Live: &live.GrafanaLive{Cfg: setting.NewCfg()},
Live: &live.GrafanaLive{Cfg: cfg},
QuotaService: &quota.QuotaService{Cfg: cfg},
}
sc := setupScenarioContext(t, url)

View File

@@ -52,7 +52,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*macaron.Macaron, *HT
}
m := macaron.New()
m.Use(getContextHandler(t).Middleware)
m.Use(getContextHandler(t, cfg).Middleware)
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: filepath.Join(setting.StaticRootPath, "views"),
IndentJSON: true,

View File

@@ -337,11 +337,11 @@ func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() {
m.Use(hs.metricsEndpoint)
m.Use(hs.ContextHandler.Middleware)
m.Use(middleware.OrgRedirect())
m.Use(middleware.OrgRedirect(hs.Cfg))
// needs to be after context handler
if setting.EnforceDomain {
m.Use(middleware.ValidateHostHeader(hs.Cfg.Domain))
m.Use(middleware.ValidateHostHeader(hs.Cfg))
}
m.Use(middleware.HandleNoCacheHeader())

View File

@@ -458,7 +458,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
func (hs *HTTPServer) Index(c *models.ReqContext) {
data, err := hs.setIndexViewData(c)
if err != nil {
c.Handle(500, "Failed to get settings", err)
c.Handle(hs.Cfg, 500, "Failed to get settings", err)
return
}
c.HTML(200, "index", data)
@@ -472,7 +472,7 @@ func (hs *HTTPServer) NotFoundHandler(c *models.ReqContext) {
data, err := hs.setIndexViewData(c)
if err != nil {
c.Handle(500, "Failed to get settings", err)
c.Handle(hs.Cfg, 500, "Failed to get settings", err)
return
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@@ -187,7 +186,7 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) Response {
user, _, err := ldapServer.User(query.Result.Login)
if err != nil {
if errors.Is(err, multildap.ErrDidNotFindUser) { // User was not in the LDAP server - we need to take action:
if setting.AdminUser == query.Result.Login { // User is *the* Grafana Admin. We cannot disable it.
if hs.Cfg.AdminUser == query.Result.Login { // User is *the* Grafana Admin. We cannot disable it.
errMsg := fmt.Sprintf(`Refusing to sync grafana super admin "%s" - it would be disabled`, query.Result.Login)
ldapLogger.Error(errMsg)
return Error(http.StatusBadRequest, errMsg, err)

View File

@@ -375,7 +375,7 @@ func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
// PostSyncUserWithLDAP tests
// ***
func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(t *testing.T)) *scenarioContext {
func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(*testing.T, *scenarioContext)) *scenarioContext {
t.Helper()
sc := setupScenarioContext(t, requestURL)
@@ -387,7 +387,7 @@ func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(t
setting.LDAPEnabled = true
hs := &HTTPServer{
Cfg: setting.NewCfg(),
Cfg: sc.cfg,
AuthTokenService: auth.NewFakeUserAuthTokenService(),
}
@@ -402,7 +402,7 @@ func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(t
req, err := http.NewRequest(http.MethodPost, requestURL, nil)
require.NoError(t, err)
preHook(t)
preHook(t, sc)
sc.req = req
sc.exec()
@@ -411,7 +411,7 @@ func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(t
}
func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
}
@@ -456,7 +456,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
}
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
}
@@ -484,7 +484,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
}
func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
}
@@ -495,9 +495,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
userSearchError = multildap.ErrDidNotFindUser
admin := setting.AdminUser
t.Cleanup(func() { setting.AdminUser = admin })
setting.AdminUser = "ldap-daniel"
sc.cfg.AdminUser = "ldap-daniel"
bus.AddHandler("test", func(q *models.GetUserByIdQuery) error {
require.Equal(t, q.Id, int64(34))
@@ -527,7 +525,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
}
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T) {
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
}

View File

@@ -77,7 +77,7 @@ func (hs *HTTPServer) CookieOptionsFromCfg() cookies.CookieOptions {
func (hs *HTTPServer) LoginView(c *models.ReqContext) {
viewData, err := setIndexViewData(hs, c)
if err != nil {
c.Handle(500, "Failed to get settings", err)
c.Handle(hs.Cfg, 500, "Failed to get settings", err)
return
}
@@ -117,7 +117,7 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) {
user := &models.User{Id: c.SignedInUser.UserId, Email: c.SignedInUser.Email, Login: c.SignedInUser.Login}
err := hs.loginUserWithUser(user, c)
if err != nil {
c.Handle(500, "Failed to sign in user", err)
c.Handle(hs.Cfg, 500, "Failed to sign in user", err)
return
}
}

View File

@@ -277,7 +277,7 @@ type LoginError struct {
}
func (hs *HTTPServer) handleOAuthLoginError(ctx *models.ReqContext, info models.LoginInfo, err LoginError) {
ctx.Handle(err.HttpStatus, err.PublicMessage, err.Err)
ctx.Handle(hs.Cfg, err.HttpStatus, err.PublicMessage, err.Err)
info.Error = err.Err
if info.Error == nil {

View File

@@ -25,7 +25,11 @@ import (
"github.com/stretchr/testify/require"
)
func mockSetIndexViewData() {
func fakeSetIndexViewData(t *testing.T) {
origSetIndexViewData := setIndexViewData
t.Cleanup(func() {
setIndexViewData = origSetIndexViewData
})
setIndexViewData = func(*HTTPServer, *models.ReqContext) (*dtos.IndexViewData, error) {
data := &dtos.IndexViewData{
User: &dtos.CurrentUser{},
@@ -36,22 +40,16 @@ func mockSetIndexViewData() {
}
}
func resetSetIndexViewData() {
setIndexViewData = (*HTTPServer).setIndexViewData
}
func mockViewIndex() {
func fakeViewIndex(t *testing.T) {
origGetViewIndex := getViewIndex
t.Cleanup(func() {
getViewIndex = origGetViewIndex
})
getViewIndex = func() string {
return "index-template"
}
}
func resetViewIndex() {
getViewIndex = func() string {
return ViewIndex
}
}
func getBody(resp *httptest.ResponseRecorder) (string, error) {
responseData, err := ioutil.ReadAll(resp.Body)
if err != nil {
@@ -86,16 +84,15 @@ type redirectCase struct {
redirectURL string
}
func TestLoginErrorCookieApiEndpoint(t *testing.T) {
mockSetIndexViewData()
defer resetSetIndexViewData()
func TestLoginErrorCookieAPIEndpoint(t *testing.T) {
fakeSetIndexViewData(t)
mockViewIndex()
defer resetViewIndex()
fakeViewIndex(t)
sc := setupScenarioContext(t, "/login")
cfg := setting.NewCfg()
hs := &HTTPServer{
Cfg: setting.NewCfg(),
Cfg: cfg,
License: &licensing.OSSLicensingService{},
}
@@ -103,7 +100,7 @@ func TestLoginErrorCookieApiEndpoint(t *testing.T) {
hs.LoginView(c)
})
setting.LoginCookieName = "grafana_session"
cfg.LoginCookieName = "grafana_session"
setting.SecretKey = "login_testing"
setting.OAuthService = &setting.OAuther{}
@@ -142,11 +139,9 @@ func TestLoginErrorCookieApiEndpoint(t *testing.T) {
}
func TestLoginViewRedirect(t *testing.T) {
mockSetIndexViewData()
defer resetSetIndexViewData()
fakeSetIndexViewData(t)
mockViewIndex()
defer resetViewIndex()
fakeViewIndex(t)
sc := setupScenarioContext(t, "/login")
hs := &HTTPServer{
Cfg: setting.NewCfg(),
@@ -318,11 +313,9 @@ func TestLoginViewRedirect(t *testing.T) {
}
func TestLoginPostRedirect(t *testing.T) {
mockSetIndexViewData()
defer resetSetIndexViewData()
fakeSetIndexViewData(t)
mockViewIndex()
defer resetViewIndex()
fakeViewIndex(t)
sc := setupScenarioContext(t, "/login")
hs := &HTTPServer{
log: &FakeLogger{},
@@ -478,8 +471,7 @@ func TestLoginPostRedirect(t *testing.T) {
}
func TestLoginOAuthRedirect(t *testing.T) {
mockSetIndexViewData()
defer resetSetIndexViewData()
fakeSetIndexViewData(t)
sc := setupScenarioContext(t, "/login")
hs := &HTTPServer{
@@ -511,11 +503,9 @@ func TestLoginOAuthRedirect(t *testing.T) {
}
func TestLoginInternal(t *testing.T) {
mockSetIndexViewData()
defer resetSetIndexViewData()
fakeSetIndexViewData(t)
mockViewIndex()
defer resetViewIndex()
fakeViewIndex(t)
sc := setupScenarioContext(t, "/login")
hs := &HTTPServer{
Cfg: setting.NewCfg(),
@@ -559,24 +549,23 @@ func TestAuthProxyLoginEnableLoginTokenDisabled(t *testing.T) {
func TestAuthProxyLoginWithEnableLoginToken(t *testing.T) {
sc := setupAuthProxyLoginTest(t, true)
require.Equal(t, sc.resp.Code, 302)
assert.Equal(t, sc.resp.Code, 302)
location, ok := sc.resp.Header()["Location"]
assert.True(t, ok)
assert.Equal(t, location[0], "/")
setCookie, ok := sc.resp.Header()["Set-Cookie"]
assert.True(t, ok, "Set-Cookie exists")
setCookie := sc.resp.Header()["Set-Cookie"]
require.NotNil(t, setCookie, "Set-Cookie should exist")
assert.Equal(t, "grafana_session=; Path=/; Max-Age=0; HttpOnly", setCookie[0])
}
func setupAuthProxyLoginTest(t *testing.T, enableLoginToken bool) *scenarioContext {
mockSetIndexViewData()
defer resetSetIndexViewData()
fakeSetIndexViewData(t)
sc := setupScenarioContext(t, "/login")
sc.cfg.LoginCookieName = "grafana_session"
hs := &HTTPServer{
Cfg: setting.NewCfg(),
Cfg: sc.cfg,
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
log: log.New("hello"),
@@ -592,8 +581,8 @@ func setupAuthProxyLoginTest(t *testing.T, enableLoginToken bool) *scenarioConte
setting.OAuthService = &setting.OAuther{}
setting.OAuthService.OAuthInfos = make(map[string]*setting.OAuthInfo)
hs.Cfg.AuthProxyEnabled = true
hs.Cfg.AuthProxyEnableLoginToken = enableLoginToken
sc.cfg.AuthProxyEnabled = true
sc.cfg.AuthProxyEnableLoginToken = enableLoginToken
sc.m.Get(sc.url, sc.defaultHandler)
sc.fakeReqNoAssertions("GET", sc.url).exec()

View File

@@ -17,7 +17,7 @@ import (
func (hs *HTTPServer) RenderToPng(c *models.ReqContext) {
queryReader, err := util.NewURLQueryReader(c.Req.URL)
if err != nil {
c.Handle(400, "Render parameters error", err)
c.Handle(hs.Cfg, 400, "Render parameters error", err)
return
}
@@ -25,25 +25,25 @@ func (hs *HTTPServer) RenderToPng(c *models.ReqContext) {
width, err := strconv.Atoi(queryReader.Get("width", "800"))
if err != nil {
c.Handle(400, "Render parameters error", fmt.Errorf("cannot parse width as int: %s", err))
c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse width as int: %s", err))
return
}
height, err := strconv.Atoi(queryReader.Get("height", "400"))
if err != nil {
c.Handle(400, "Render parameters error", fmt.Errorf("cannot parse height as int: %s", err))
c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse height as int: %s", err))
return
}
timeout, err := strconv.Atoi(queryReader.Get("timeout", "60"))
if err != nil {
c.Handle(400, "Render parameters error", fmt.Errorf("cannot parse timeout as int: %s", err))
c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse timeout as int: %s", err))
return
}
scale, err := strconv.ParseFloat(queryReader.Get("scale", "1"), 64)
if err != nil {
c.Handle(400, "Render parameters error", fmt.Errorf("cannot parse scale as float: %s", err))
c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse scale as float: %s", err))
return
}
@@ -69,19 +69,19 @@ func (hs *HTTPServer) RenderToPng(c *models.ReqContext) {
})
if err != nil {
if errors.Is(err, rendering.ErrTimeout) {
c.Handle(500, err.Error(), err)
c.Handle(hs.Cfg, 500, err.Error(), err)
return
}
if errors.Is(err, rendering.ErrPhantomJSNotInstalled) {
if strings.HasPrefix(runtime.GOARCH, "arm") {
c.Handle(500, "Rendering failed - PhantomJS isn't included in arm build per default", err)
c.Handle(hs.Cfg, 500, "Rendering failed - PhantomJS isn't included in arm build per default", err)
} else {
c.Handle(500, "Rendering failed - PhantomJS isn't installed correctly", err)
c.Handle(hs.Cfg, 500, "Rendering failed - PhantomJS isn't installed correctly", err)
}
return
}
c.Handle(500, "Rendering failed.", err)
c.Handle(hs.Cfg, 500, "Rendering failed.", err)
return
}