Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard: Redirects for old (pre 7.0) edit & view panel urls #25653

Merged
merged 1 commit into from Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/api/api.go
Expand Up @@ -18,6 +18,7 @@ func (hs *HTTPServer) registerRoutes() {
reqSnapshotPublicModeOrSignedIn := middleware.SnapshotPublicModeOrSignedIn()
redirectFromLegacyDashboardURL := middleware.RedirectFromLegacyDashboardURL()
redirectFromLegacyDashboardSoloURL := middleware.RedirectFromLegacyDashboardSoloURL()
redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL()
quota := middleware.Quota(hs.QuotaService)
bind := binding.Bind

Expand Down Expand Up @@ -65,8 +66,8 @@ func (hs *HTTPServer) registerRoutes() {
r.Get("/plugins/:id/page/:page", reqSignedIn, hs.Index)
r.Get("/a/:id/*", reqSignedIn, hs.Index) // App Root Page

r.Get("/d/:uid/:slug", reqSignedIn, hs.Index)
r.Get("/d/:uid", reqSignedIn, hs.Index)
r.Get("/d/:uid/:slug", reqSignedIn, redirectFromLegacyPanelEditURL, hs.Index)
r.Get("/d/:uid", reqSignedIn, redirectFromLegacyPanelEditURL, hs.Index)
r.Get("/dashboard/db/:slug", reqSignedIn, redirectFromLegacyDashboardURL, hs.Index)
r.Get("/dashboard/script/*", reqSignedIn, hs.Index)
r.Get("/dashboard-solo/snapshot/*", hs.Index)
Expand Down
27 changes: 27 additions & 0 deletions pkg/middleware/dashboard_redirect.go
Expand Up @@ -34,6 +34,33 @@ func RedirectFromLegacyDashboardURL() macaron.Handler {
}
}

// In Grafana v7.0 we changed panel edit & view query parameters.
// This middleware tries to detect those old url parameters and direct to the new url query params
func RedirectFromLegacyPanelEditURL() macaron.Handler {
return func(c *models.ReqContext) {
queryParams := c.Req.URL.Query()

panelId, hasPanelId := queryParams["panelId"]
_, hasFullscreen := queryParams["fullscreen"]
_, hasEdit := queryParams["edit"]

if hasPanelId && hasFullscreen {
delete(queryParams, "panelId")
delete(queryParams, "fullscreen")
delete(queryParams, "edit")

if hasEdit {
queryParams["editPanel"] = panelId
} else {
queryParams["viewPanel"] = panelId
}

newURL := setting.ToAbsUrl(fmt.Sprintf("%s?%s", strings.TrimPrefix(c.Req.URL.Path, "/"), queryParams.Encode()))
c.Redirect(newURL, 301)
}
}
}

func RedirectFromLegacyDashboardSoloURL() macaron.Handler {
return func(c *models.ReqContext) {
slug := c.Params("slug")
Expand Down
17 changes: 17 additions & 0 deletions pkg/middleware/dashboard_redirect_test.go
Expand Up @@ -55,4 +55,21 @@ func TestMiddlewareDashboardRedirect(t *testing.T) {
})
})
})

Convey("Given the dashboard legacy edit panel middleware", t, func() {
Copy link
Contributor

@aknuds1 aknuds1 Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to rewrite this using the standard testing library, since we're committed to getting rid of Convey.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we have to convert this whole file, what test runners are you using?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@torkelo We just use go test for running tests. In this case, I think it would be easy to write this test without Convey. That's what I usually do when adding new tests, just write them with the standard library, in addition to the existing Convey ones (which I guess we'll clean up at some point).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go test is terrible, have scroll a bunch to see what failed due to stack traces that are more than a screen long, and it does not rerun tests on file change (no watch), so the whole experience I find very poor. Like having a test runner in a tmux split that runs tests on file change and print failures in readable form.

I tried to rewrite this to go testing library but sadly it depends on middlewareScenario which uses GoConvey so have to rewrite hundreds of tests to go testing library to convert this test :(

bus.ClearBusHandlers()

middlewareScenario(t, "GET dashboard by legacy edit url", func(sc *scenarioContext) {
sc.m.Get("/d/:uid/:slug", RedirectFromLegacyPanelEditURL(), sc.defaultHandler)

sc.fakeReqWithParams("GET", "/d/asd/dash?orgId=1&panelId=12&fullscreen&edit", map[string]string{}).exec()

Convey("Should redirect to new dashboard edit url with a 301 Moved Permanently", func() {
So(sc.resp.Code, ShouldEqual, 301)
redirectURL, _ := sc.resp.Result().Location()
So(redirectURL.String(), ShouldEqual, "/d/asd/d/asd/dash?editPanel=12&orgId=1")
})
})
})

}