Commit 13d5db7d by Marcus Efraimsson

dashboards: add support for retrieving a dashboard by uid

Introduces new url in api /dashboards/<uid> for fetching dashboard by unique id
Leave the old dashboard by slug url /dashboards/db/<slug> for backward
compatibility and for supporting fallback
WIP for #7883
parent c1cff384
...@@ -242,6 +242,8 @@ func (hs *HttpServer) registerRoutes() { ...@@ -242,6 +242,8 @@ func (hs *HttpServer) registerRoutes() {
// Dashboard // Dashboard
apiRoute.Group("/dashboards", func(dashboardRoute RouteRegister) { apiRoute.Group("/dashboards", func(dashboardRoute RouteRegister) {
dashboardRoute.Get("/uid/:uid", wrap(GetDashboard))
dashboardRoute.Get("/db/:slug", wrap(GetDashboard)) dashboardRoute.Get("/db/:slug", wrap(GetDashboard))
dashboardRoute.Delete("/db/:slug", reqEditorRole, wrap(DeleteDashboard)) dashboardRoute.Delete("/db/:slug", reqEditorRole, wrap(DeleteDashboard))
......
...@@ -44,7 +44,7 @@ func dashboardGuardianResponse(err error) Response { ...@@ -44,7 +44,7 @@ func dashboardGuardianResponse(err error) Response {
} }
func GetDashboard(c *middleware.Context) Response { func GetDashboard(c *middleware.Context) Response {
dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0) dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0, c.Params(":uid"))
if rsp != nil { if rsp != nil {
return rsp return rsp
} }
...@@ -124,8 +124,15 @@ func getUserLogin(userId int64) string { ...@@ -124,8 +124,15 @@ func getUserLogin(userId int64) string {
} }
} }
func getDashboardHelper(orgId int64, slug string, id int64) (*m.Dashboard, Response) { func getDashboardHelper(orgId int64, slug string, id int64, uid string) (*m.Dashboard, Response) {
query := m.GetDashboardQuery{Slug: slug, Id: id, OrgId: orgId} var query m.GetDashboardQuery
if len(uid) > 0 {
query = m.GetDashboardQuery{Uid: uid, Id: id, OrgId: orgId}
} else {
query = m.GetDashboardQuery{Slug: slug, Id: id, OrgId: orgId}
}
if err := bus.Dispatch(&query); err != nil { if err := bus.Dispatch(&query); err != nil {
return nil, ApiError(404, "Dashboard not found", err) return nil, ApiError(404, "Dashboard not found", err)
} }
...@@ -133,7 +140,7 @@ func getDashboardHelper(orgId int64, slug string, id int64) (*m.Dashboard, Respo ...@@ -133,7 +140,7 @@ func getDashboardHelper(orgId int64, slug string, id int64) (*m.Dashboard, Respo
} }
func DeleteDashboard(c *middleware.Context) Response { func DeleteDashboard(c *middleware.Context) Response {
dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0) dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0, "")
if rsp != nil { if rsp != nil {
return rsp return rsp
} }
...@@ -393,7 +400,7 @@ func CalculateDashboardDiff(c *middleware.Context, apiOptions dtos.CalculateDiff ...@@ -393,7 +400,7 @@ func CalculateDashboardDiff(c *middleware.Context, apiOptions dtos.CalculateDiff
// RestoreDashboardVersion restores a dashboard to the given version. // RestoreDashboardVersion restores a dashboard to the given version.
func RestoreDashboardVersion(c *middleware.Context, apiCmd dtos.RestoreDashboardVersionCommand) Response { func RestoreDashboardVersion(c *middleware.Context, apiCmd dtos.RestoreDashboardVersionCommand) Response {
dash, rsp := getDashboardHelper(c.OrgId, "", c.ParamsInt64(":dashboardId")) dash, rsp := getDashboardHelper(c.OrgId, "", c.ParamsInt64(":dashboardId"), "")
if rsp != nil { if rsp != nil {
return rsp return rsp
} }
......
...@@ -39,8 +39,11 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -39,8 +39,11 @@ func TestDashboardApiEndpoint(t *testing.T) {
fakeDash.FolderId = 1 fakeDash.FolderId = 1
fakeDash.HasAcl = false fakeDash.HasAcl = false
var getDashboardQueries []*m.GetDashboardQuery
bus.AddHandler("test", func(query *m.GetDashboardQuery) error { bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
query.Result = fakeDash query.Result = fakeDash
getDashboardQueries = append(getDashboardQueries, query)
return nil return nil
}) })
...@@ -73,9 +76,13 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -73,9 +76,13 @@ func TestDashboardApiEndpoint(t *testing.T) {
Convey("When user is an Org Viewer", func() { Convey("When user is an Org Viewer", func() {
role := m.ROLE_VIEWER role := m.ROLE_VIEWER
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should not be able to edit or save dashboard", func() { Convey("Should not be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeFalse) So(dash.Meta.CanEdit, ShouldBeFalse)
So(dash.Meta.CanSave, ShouldBeFalse) So(dash.Meta.CanSave, ShouldBeFalse)
...@@ -83,9 +90,27 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -83,9 +90,27 @@ func TestDashboardApiEndpoint(t *testing.T) {
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should not be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeFalse)
So(dash.Meta.CanSave, ShouldBeFalse)
So(dash.Meta.CanAdmin, ShouldBeFalse)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -107,9 +132,13 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -107,9 +132,13 @@ func TestDashboardApiEndpoint(t *testing.T) {
Convey("When user is an Org Editor", func() { Convey("When user is an Org Editor", func() {
role := m.ROLE_EDITOR role := m.ROLE_EDITOR
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be able to edit or save dashboard", func() { Convey("Should be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeTrue) So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue) So(dash.Meta.CanSave, ShouldBeTrue)
...@@ -117,9 +146,27 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -117,9 +146,27 @@ func TestDashboardApiEndpoint(t *testing.T) {
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue)
So(dash.Meta.CanAdmin, ShouldBeFalse)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 200) So(sc.resp.Code, ShouldEqual, 200)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -186,8 +233,11 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -186,8 +233,11 @@ func TestDashboardApiEndpoint(t *testing.T) {
return nil return nil
}) })
var getDashboardQueries []*m.GetDashboardQuery
bus.AddHandler("test", func(query *m.GetDashboardQuery) error { bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
query.Result = fakeDash query.Result = fakeDash
getDashboardQueries = append(getDashboardQueries, query)
return nil return nil
}) })
...@@ -208,18 +258,39 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -208,18 +258,39 @@ func TestDashboardApiEndpoint(t *testing.T) {
Convey("When user is an Org Viewer and has no permissions for this dashboard", func() { Convey("When user is an Org Viewer and has no permissions for this dashboard", func() {
role := m.ROLE_VIEWER role := m.ROLE_VIEWER
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
sc.handlerFunc = GetDashboard sc.handlerFunc = GetDashboard
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be denied access", func() { Convey("Should be denied access", func() {
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
sc.handlerFunc = GetDashboard
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be denied access", func() {
So(sc.resp.Code, ShouldEqual, 403)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -241,18 +312,39 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -241,18 +312,39 @@ func TestDashboardApiEndpoint(t *testing.T) {
Convey("When user is an Org Editor and has no permissions for this dashboard", func() { Convey("When user is an Org Editor and has no permissions for this dashboard", func() {
role := m.ROLE_EDITOR role := m.ROLE_EDITOR
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
sc.handlerFunc = GetDashboard sc.handlerFunc = GetDashboard
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be denied access", func() { Convey("Should be denied access", func() {
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
sc.handlerFunc = GetDashboard
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be denied access", func() {
So(sc.resp.Code, ShouldEqual, 403)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -283,9 +375,13 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -283,9 +375,13 @@ func TestDashboardApiEndpoint(t *testing.T) {
return nil return nil
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be able to get dashboard with edit rights", func() { Convey("Should be able to get dashboard with edit rights", func() {
So(dash.Meta.CanEdit, ShouldBeTrue) So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue) So(dash.Meta.CanSave, ShouldBeTrue)
...@@ -293,9 +389,27 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -293,9 +389,27 @@ func TestDashboardApiEndpoint(t *testing.T) {
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be able to get dashboard with edit rights", func() {
So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue)
So(dash.Meta.CanAdmin, ShouldBeFalse)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 200) So(sc.resp.Code, ShouldEqual, 200)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -332,9 +446,13 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -332,9 +446,13 @@ func TestDashboardApiEndpoint(t *testing.T) {
return nil return nil
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be able to get dashboard with edit rights but can save should be false", func() { Convey("Should be able to get dashboard with edit rights but can save should be false", func() {
So(dash.Meta.CanEdit, ShouldBeTrue) So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeFalse) So(dash.Meta.CanSave, ShouldBeFalse)
...@@ -342,9 +460,27 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -342,9 +460,27 @@ func TestDashboardApiEndpoint(t *testing.T) {
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be able to get dashboard with edit rights but can save should be false", func() {
So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeFalse)
So(dash.Meta.CanAdmin, ShouldBeFalse)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
}) })
...@@ -360,9 +496,13 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -360,9 +496,13 @@ func TestDashboardApiEndpoint(t *testing.T) {
return nil return nil
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should be able to get dashboard with edit rights", func() { Convey("Should be able to get dashboard with edit rights", func() {
So(dash.Meta.CanEdit, ShouldBeTrue) So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue) So(dash.Meta.CanSave, ShouldBeTrue)
...@@ -370,9 +510,27 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -370,9 +510,27 @@ func TestDashboardApiEndpoint(t *testing.T) {
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should be able to get dashboard with edit rights", func() {
So(dash.Meta.CanEdit, ShouldBeTrue)
So(dash.Meta.CanSave, ShouldBeTrue)
So(dash.Meta.CanAdmin, ShouldBeTrue)
})
})
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 200) So(sc.resp.Code, ShouldEqual, 200)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
...@@ -408,18 +566,39 @@ func TestDashboardApiEndpoint(t *testing.T) { ...@@ -408,18 +566,39 @@ func TestDashboardApiEndpoint(t *testing.T) {
return nil return nil
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc) dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
Convey("Should not be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeFalse)
So(dash.Meta.CanSave, ShouldBeFalse)
})
})
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
dash := GetDashboardShouldReturn200(sc)
Convey("Should lookup dashboard by uid", func() {
So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi")
})
Convey("Should not be able to edit or save dashboard", func() { Convey("Should not be able to edit or save dashboard", func() {
So(dash.Meta.CanEdit, ShouldBeFalse) So(dash.Meta.CanEdit, ShouldBeFalse)
So(dash.Meta.CanSave, ShouldBeFalse) So(dash.Meta.CanSave, ShouldBeFalse)
}) })
}) })
loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/2", "/api/dashboards/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
CallDeleteDashboard(sc) CallDeleteDashboard(sc)
So(sc.resp.Code, ShouldEqual, 403) So(sc.resp.Code, ShouldEqual, 403)
Convey("Should lookup dashboard by slug", func() {
So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash")
})
}) })
loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
......
...@@ -186,8 +186,9 @@ type DeleteDashboardCommand struct { ...@@ -186,8 +186,9 @@ type DeleteDashboardCommand struct {
// //
type GetDashboardQuery struct { type GetDashboardQuery struct {
Slug string // required if no Id is specified Slug string // required if no Id or Uid is specified
Id int64 // optional if slug is set Id int64 // optional if slug is set
Uid string // optional if slug is set
OrgId int64 OrgId int64
Result *Dashboard Result *Dashboard
......
...@@ -165,7 +165,7 @@ func setHasAcl(sess *DBSession, dash *m.Dashboard) error { ...@@ -165,7 +165,7 @@ func setHasAcl(sess *DBSession, dash *m.Dashboard) error {
} }
func GetDashboard(query *m.GetDashboardQuery) error { func GetDashboard(query *m.GetDashboardQuery) error {
dashboard := m.Dashboard{Slug: query.Slug, OrgId: query.OrgId, Id: query.Id} dashboard := m.Dashboard{Slug: query.Slug, OrgId: query.OrgId, Id: query.Id, Uid: query.Uid}
has, err := x.Get(&dashboard) has, err := x.Get(&dashboard)
if err != nil { if err != nil {
......
...@@ -30,15 +30,33 @@ func TestDashboardDataAccess(t *testing.T) { ...@@ -30,15 +30,33 @@ func TestDashboardDataAccess(t *testing.T) {
So(savedDash.Id, ShouldNotEqual, 0) So(savedDash.Id, ShouldNotEqual, 0)
So(savedDash.IsFolder, ShouldBeFalse) So(savedDash.IsFolder, ShouldBeFalse)
So(savedDash.FolderId, ShouldBeGreaterThan, 0) So(savedDash.FolderId, ShouldBeGreaterThan, 0)
So(len(savedDash.Uid), ShouldBeGreaterThan, 0)
So(savedFolder.Title, ShouldEqual, "1 test dash folder") So(savedFolder.Title, ShouldEqual, "1 test dash folder")
So(savedFolder.Slug, ShouldEqual, "1-test-dash-folder") So(savedFolder.Slug, ShouldEqual, "1-test-dash-folder")
So(savedFolder.Id, ShouldNotEqual, 0) So(savedFolder.Id, ShouldNotEqual, 0)
So(savedFolder.IsFolder, ShouldBeTrue) So(savedFolder.IsFolder, ShouldBeTrue)
So(savedFolder.FolderId, ShouldEqual, 0) So(savedFolder.FolderId, ShouldEqual, 0)
So(len(savedFolder.Uid), ShouldBeGreaterThan, 0)
}) })
Convey("Should be able to get dashboard", func() { Convey("Should be able to get dashboard by id", func() {
query := m.GetDashboardQuery{
Id: savedDash.Id,
OrgId: 1,
}
err := GetDashboard(&query)
So(err, ShouldBeNil)
So(query.Result.Title, ShouldEqual, "test dash 23")
So(query.Result.Slug, ShouldEqual, "test-dash-23")
So(query.Result.Id, ShouldEqual, savedDash.Id)
So(query.Result.Uid, ShouldEqual, savedDash.Uid)
So(query.Result.IsFolder, ShouldBeFalse)
})
Convey("Should be able to get dashboard by slug", func() {
query := m.GetDashboardQuery{ query := m.GetDashboardQuery{
Slug: "test-dash-23", Slug: "test-dash-23",
OrgId: 1, OrgId: 1,
...@@ -49,6 +67,24 @@ func TestDashboardDataAccess(t *testing.T) { ...@@ -49,6 +67,24 @@ func TestDashboardDataAccess(t *testing.T) {
So(query.Result.Title, ShouldEqual, "test dash 23") So(query.Result.Title, ShouldEqual, "test dash 23")
So(query.Result.Slug, ShouldEqual, "test-dash-23") So(query.Result.Slug, ShouldEqual, "test-dash-23")
So(query.Result.Id, ShouldEqual, savedDash.Id)
So(query.Result.Uid, ShouldEqual, savedDash.Uid)
So(query.Result.IsFolder, ShouldBeFalse)
})
Convey("Should be able to get dashboard by uid", func() {
query := m.GetDashboardQuery{
Uid: savedDash.Uid,
OrgId: 1,
}
err := GetDashboard(&query)
So(err, ShouldBeNil)
So(query.Result.Title, ShouldEqual, "test dash 23")
So(query.Result.Slug, ShouldEqual, "test-dash-23")
So(query.Result.Id, ShouldEqual, savedDash.Id)
So(query.Result.Uid, ShouldEqual, savedDash.Uid)
So(query.Result.IsFolder, ShouldBeFalse) So(query.Result.IsFolder, ShouldBeFalse)
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment