From ecf438f8d01a521c63129164783fd3c77abafd73 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 27 Feb 2018 17:53:30 +0100 Subject: [PATCH] dashboard: add permission check for diff api route ref #10770 --- pkg/api/dashboard.go | 16 +++++++-- pkg/api/dashboard_test.go | 69 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 88502804919..53174075c25 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -411,6 +411,18 @@ func GetDashboardVersion(c *middleware.Context) Response { // POST /api/dashboards/calculate-diff performs diffs on two dashboards func CalculateDashboardDiff(c *middleware.Context, apiOptions dtos.CalculateDiffOptions) Response { + guardianBase := guardian.New(apiOptions.Base.DashboardId, c.OrgId, c.SignedInUser) + if canSave, err := guardianBase.CanSave(); err != nil || !canSave { + return dashboardGuardianResponse(err) + } + + if apiOptions.Base.DashboardId != apiOptions.New.DashboardId { + guardianNew := guardian.New(apiOptions.New.DashboardId, c.OrgId, c.SignedInUser) + if canSave, err := guardianNew.CanSave(); err != nil || !canSave { + return dashboardGuardianResponse(err) + } + } + options := dashdiffs.Options{ OrgId: c.OrgId, DiffType: dashdiffs.ParseDiffType(apiOptions.DiffType), @@ -436,9 +448,9 @@ func CalculateDashboardDiff(c *middleware.Context, apiOptions dtos.CalculateDiff if options.DiffType == dashdiffs.DiffDelta { return Respond(200, result.Delta).Header("Content-Type", "application/json") - } else { - return Respond(200, result.Delta).Header("Content-Type", "text/html") } + + return Respond(200, result.Delta).Header("Content-Type", "text/html") } // RestoreDashboardVersion restores a dashboard to the given version. diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 734df3da00d..3857fa0b9e1 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -743,6 +743,53 @@ func TestDashboardApiEndpoint(t *testing.T) { } }) }) + + Convey("Given two dashboards being compared", t, func() { + mockResult := []*m.DashboardAclInfoDTO{} + bus.AddHandler("test", func(query *m.GetDashboardAclInfoListQuery) error { + query.Result = mockResult + return nil + }) + + bus.AddHandler("test", func(query *m.GetDashboardVersionQuery) error { + query.Result = &m.DashboardVersion{ + Data: simplejson.NewFromAny(map[string]interface{}{ + "title": "Dash" + string(query.DashboardId), + }), + } + return nil + }) + + cmd := dtos.CalculateDiffOptions{ + Base: dtos.CalculateDiffTarget{ + DashboardId: 1, + Version: 1, + }, + New: dtos.CalculateDiffTarget{ + DashboardId: 2, + Version: 2, + }, + DiffType: "basic", + } + + Convey("when user does not have permission", func() { + role := m.ROLE_VIEWER + + postDiffScenario("When calling POST on", "/api/dashboards/calculate-diff", "/api/dashboards/calculate-diff", cmd, role, func(sc *scenarioContext) { + CallPostDashboard(sc) + So(sc.resp.Code, ShouldEqual, 403) + }) + }) + + Convey("when user does have permission", func() { + role := m.ROLE_ADMIN + + postDiffScenario("When calling POST on", "/api/dashboards/calculate-diff", "/api/dashboards/calculate-diff", cmd, role, func(sc *scenarioContext) { + CallPostDashboard(sc) + So(sc.resp.Code, ShouldEqual, 200) + }) + }) + }) } func GetDashboardShouldReturn200(sc *scenarioContext) dtos.DashboardFullWithMeta { @@ -835,6 +882,28 @@ func postDashboardScenario(desc string, url string, routePattern string, mock *d }) } +func postDiffScenario(desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions, role m.RoleType, fn scenarioFunc) { + Convey(desc+" "+url, func() { + defer bus.ClearBusHandlers() + + sc := setupScenarioContext(url) + sc.defaultHandler = wrap(func(c *middleware.Context) Response { + sc.context = c + sc.context.SignedInUser = &m.SignedInUser{ + OrgId: TestOrgID, + UserId: TestUserID, + } + sc.context.OrgRole = role + + return CalculateDashboardDiff(c, cmd) + }) + + sc.m.Post(routePattern, sc.defaultHandler) + + fn(sc) + }) +} + func (sc *scenarioContext) ToJson() *simplejson.Json { var result *simplejson.Json err := json.NewDecoder(sc.resp.Body).Decode(&result)