diff --git a/docs/sources/http_api/dashboard.md b/docs/sources/http_api/dashboard.md index b64d61f7e19..d287803b23a 100644 --- a/docs/sources/http_api/dashboard.md +++ b/docs/sources/http_api/dashboard.md @@ -439,105 +439,3 @@ Content-Type: application/json ## Dashboard Search See [Folder/Dashboard Search API]({{< relref "folder_dashboard_search.md" >}}). - -## Deprecated resources -Please note that these resource have been deprecated and will be removed in a future release. - -### Get dashboard by slug -**Deprecated starting from Grafana v5.0. Please update to use the new *Get dashboard by uid* resource instead** - -`GET /api/dashboards/db/:slug` - -Will return the dashboard given the dashboard slug. Slug is the URL friendly version of the dashboard title. -If there exists multiple dashboards with the same slug, one of them will be returned in the response. - -**Example Request**: - -```http -GET /api/dashboards/db/production-overview HTTP/1.1 -Accept: application/json -Content-Type: application/json -Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk -``` - -**Example Response**: - -```http -HTTP/1.1 200 -Content-Type: application/json - -{ - "dashboard": { - "id": 1, - "uid": "cIBgcSjkk", - "title": "Production Overview", - "tags": [ "templated" ], - "timezone": "browser", - "schemaVersion": 16, - "version": 0 - }, - "meta": { - "isStarred": false, - "url": "/d/cIBgcSjkk/production-overview", - "slug": "production-overview" // deprecated in Grafana v5.0 - } -} -``` - -Status Codes: - -- **200** – Found -- **401** – Unauthorized -- **403** – Access denied -- **404** – Not found - -### Delete dashboard by slug -**Deprecated starting from Grafana v5.0. Please update to use the *Delete dashboard by uid* resource instead.** - -`DELETE /api/dashboards/db/:slug` - -Will delete the dashboard given the specified slug. Slug is the URL friendly version of the dashboard title. - -**Example Request**: - -```http -DELETE /api/dashboards/db/test HTTP/1.1 -Accept: application/json -Content-Type: application/json -Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk -``` - -**Example Response**: - -```http -HTTP/1.1 200 -Content-Type: application/json - -{ - "title": "Production Overview", - "message": "Dashboard Production Overview deleted", - "id": 2 -} -``` - -Status Codes: - -- **200** – Deleted -- **401** – Unauthorized -- **403** – Access denied -- **404** – Not found -- **412** – Precondition failed - -The **412** status code is used when there exists multiple dashboards with the same slug. -The response body will look like this: - -```http -HTTP/1.1 412 Precondition Failed -Content-Type: application/json; charset=UTF-8 -Content-Length: 97 - -{ - "message": "Multiple dashboards with the same slug exists", - "status": "multiple-slugs-exists" -} -``` diff --git a/pkg/api/api.go b/pkg/api/api.go index eed0833cbb7..97f242228e1 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -29,8 +29,6 @@ func (hs *HTTPServer) registerRoutes() { reqOrgAdmin := middleware.ReqOrgAdmin reqCanAccessTeams := middleware.AdminOrFeatureEnabled(hs.Cfg.EditorsCanAdmin) reqSnapshotPublicModeOrSignedIn := middleware.SnapshotPublicModeOrSignedIn(hs.Cfg) - redirectFromLegacyDashboardURL := middleware.RedirectFromLegacyDashboardURL() - redirectFromLegacyDashboardSoloURL := middleware.RedirectFromLegacyDashboardSoloURL(hs.Cfg) redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL(hs.Cfg) authorize := acmiddleware.Middleware(hs.AccessControl) quota := middleware.Quota(hs.QuotaService) @@ -84,13 +82,11 @@ func (hs *HTTPServer) registerRoutes() { 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/new", reqSignedIn, hs.Index) r.Get("/dashboard-solo/snapshot/*", hs.Index) r.Get("/d-solo/:uid/:slug", reqSignedIn, hs.Index) r.Get("/d-solo/:uid", reqSignedIn, hs.Index) - r.Get("/dashboard-solo/db/:slug", reqSignedIn, redirectFromLegacyDashboardSoloURL, hs.Index) r.Get("/dashboard-solo/script/*", reqSignedIn, hs.Index) r.Get("/import/dashboard", reqSignedIn, hs.Index) r.Get("/dashboards/", reqSignedIn, hs.Index) @@ -327,9 +323,6 @@ func (hs *HTTPServer) registerRoutes() { dashboardRoute.Get("/uid/:uid", routing.Wrap(hs.GetDashboard)) dashboardRoute.Delete("/uid/:uid", routing.Wrap(hs.DeleteDashboardByUID)) - dashboardRoute.Get("/db/:slug", routing.Wrap(hs.GetDashboard)) - dashboardRoute.Delete("/db/:slug", routing.Wrap(hs.DeleteDashboardBySlug)) - dashboardRoute.Post("/calculate-diff", bind(dtos.CalculateDiffOptions{}), routing.Wrap(CalculateDashboardDiff)) dashboardRoute.Post("/trim", bind(models.TrimDashboardCommand{}), routing.Wrap(hs.TrimDashboard)) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index b3ef5317ba5..95855433c83 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -69,9 +69,8 @@ func (hs *HTTPServer) TrimDashboard(c *models.ReqContext, cmd models.TrimDashboa } func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response { - slug := c.Params(":slug") uid := c.Params(":uid") - dash, rsp := getDashboardHelper(c.OrgId, slug, 0, uid) + dash, rsp := getDashboardHelper(c.OrgId, 0, uid) if rsp != nil { return rsp } @@ -197,13 +196,13 @@ func getUserLogin(userID int64) string { return query.Result.Login } -func getDashboardHelper(orgID int64, slug string, id int64, uid string) (*models.Dashboard, response.Response) { +func getDashboardHelper(orgID int64, id int64, uid string) (*models.Dashboard, response.Response) { var query models.GetDashboardQuery if len(uid) > 0 { query = models.GetDashboardQuery{Uid: uid, Id: id, OrgId: orgID} } else { - query = models.GetDashboardQuery{Slug: slug, Id: id, OrgId: orgID} + query = models.GetDashboardQuery{Id: id, OrgId: orgID} } if err := bus.Dispatch(&query); err != nil { @@ -232,7 +231,7 @@ func (hs *HTTPServer) DeleteDashboardByUID(c *models.ReqContext) response.Respon } func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response { - dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0, c.Params(":uid")) + dash, rsp := getDashboardHelper(c.OrgId, 0, c.Params(":uid")) if rsp != nil { return rsp } @@ -626,7 +625,7 @@ func CalculateDashboardDiff(c *models.ReqContext, apiOptions dtos.CalculateDiffO // RestoreDashboardVersion restores a dashboard to the given version. func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext, apiCmd dtos.RestoreDashboardVersionCommand) response.Response { - dash, rsp := getDashboardHelper(c.OrgId, "", c.ParamsInt64(":dashboardId"), "") + dash, rsp := getDashboardHelper(c.OrgId, c.ParamsInt64(":dashboardId"), "") if rsp != nil { return rsp } diff --git a/pkg/api/dashboard_permission.go b/pkg/api/dashboard_permission.go index 0b35ec0cc92..cf6e3379b45 100644 --- a/pkg/api/dashboard_permission.go +++ b/pkg/api/dashboard_permission.go @@ -13,7 +13,7 @@ import ( func (hs *HTTPServer) GetDashboardPermissionList(c *models.ReqContext) response.Response { dashID := c.ParamsInt64(":dashboardId") - _, rsp := getDashboardHelper(c.OrgId, "", dashID, "") + _, rsp := getDashboardHelper(c.OrgId, dashID, "") if rsp != nil { return rsp } @@ -57,7 +57,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt dashID := c.ParamsInt64(":dashboardId") - _, rsp := getDashboardHelper(c.OrgId, "", dashID, "") + _, rsp := getDashboardHelper(c.OrgId, dashID, "") if rsp != nil { return rsp } diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index ac934acd929..1b3ee466d41 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -144,19 +144,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { t.Run("When user is an Org Viewer", func(t *testing.T) { role := models.ROLE_VIEWER - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - dash := getDashboardShouldReturn200(sc) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - - assert.False(t, dash.Meta.CanEdit) - assert.False(t, dash.Meta.CanSave) - assert.False(t, dash.Meta.CanAdmin) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -170,20 +157,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.False(t, dash.Meta.CanAdmin) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - callDeleteDashboardBySlug(sc, &HTTPServer{ - Cfg: setting.NewCfg(), - LibraryPanelService: &mockLibraryPanelService{}, - LibraryElementService: &mockLibraryElementService{}, - }) - assert.Equal(t, 403, sc.resp.Code) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -218,19 +191,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { t.Run("When user is an Org Editor", func(t *testing.T) { role := models.ROLE_EDITOR - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - dash := getDashboardShouldReturn200(sc) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - - assert.True(t, dash.Meta.CanEdit) - assert.True(t, dash.Meta.CanSave) - assert.False(t, dash.Meta.CanAdmin) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -243,19 +203,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.False(t, dash.Meta.CanAdmin) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - callDeleteDashboardBySlug(sc, &HTTPServer{ - Cfg: setting.NewCfg(), - LibraryPanelService: &mockLibraryPanelService{}, - LibraryElementService: &mockLibraryElementService{}, - }) - assert.Equal(t, 200, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -353,16 +300,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { t.Run("When user is an Org Viewer and has no permissions for this dashboard", func(t *testing.T) { role := models.ROLE_VIEWER - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - sc.handlerFunc = hs.GetDashboard - sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.Equal(t, 403, sc.resp.Code) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -373,15 +310,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.Equal(t, 403, sc.resp.Code) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 403, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -411,17 +339,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { t.Run("When user is an Org Editor and has no permissions for this dashboard", func(t *testing.T) { role := models.ROLE_EDITOR - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - sc.handlerFunc = hs.GetDashboard - sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.Equal(t, 403, sc.resp.Code) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -433,15 +350,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.Equal(t, 403, sc.resp.Code) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUp() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 403, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUp() @@ -484,22 +392,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { return state } - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error { - query.Result = mockResult - return nil - }) - - dash := getDashboardShouldReturn200(sc) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.True(t, dash.Meta.CanEdit) - assert.True(t, dash.Meta.CanSave) - assert.False(t, dash.Meta.CanAdmin) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -512,14 +404,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.False(t, dash.Meta.CanAdmin) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 200, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -567,17 +451,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { return state } - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - dash := getDashboardShouldReturn200(sc) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.True(t, dash.Meta.CanEdit) - assert.False(t, dash.Meta.CanSave) - assert.False(t, dash.Meta.CanAdmin) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -590,14 +463,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.False(t, dash.Meta.CanAdmin) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 403, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -623,16 +488,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { return state } - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - dash := getDashboardShouldReturn200(sc) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.True(t, dash.Meta.CanEdit) - assert.True(t, dash.Meta.CanSave) - assert.True(t, dash.Meta.CanAdmin) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -644,14 +499,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.True(t, dash.Meta.CanAdmin) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 200, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -691,16 +538,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { return state } - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - dash := getDashboardShouldReturn200(sc) - - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - assert.False(t, dash.Meta.CanEdit) - assert.False(t, dash.Meta.CanSave) - }) - loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -710,14 +547,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { assert.False(t, dash.Meta.CanSave) }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - state := setUpInner() - - callDeleteDashboardBySlug(sc, hs) - assert.Equal(t, 403, sc.resp.Code) - assert.Equal(t, "child-dash", state.dashQueries[0].Slug) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { state := setUpInner() @@ -758,18 +587,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { query.Result = dashboards return nil }) - - role := models.ROLE_EDITOR - - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash", - "/api/dashboards/db/:slug", role, func(sc *scenarioContext) { - callDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()}) - - assert.Equal(t, 412, sc.resp.Code) - result := sc.ToJSON() - assert.Equal(t, "multiple-slugs-exists", result.Get("status").MustString()) - assert.Equal(t, models.ErrDashboardsWithSameSlugExists.Error(), result.Get("message").MustString()) - }) }) t.Run("Post dashboard response tests", func(t *testing.T) { @@ -1132,21 +949,6 @@ func TestDashboardAPIEndpoint(t *testing.T) { }) } - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash", - "/api/dashboards/db/:slug", models.ROLE_EDITOR, func(sc *scenarioContext) { - setUp() - - callDeleteDashboardBySlug(sc, &HTTPServer{ - Cfg: setting.NewCfg(), - LibraryPanelService: &mockLibraryPanelService{}, - LibraryElementService: &mockLibraryElementService{}, - }) - - assert.Equal(t, 400, sc.resp.Code) - result := sc.ToJSON() - assert.Equal(t, models.ErrDashboardCannotDeleteProvisionedDashboard.Error(), result.Get("error").MustString()) - }) - loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/abcdefghi", "/api/dashboards/db/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) { setUp() diff --git a/pkg/middleware/dashboard_redirect.go b/pkg/middleware/dashboard_redirect.go index 734e7215eb8..496f8243e81 100644 --- a/pkg/middleware/dashboard_redirect.go +++ b/pkg/middleware/dashboard_redirect.go @@ -4,35 +4,10 @@ import ( "fmt" "strings" - "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" ) -func getDashboardURLBySlug(orgID int64, slug string) (string, error) { - // TODO: Drop bus call - query := models.GetDashboardQuery{Slug: slug, OrgId: orgID} - if err := bus.Dispatch(&query); err != nil { - return "", models.ErrDashboardNotFound - } - - return models.GetDashboardUrl(query.Result.Uid, query.Result.Slug), nil -} - -func RedirectFromLegacyDashboardURL() func(c *models.ReqContext) { - return func(c *models.ReqContext) { - slug := c.Params("slug") - - if slug != "" { - if url, err := getDashboardURLBySlug(c.OrgId, slug); err == nil { - url = fmt.Sprintf("%s?%s", url, c.Req.URL.RawQuery) - c.Redirect(url, 301) - return - } - } - } -} - // 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(cfg *setting.Cfg) func(c *models.ReqContext) { @@ -59,26 +34,3 @@ func RedirectFromLegacyPanelEditURL(cfg *setting.Cfg) func(c *models.ReqContext) } } } - -func RedirectFromLegacyDashboardSoloURL(cfg *setting.Cfg) func(c *models.ReqContext) { - return func(c *models.ReqContext) { - slug := c.Params("slug") - renderRequest := c.QueryBool("render") - - if slug != "" { - url, err := getDashboardURLBySlug(c.OrgId, slug) - if err != nil { - return - } - - if renderRequest && strings.Contains(url, cfg.AppSubURL) { - url = strings.Replace(url, cfg.AppSubURL, "", 1) - } - - url = strings.Replace(url, "/d/", "/d-solo/", 1) - url = fmt.Sprintf("%s?%s", url, c.Req.URL.RawQuery) - c.Redirect(url, 301) - return - } - } -} diff --git a/pkg/middleware/dashboard_redirect_test.go b/pkg/middleware/dashboard_redirect_test.go index 3d2fab37cf7..92310442099 100644 --- a/pkg/middleware/dashboard_redirect_test.go +++ b/pkg/middleware/dashboard_redirect_test.go @@ -1,81 +1,12 @@ package middleware import ( - "strings" "testing" - "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestMiddlewareDashboardRedirect(t *testing.T) { - bus.ClearBusHandlers() - fakeDash := models.NewDashboard("Child dash") - fakeDash.Id = 1 - fakeDash.FolderId = 1 - fakeDash.HasAcl = false - fakeDash.Uid = util.GenerateShortUID() - - middlewareScenario(t, "GET dashboard by legacy url", func(t *testing.T, sc *scenarioContext) { - redirectFromLegacyDashboardURL := RedirectFromLegacyDashboardURL() - - bus.AddHandler("test", func(query *models.GetDashboardQuery) error { - t.Log("Returning fake dashboard") - query.Result = fakeDash - return nil - }) - - sc.handlerFunc = redirectFromLegacyDashboardURL - sc.m.Get("/dashboard/db/:slug", sc.defaultHandler) - sc.fakeReqWithParams("GET", "/dashboard/db/dash?orgId=1&panelId=2", map[string]string{}).exec() - - assert.Equal(t, 301, sc.resp.Code) - // nolint:bodyclose - resp := sc.resp.Result() - t.Cleanup(func() { - err := resp.Body.Close() - assert.NoError(t, err) - }) - redirectURL, err := resp.Location() - require.NoError(t, err) - assert.Equal(t, models.GetDashboardUrl(fakeDash.Uid, fakeDash.Slug), redirectURL.Path) - assert.Len(t, redirectURL.Query(), 2) - }) - - middlewareScenario(t, "GET dashboard solo by legacy url", func(t *testing.T, sc *scenarioContext) { - redirectFromLegacyDashboardSoloURL := RedirectFromLegacyDashboardSoloURL(sc.cfg) - - bus.AddHandler("test", func(query *models.GetDashboardQuery) error { - t.Log("Returning fake dashboard") - query.Result = fakeDash - return nil - }) - - sc.handlerFunc = redirectFromLegacyDashboardSoloURL - sc.m.Get("/dashboard-solo/db/:slug", sc.defaultHandler) - - sc.fakeReqWithParams("GET", "/dashboard-solo/db/dash?orgId=1&panelId=2", map[string]string{}).exec() - - require.Equal(t, 301, sc.resp.Code) - // nolint:bodyclose - resp := sc.resp.Result() - t.Cleanup(func() { - err := resp.Body.Close() - assert.NoError(t, err) - }) - redirectURL, err := resp.Location() - require.NoError(t, err) - // XXX: Should this be called path?? - expectedURL := models.GetDashboardUrl(fakeDash.Uid, fakeDash.Slug) - expectedURL = strings.Replace(expectedURL, "/d/", "/d-solo/", 1) - assert.Equal(t, expectedURL, redirectURL.Path) - assert.Len(t, redirectURL.Query(), 2) - }) -} - func TestMiddlewareDashboardRedirect_legacyEditPanel(t *testing.T) { middlewareScenario(t, "GET dashboard by legacy edit URL", func(t *testing.T, sc *scenarioContext) { sc.handlerFunc = RedirectFromLegacyPanelEditURL(sc.cfg) diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 84fa55b32ff..f57ee1b3d2a 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -403,10 +403,6 @@ export class BackendSrv implements BackendService { return this.get('/api/search', query); } - getDashboardBySlug(slug: string) { - return this.get(`/api/dashboards/db/${slug}`); - } - getDashboardByUid(uid: string) { return this.get(`/api/dashboards/uid/${uid}`); } diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 6075f4d1bda..bb5daa3506f 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -34,23 +34,6 @@ export interface InitDashboardArgs { fixUrl: boolean; } -async function redirectToNewUrl(slug: string) { - const res = await backendSrv.getDashboardBySlug(slug); - - if (res) { - const location = locationService.getLocation(); - let newUrl = res.meta.url; - - // fix solo route urls - if (location.pathname.indexOf('dashboard-solo') !== -1) { - newUrl = newUrl.replace('/d/', '/d-solo/'); - } - - const url = locationUtil.stripBaseFromUrl(newUrl); - locationService.replace(url); - } -} - async function fetchDashboard( args: InitDashboardArgs, dispatch: ThunkDispatch, @@ -76,12 +59,6 @@ async function fetchDashboard( return dashDTO; } case DashboardRoutes.Normal: { - // for old db routes we redirect - if (args.urlType === 'db') { - redirectToNewUrl(args.urlSlug!); - return null; - } - const dashDTO: DashboardDTO = await dashboardLoaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid); if (args.fixUrl && dashDTO.meta.url) { diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index 253dfa7e49a..4ab526a729a 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -64,14 +64,6 @@ export function getAppRoutes(): RouteDescriptor[] { () => import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage') ), }, - { - path: '/dashboard-solo/:type/:slug', - pageClass: 'dashboard-solo', - routeName: DashboardRoutes.Normal, - component: SafeDynamicImport( - () => import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage') - ), - }, { path: '/dashboard/import', component: SafeDynamicImport(