瀏覽代碼

dashboard: add permission check for diff api route

ref #10770
Daniel Lee 7 年之前
父節點
當前提交
ecf438f8d0
共有 2 個文件被更改,包括 83 次插入2 次删除
  1. 14 2
      pkg/api/dashboard.go
  2. 69 0
      pkg/api/dashboard_test.go

+ 14 - 2
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.

+ 69 - 0
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)