mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 01:41:24 -06:00
Chore: Remove endpoints that contain the slug field (#35104)
* Chore: Remove endpoints that contain the slug field * More cleanups * Lint fixes * Remove unnecessary funcs * Cleanup frontend code * Remove deprecated endpoints from docs * Revert change according to reviewer's comments
This commit is contained in:
parent
aa4c5bbfe4
commit
1c49986b2f
@ -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"
|
||||
}
|
||||
```
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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}`);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user