From 95d063621e29562b20d92589bb375363dd8c332d Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 31 Jan 2018 16:46:31 +0100 Subject: [PATCH] dashboards: new route for deleting dashboards by uid --- pkg/api/api.go | 1 + pkg/api/dashboard.go | 20 ++++++++++ pkg/api/dashboard_test.go | 81 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/pkg/api/api.go b/pkg/api/api.go index 6d2207971e7..d10b459cd6a 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -249,6 +249,7 @@ func (hs *HttpServer) registerRoutes() { // Dashboard apiRoute.Group("/dashboards", func(dashboardRoute RouteRegister) { dashboardRoute.Get("/uid/:uid", wrap(GetDashboard)) + dashboardRoute.Delete("/uid/:uid", wrap(DeleteDashboardByUid)) dashboardRoute.Get("/db/:slug", wrap(GetDashboard)) dashboardRoute.Delete("/db/:slug", reqEditorRole, wrap(DeleteDashboard)) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 7799ad868f9..ae8d819b981 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -165,6 +165,26 @@ func DeleteDashboard(c *middleware.Context) Response { return Json(200, resp) } +func DeleteDashboardByUid(c *middleware.Context) Response { + dash, rsp := getDashboardHelper(c.OrgId, "", 0, c.Params(":uid")) + if rsp != nil { + return rsp + } + + guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) + if canSave, err := guardian.CanSave(); err != nil || !canSave { + return dashboardGuardianResponse(err) + } + + cmd := m.DeleteDashboardCommand{OrgId: c.OrgId, Id: dash.Id} + if err := bus.Dispatch(&cmd); err != nil { + return ApiError(500, "Failed to delete dashboard", err) + } + + var resp = map[string]interface{}{"title": dash.Title} + return Json(200, resp) +} + func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) Response { cmd.OrgId = c.OrgId cmd.UserId = c.UserId diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 0bd586f6067..3d8f49b5f23 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -113,6 +113,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 403) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 403) @@ -169,6 +178,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 200) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 200) @@ -287,6 +305,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 403) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 403) @@ -341,6 +368,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 403) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 403) @@ -406,6 +442,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 200) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 200) @@ -470,6 +515,15 @@ func TestDashboardApiEndpoint(t *testing.T) { So(getDashboardQueries[0].Slug, ShouldEqual, "child-dash") }) }) + + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 403) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) }) Convey("When user is an Org Viewer but has an admin permission", func() { @@ -521,6 +575,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 200) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 200) @@ -583,6 +646,15 @@ func TestDashboardApiEndpoint(t *testing.T) { }) }) + loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) { + CallDeleteDashboardByUid(sc) + So(sc.resp.Code, ShouldEqual, 403) + + Convey("Should lookup dashboard by uid", func() { + So(getDashboardQueries[0].Uid, ShouldEqual, "abcdefghi") + }) + }) + loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { CallGetDashboardVersion(sc) So(sc.resp.Code, ShouldEqual, 403) @@ -643,6 +715,15 @@ func CallDeleteDashboard(sc *scenarioContext) { sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() } +func CallDeleteDashboardByUid(sc *scenarioContext) { + bus.AddHandler("test", func(cmd *m.DeleteDashboardCommand) error { + return nil + }) + + sc.handlerFunc = DeleteDashboardByUid + sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() +} + func CallPostDashboard(sc *scenarioContext) { bus.AddHandler("test", func(cmd *alerting.ValidateDashboardAlertsCommand) error { return nil