Browse Source

WIP: permission checking for dash version api methods

Daniel Lee 8 years ago
parent
commit
92717ccafb
2 changed files with 123 additions and 0 deletions
  1. 33 0
      pkg/api/dashboard.go
  2. 90 0
      pkg/api/dashboard_test.go

+ 33 - 0
pkg/api/dashboard.go

@@ -116,6 +116,21 @@ func getPermissions(dash *m.Dashboard, orgRole m.RoleType, isGrafanaAdmin bool,
 	return canView, canEdit, canSave, nil
 }
 
+func checkIfCanSaveDashboard(dashboardId int64, orgId int64, orgRole m.RoleType, isGrafanaAdmin bool, userId int64) (bool, error) {
+	dashQuery := m.GetDashboardQuery{Id: dashboardId, OrgId: orgId}
+	err := bus.Dispatch(&dashQuery)
+	if err != nil {
+		return false, err
+	}
+
+	_, _, canSave, err := getPermissions(dashQuery.Result, orgRole, isGrafanaAdmin, userId)
+	if err != nil {
+		return false, err
+	}
+
+	return canSave, nil
+}
+
 func getUserLogin(userId int64) string {
 	query := m.GetUserByIdQuery{Id: userId}
 	err := bus.Dispatch(&query)
@@ -319,6 +334,15 @@ func GetDashboardVersions(c *middleware.Context) Response {
 	limit := c.QueryInt("limit")
 	start := c.QueryInt("start")
 
+	canSave, err := checkIfCanSaveDashboard(dashboardId, c.OrgId, c.OrgRole, c.IsGrafanaAdmin, c.UserId)
+	if err != nil {
+		return ApiError(500, "Error while checking dashboard permissions", err)
+	}
+
+	if !canSave {
+		return ApiError(403, "Does not have permission to save this dashboard", nil)
+	}
+
 	if limit == 0 {
 		limit = 1000
 	}
@@ -358,6 +382,15 @@ func GetDashboardVersion(c *middleware.Context) Response {
 	dashboardId := c.ParamsInt64(":dashboardId")
 	version := c.ParamsInt(":id")
 
+	canSave, err := checkIfCanSaveDashboard(dashboardId, c.OrgId, c.OrgRole, c.IsGrafanaAdmin, c.UserId)
+	if err != nil {
+		return ApiError(500, "Error while checking dashboard permissions", err)
+	}
+
+	if !canSave {
+		return ApiError(403, "Does not have permission to save this dashboard", nil)
+	}
+
 	query := m.GetDashboardVersionQuery{
 		OrgId:       c.OrgId,
 		DashboardId: dashboardId,

+ 90 - 0
pkg/api/dashboard_test.go

@@ -53,6 +53,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 403)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 403)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 403)
@@ -75,6 +85,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 403)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 403)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 403)
@@ -98,6 +118,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 200)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 200)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 200)
@@ -149,6 +179,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 403)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 403)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 403)
@@ -177,6 +217,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 403)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 403)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 403)
@@ -209,6 +259,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 200)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 200)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 200)
@@ -241,6 +301,16 @@ func TestDashboardApiEndpoint(t *testing.T) {
 				So(sc.resp.Code, ShouldEqual, 403)
 			})
 
+			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)
+			})
+
+			loggedInUserScenarioWithRole("When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) {
+				CallGetDashboardVersions(sc)
+				So(sc.resp.Code, ShouldEqual, 403)
+			})
+
 			postDashboardScenario("When calling POST on", "/api/dashboards", "/api/dashboards", role, cmd, func(sc *scenarioContext) {
 				CallPostDashboard(sc)
 				So(sc.resp.Code, ShouldEqual, 403)
@@ -262,6 +332,26 @@ func GetDashboardShouldReturn200(sc *scenarioContext) dtos.DashboardFullWithMeta
 	return dash
 }
 
+func CallGetDashboardVersion(sc *scenarioContext) {
+	bus.AddHandler("test", func(query *models.GetDashboardVersionQuery) error {
+		query.Result = &models.DashboardVersion{}
+		return nil
+	})
+
+	sc.handlerFunc = GetDashboardVersion
+	sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
+}
+
+func CallGetDashboardVersions(sc *scenarioContext) {
+	bus.AddHandler("test", func(query *models.GetDashboardVersionsQuery) error {
+		query.Result = []*models.DashboardVersionDTO{}
+		return nil
+	})
+
+	sc.handlerFunc = GetDashboardVersions
+	sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
+}
+
 func CallDeleteDashboard(sc *scenarioContext) {
 	bus.AddHandler("test", func(cmd *models.DeleteDashboardCommand) error {
 		return nil